Archivado en: GNU/Linux
Escribir una módulo para el kernel 2.4 es una sencilla tarea que no debería abrumar a ningún programador. Tan sólo utilizando la siguiente estructura tendremos un módulo del kernel que a su vez actuará como device driver. Una vez compilado con el comando:
gcc -c counter.c -I/usr/src/linux/include
Recuerda que la directiva "-I" indica el path de las fuentes del kernel.
Podremos insertar nuestro módulo de forma dinámica mediante insmod counter.o y retirarlo con rmmod counter. Para verificar que efectivamente está corriendo lo haremos con lsmod | grep counter.
Para montarlo como dispositivo lo haremos con el comando:
mknod -c 37 1 /dev/counter
Con esto crearemos un dispositivo en el sistema de ficheros llamado /dev/counter cuyo major será 37 y minor 1 y será de tipo carácter.
Y podremos utilizar las llamadas a sistema estándar de Unix (open, read, write,...) con este dispositivo lógico que acabamos de crear.
#define __KERNEL__ /* We're part of the kernel */ #define MODULE /* Not a permanent part, though. */ /* Standard headers for LKMs */ #include "linux/module.h" // Disp. Major int counter_major = 37; char * counter_buffer; // Unix module read implementation ssize_t read_counter(struct file * file, char * buf, size_t count,loff_t * offset) { struct task_struct *p; char * mess; int i = 0; // For example, we return the number of tasks of the system for_each_task(p) i++; copy_to_user(buf,&i,sizeof(i)); return count; } ssize_t write_counter(struct file * file, const char * buf, size_t count,loff_t * offset) { return count; } int open_counter(struct file * file) { // Internal usage module counter MOD_INC_USE_COUNT; return 0; } int release_counter(struct file * file) { // Internal usage module counter MOD_DEC_USE_COUNT; return 0; } // Operations we implement struct file_operations counter_fops = { read: read_counter, write: write_counter, open: open_counter, release: release_counter }; /* Initialize the LKM */ int init_module() { int result; result = register_chrdev(counter_major,"counter",&counter_fops); if(result < 0) { printk(KERN_INFO "Can not register major(%d)",counter_major); return result; } counter_buffer = kmalloc(1, GFP_KERNEL); if(!counter_buffer){ result = -ENOMEM; cleanup_module(); return result; } memset(counter_buffer,0,1); return 0; } /* Cleanup - undo whatever init_module did */ void cleanup_module() { unregister_chrdev(counter_major,"counter"); if(counter_buffer) kfree(counter_buffer); } |