Home

Aqué

image

Contents

1. Est ndar en m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo T Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif Para dispositivos de car cter Las definiciones de dispositivo de car cter est n aqu include lt linux fs h gt Un envoltorio el cual no hace nada en la actualidad pero que quiz s ayude para compatibilizar con futuras versiones de Linux include lt linux wrapper h gt Nuestros propios n meros ioctl include chardev h En 2 2 3 usr include linux version h se incluye una macro para esto pero 2 0 35 no lo hace por lo tanto lo a ado aqu si es necesario ifndef KERNEL_VERSION define KERNEL_VERSION a b c a 65536 b 256 c endif if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 include lt asm uaccess h gt para get_user y put_user fendif define SUCCE E v wn o 2 1 Ficheros fuente para varias versiones del nucleo 33 Declaraciones de Dispositivo KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK el nombre de nuestro dispositivo tal como aparecera en proc devices define DEVICE NAME char_dev La maxima longitud del mensaje para
2. En la versi n 2 0 en la versi n 2 2 esto es realizado autom ticamente para nosotros si establecemos el inodo a cero 18 2 1 Ficheros fuente para varias versiones del nucleo 19 define MODVERSIONS include lt linux modversions h gt endif Necesario porque usamos el sistema de ficheros proc include lt linux proc_fs h gt En 2 2 3 usr include linux version h se incluye una macro para eso pero 2 0 35 no lo hace por lo tanto lo a ado aqui si es necesario ifndef KERNEL_VERSION define KERNEL_VERSION a b c a 65536 b 256 c endif Ponemos datos en el fichero del sistema de fichero proc Argumentos 1 El buffer donde los datos van a ser insertados si decides usarlo 2 Un puntero a un puntero de caracteres Esto es util si no quieres usar el buffer asignado por el n cleo La posici n actual en el fichero El tama o del buffer en el primer argumento Cero gt para uso futuro Uso y Valores de Retorno Si utilizas tu propio buffer como yo pon su situaci n en el segundo argumento y retorna el n mero de bytes usados en el buffer Un valor de retorno de cero significa que actualmente no tienes m s informaci n final del fichero Un valor negativo es una condici n de error Para M s Informaci n La forma en la que descubr qu hacer con esta funci n no fue leyendo documentaci n sin
3. Declaraciones de Dispositivo KKKKKKKKKKKKKKKKKKKKKKKKKKKK El nombre de nuestro dispositivo tal como aparecer en proc devices define DEVICE_NAME char_dev La m xima longitud del mensaje desd l dispositivo define BUF_LEN 80 gt Esta el dispositivo abierto correctamente ahora Usado para prevenir el acceso concurrente en el mismo dispositivo static int Device_Open 0 El mensaje que el dispositivo dar cuando preguntemos static char Message BUF_LEN gt Cu nto m s tiene que coger el proceso durante la lectura til si el mensaje es m s grande que el tama o del buffer que cogemos para rellenar en device_read static char Message_Ptr Esta funci n es llamada cuando un proceso intenta abrir el fichero del dispositivo static int device_open struct inode inode struct file file static int counter 0 1 2 M dulos del nucleo de varios ficheros 12 ifdef DEBUG printk Dispositivo abierto p p n inode file endif Esto es como coger el n mero menor del dispositivo pr ino if De Sp en el caso de que tengas mas de un dispositivo fisico usando el controlador intk Dispositivo d d n de gt i_rdev gt gt 8 inode gt i_rdev OxFF No queremos que dos procesos hablen al mismo tiempo Device_Open return
4. Las llamadas al sistema que son el principal interfaz que el n cleo muestra a los procesos generalmente permanecen igual de versi n a versi n Se puede a adir una nueva llamada al sistema pero normalmente las antiguas se comportar n igual que de costumbre Esto es necesario para la compatibilidad regresiva una versi n nueva del n cleo se supone que no romper con los procesos regulares En la mayor a de los casos los ficheros de dispositivo tambi n permanecer n igual En cambio las interfaces internas dentro del n cleo pueden y de hecho sufren cambios entre las versiones Las versiones del n cleo Linux est n divididas entre las versiones estables n lt n mero par gt m y las versiones en desarrollo n lt n mero impar gt m Las versiones en desarrollo incluyen todas las ideas nuevas incluyendo aquellas que ser n consideradas un error o reimplementadas en la siguiente versi n Como resultado no puedes confiar en que la interfaz permanecer igual en estas versiones es por lo que no las tratamos en este libro es mucho trabajo y caducar n r pidamente En las versiones estables por otro lado podemos esperar que el interfaz permanezca sin cambios sin importar la versi n de correcci n de fallos el 2 1 Ficheros fuente para varias versiones del nucleo 17 numero m Esta versi n de la GPMNL incluye soporte para la versi n 2 0 x y la vers 1 n 2 2 x del n cleo Linux Como hay diferencias entre las dos es
5. else return proc_register_dynamic amp proc_root amp Our_Proc_File endif 2 1 Ficheros fuente para varias versiones del nucleo 68 Limpieza void cleanup_module libera nuestro fichero proc proc_unregister amp proc_root Our_Proc_File low_ino Duerme hasta que intrpt_routine es llamada por ltima vez Esto es necesario porque en otro caso desasignaremos la memoria manteniendo intrpt_routine y Task mientras tq timer a n las referencia Destacar que no permitimos se ales que nos interrumpan Como WaitQ no es ahora NULL esto dice autom ticamente a la rutina de interrupci n su momento de muerte sleep_on 8 WaitQ Capitulo 11 Manejadores de interrupciones Excepto para el ltimo cap tulo todo lo que hemos hecho hasta ahora en el n cleo ha sido como respuesta a un proceso que lo pide ya sea tratando con un fichero especial enviando un ioct 1 o a trav s de una llamada al sistema Pero el trabajo del n cleo no es s lo responder a las peticiones de los procesos Otro trabajo no menos importante es hablar con el hardware conectado a la m quina Hay dos tipos de interacci n entre la CPU y el resto del hardware de la computadora El primer tipo es cuando la CPU da rdenes al hardware el el otro es cuando el hardware necesita decirle algo a la CPU La segunda llamada interrupci n es mucho m s dif cil de implementar porque hay que tratar con ella cuando l
6. necesita sitio Pone un cero al final del buffer por lo tanto estar correctamente terminado put_user 0 char ioctl_param i break case IOCTL_GET_NTH_BYTE Este ioctl es para entrada ioctl_param y para salida el valor de retorno de esta funci n return Message ioctl_param break return SUCCESS E 2 1 Ficheros fuente para varias versiones del nucleo 38 Declaraciones del M dulo KKAXKKKKKKKKKXKKKKKKKKKKkAk kk Esta estructura mantendr las funciones a ser llamadas cuando un proceso realiza algo al dispositivo que hemos creado Desde que un puntero a esta estructura es mantenido en la tabla de dispositivos no puede ser local a init_module NULL es para funciones no implementadas struct file operations Fops NULL b squeda device_read device_write NULL readdir NULL selecci n device_ioctl ioctl NULL mmap device_open if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 NULL borrar endif y device_releas cerrar Inicializa el m dulo Registra el dispositivo de car cter int init_module int ret_val Registra el dispositivo de car cter por lo menos lo intenta ret_val module_register_chrdev MAJOR_NUM DEVICE_NAME amp Fops Valores negativos significan un error if
7. x x Operaciones de fichero para nuestro fichero proc Aqu es donde colocamos los punteros a todas las funciones llamadas cuando alguien intenta hacer algo a nuestro fichero NULL significa que no queremos tratar con algo static struct file operations File_Ops_4 Our _Proc_File NULL lseek module_output lee del fichero module_input escribe al fichero NULL readdir NULL seleccionar NULL ioctl NULL mmap module_open llamado cuando el fichero proc es abierto i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 NULL borrado endif module_close llamado cuando es cerrado y Las operaciones de inodo para nuestro fichero proc Las necesitamos para tener algo donde especificar la estructura de operaciones del fichero que queremos usar y las funciones que usamos para los permisos Tambi n es posible especificar funciones que pueden ser llamadas por alguien m s lo cual se puede realizar en un inodo como no queremos ninguna ponemos NULL static struct inode _ operations Inode_Ops_4 Our_Proc_File amp File_Ops_4 Our_Proc_File NULL crear NULL lookup NULL enlazar NULL desenlazar NULL enlace simb lico 2 1 Ficheros fuente para varias versiones del nucleo 59 ULL mkdir ULL rmd
8. 2 1 Ficheros fuente para varias versiones del n cleo 42 int 1 Char ie printf get_nth_byte mensaje i 0 while c 0 c ioctl file_desc IOCTL_GET_NTH_BYTE i if e x 0j y printf ioctl_get_nth_byte fallo en el byte d esimo n exit 1 putchar c putchar n Principal Llama a las funciones ioctl main int file_desc ret_val char msg Mensaje pasado por ioctl n file_desc open DEVICE_FILE_NAME 0 if file_desc lt 0 1 printf No se puede abrir el fichero del dispositivo s n DEVICE_FILE_NAME exit 1 loctl_get_nth_byte file_desc loctl_get_msg file_desc loctl_set_msg file_desc msg close file_desc Capitulo 6 Parametros de inicio En muchos ejemplos previos tuvimos que codificar algo en el m dulo del n cleo tal como el nombre del fichero para los ficheros proc o el n mero mayor del dispositivo para el dispositivo para que pudi ramos hacer ioctls en l Esto va en contra de la filosof a de Unix y Linux que es escribir un programa flexible que el usuario pueda configurar La forma de decirle a un programa o a un m dulo del n cleo algo que necesitan antes de empezar a trabajar es mediante los par metros de la l nea de rdenes En el caso de los m dulos del n cleo no disponemos de argc y argv en cambio tenemos algo mejor Podemos definir varia
9. These requirements apply to the modified work as a whole If identifiable sections of that work are not derived from the Program and can be reasonably considered independent and separate works in themselves then this License and its terms do not apply to those sections when you distribute them as separate works But when you distribute the same sections as part of a whole which is a work based on the Program the distribution of the whole must be on the terms of this License whose permissions for other licensees extend to the entire whole and thus to each and every part regardless of who wrote it Thus it is not the intent of this section to claim rights or contest your rights to work written entirely by you rather the intent is to exercise the right to control the distribution of derivative or collective works based on the Program In addition mere aggregation of another work not based on the Program with the Program or with a work based on the Program on a volume of a storage or distribution medium does not bring the other work under the scope of this License 3 You may copy and distribute the Program or a work based on it under Section 2 in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following La Licencia General P blica GNU 82 a Accompany it with the complete corresponding machine readable source code which must be distributed under the terms of Sections
10. printk Soy peligroso Espero que hayas hecho un printk sync antes de insertarme n printk Mi duplicado cleanup_module es todav a printk m s peligroso Si n printk valoras tu sistema de ficheros ser mejor printk que hagas sync rmmod An printk cuando borres este mddulo n Mantiene un puntero a la funci n original en original_call y entonces reemplaza la llamada al sistema en la tabla de llamadas al sistema con our_sys_open original_call sys_call_table __NR_open sys_call_table __NR_open our_sys_open Para obtener la direcci n de la funci n para la llamada al sistema foo va a sys_call_table __NR_foo printk Espiando el UID d n uid Coje la llamada al sistema para getuid getuid_call sys_call_table __NR_getuid return 0 Limpieza libera el fichero apropiado de proc void cleanup_module Retorna la llamada al sistema a la normalidad if sys_call_table __NR_open our_sys_open printk Alguien m s jug con la llamada al sistema printk openin printk El sistema quiz s haya sido dejado printk en un estado iniestable n sys_call_table __NR_open original_call 2 1 Ficheros fuente para varias versiones del n cleo 51 Capitulo 8 Procesos bloqueantes Qu puedes hacer cuando alguien te pregunta
11. Recibe un puntero al mensaje en el espacio de usuario y establece lo que ser el mensaje del dispositivo 2 1 Ficheros fuente para varias versiones del nucleo 37 Coge el pardmetro dado a ioctl por el proceso temp char ioctl_param Encuentra la longitud del mensaje i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 get_user ch temp for i 0 ch amp amp i lt BUF_LEN i temp get_user ch temp T else for i 0 get_user temp amp amp i lt BUF_LEN i temp F endif No reinventa la rueda llama a device_write if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 device_write file char ioctl_param i 0 else device_write inode file char ioctl_param i endif break case IOCTL_GET_MSG Da el mensaje actual al proceso llamador el par metro que damos en un puntero lo rellena if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 i device _read file char ioctl_param 99 0 else i device_read inode file char ioctl_param 99 fendif Peligro asumimos aqu que la longitud del buffer es 100 Si es menor de lo que tenemos quiz s desborde el buffer causando que el proceso vuelque la memoria El motivo por el que permitimos hasta 99 caracteres es que el NULL que termina la cadena de caracteres tambi n
12. ay Copyright C 1998 99 por Ori Pomerantz Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo T Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif include lt sys syscall h gt La lista de llamadas al sistema 2 1 Ficheros fuente para varias versiones del nucleo 48 Para el actual estructura proceso necesitamos esto para conocer qui n es el usuario actual include lt linux sched h gt En 2 2 3 usr include linux version h se incluye una macro para esto pero 2 0 35 no lo hace por lo tanto lo afiado aqui si es necesario ifndef KERNEL _VERSION define KERNEL VERSION a b c a 65536 b 256 c endif i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 include lt asm uaccess h gt endif La tabla de llamadas al sistema una tabla de funciones Nosotros justamente definimos esto como externo y el n cleo lo rellener para nosotros cuando instalemos el m dulo af extern void sys_call_table UID que queremos espiar ser rellenado desde la linea de comandos int uid i LINUX_VERSION_CODE
13. chardev c Copyright C 1998 1999 by Ori Pomerantz Crea un dispositivo de car cter s lo lectura Ef Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo T Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif Para dispositivos de car cter include lt linux fs h gt Las definiciones de dispositivos de car cter est n aqui include lt linux wrapper h gt Un envoltorio que no hace nada actualmente pero que quizas ayude para compatibilizar con futuras 1 2 M dulos del n cleo de varios ficheros 11 versiones de Linux En 2 2 3 usr include linux version h incluye una macro para esto pero 2 0 35 no lo hace por lo tanto lo a ado aqu si es necesario ifndef KERNEL_VERSION define KERNEL_VERSION a b c a 65536 b 256 c endif Compilaci n condicional LINUX_VERSION_CODE es el c digo como KERNEL_VERSION de esta versi n if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 include lt asm uaccess h gt for put_user endif define SUCCE E v wn o
14. cuando alguien intenta hacer algo en nuestro fichero NULL significa que no queremos tratar con algo static struct file operations File _Ops_4 Our_Proc_File NULL lseek module_output lee desde el fichero module_input escribe en el fichero NULL readdir NULL select NULL ioctl NULL mmap module_open Alguien abri el fichero if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 NULL borrado a adido aqu en la versi n 2 2 endif module_close Alguien cerr el fichero etc etc etc son todas dadas en x usr include linux fs h Ya que no ponemos nada m s aqu el sistema mantendr los datos por defecto que en Unix son ceros NULLs cuando cogemos punteros y Las operaciones del inodo para nuestro fichero proc Las necesitamos por lo tanto tendremos alg n lugar para especificar las estructuras de operaciones del fichero que queremos usar Tambi n es posible especificar funciones a ser llamadas para cualquier cosa que pudiera ser hecha en un inodo como no queremos molestar las ponemos a NULL static struct inode_ operations Inode_Ops_4 Our_Proc_File amp File_Ops_4 Our_Proc_File ULL crear ULL lookup ULL enlazar ULL desenlazar ULL enlace simb lico ULL mkdir ULL rm
15. gt KERNEL VERSION 2 2 0 MODULE_PARM uid i endif Un puntero a la llamada al sistema original El motivo para mantener esto mejor que llamar a la funci n original sys_open es que alguien quiz s haya reemplazado la llamada al sistema antes que nosotros Destacar que esto no es seguro al 100 porque si otro m dulo reemplaza sys_open antes que nosotros entonces cuando insertemos llamaremos a la funci n en ese m dulo y quiz s sea borrado antes que nosotros Otro motivo para esto es que no podemos tener sys_open Es una variable est tica por lo tanto no es exportada asmlinkage int original_call const char int int 2 1 Ficheros fuente para varias versiones del n cleo 49 Por alg n motivo en 2 2 3 current uid me da cero en vez d la ID real del usuario He intentado encontrar d nde viene mal pero no lo he podido hacer en un breve periodo de tiempo y soy vago por lo tanto usaremos la llamada al sistema para obtener el uid de la forma que un proceso lo har a Por alg n motivo despu s de que recompilara el n cleo este problema se ha ido asmlinkage int getuid_call La funci n con la que reemplazaremos sys_open la funci n llamada cuando llamas a la llamada al sistema open Para encontrar el prototipo exacto con el n mero y tipo de argumentos encon
16. n 2 1 Ficheros fuente para varias versiones del nucleo 66 y st in Esta funci n ser llamada en cada interrupci n de reloj N tese que el puntero void funciones de la tarea puede ser usado para m s de un prop sito obteniendo cada vez un par metro diferente atic void intrpt_routine void irrelevant Incrementa el contador TimerTntrpt Si cleanup nos quiere matar if WaitQ NULL wake_up amp WaitQ Ahora cleanup_module puede retornar else Nos vuelve a poner en la cola de tareas queue_task amp Task amp tq_timer Pone datos en el fichero del sistema de ficheros proc t procfile_read char buffer char buffer_location off_t offset int buffer_length int zero int len Numero de bytes usados actualmente Esto es est tico por lo tanto permanecer en memoria cuando deje esta funci n static char my_buffer 80 static int count 1 Damos toda nuestra informaci n de una vez por lo tanto si alguien nos pregunta si tenemos mas informaci n la respuesta deber a de ser no EE if offset gt 0 return 0 Rellena el buffer y obtiene su longitud len sprintf my_buffer Timer fue llamado d vecesin TimerIntrpt count Dice a la funci n que nos ha llamado d nde 2 1 Ficheros fuente para varias versiones del nucleo 67 est el buffer buffer_location my_b
17. n oficial ioctl 31 asm uaccess h 76 BH_IMMEDIATE 70 bibliotecas est ndar 75 bloqueantes 52 procesos 52 bloqueo c mo evitarlo 52 bottom half 69 car cter 9 ficheros de dispositivos 9 chardev c source file 10 31 chardev h source file 39 cleanup_module 4 10 prop sito general 10 close 76 codificar 43 compilaci n condicionada 17 86 compilando 5 comprobaci n de tipos 43 condicionada 17 compilaci n 17 config h 5 CONFIG_MODVERSIONS 5 configuraci n 5 nucleo 5 configuraci n del n cleo 5 consola 6 copying Linux 84 copyright 80 84 CPU 74 varias 74 crontab 64 ctrl c 52 cuenta de referencia 10 64 definiendo ioctls 40 despertando procesos 52 disco duro 9 particiones de 9 dispositivos f sicos 9 dom sticas 64 dormir 52 poniendo lo procesos a 52 DOS 2 EAGAIN 52 egoismo 79 EINTR 52 elf 1386 6 Entrada 23 usando proc para 23 entrada a ficheros de dispositivos 31 ENTRY system_call 46 entry S 46 escritura 23 a ficheros de dispositivos 31 en el n cleo 23 est ndar 75 bibliotecas 75 estructura 52 task 52 INDICE DE MATERIAS 87 tty 61 fisicos 9 dispositivos 9 fichero de cabeceras para ioctls 40 ficheros de dispositivo 9 bloque 9 car cter 9 entrada a 31 ficheros de dispositivos de car cter 9 ficheros fuente 6 varios 6 file_operations 76 structure 76 file_operations structure 10 23 flush 76 Free Sof
18. ret_val lt 0 printk s fall con d n Lo siento registrando el dispositivo de car cter ret_val return ret_val printk s El n mero mayor del dispositivo es d n El registro es un xito MAJOR_NUM printk si quieres hablar con el controlador del dispositivo n printk tienes que crear el fichero del dispositivo n printk Te sugerimos que uses n printk mknod s c d 0 n DEVICE_FILE_NAME MAJOR_NUM 2 1 Ficheros fuente para varias versiones del nucleo 39 printk El nombre del fichero del dispositivo es muy importante porque n printk el programa ioctl asume que es el n printk fichero que usar s In return 0 Limpieza libera el fichero apropiado de proc void cleanup_module int ret libera el dispositivo ret module_unregister_chrdev MAJOR_NUM DEVICE_NAME Si hay un error informa de ello if ret lt 0 printk Error en module_unregister_chrdev d n ret chardev h chardev h el fichero de cabeceras con las definiciones ioctl Aqu las declaraciones tienen qu star en un fichero de cabeceras porque necesitan ser conocidas por el m dulo del n cleo en chardev c o por el proceso llamando a ioctl ioctl c if ifndef CHARDI define CHARDI E lt tf lt mm include lt linux ioctl h gt El n me
19. 1 Makefiles para los m dulos del n cleo Un m dulo del n cleo no es un ejecutable independiente sino un fichero objeto que ser enlazado dentro del n cleo en tiempo de ejecuci n En consecuencia deber an ser compilados con la bandera c Tambi n todos los m dulos del n cleo deber an ser compilados con ciertos s mbolos definidos e _KERNEL__ Esto le dice a los ficheros de cabeceras que este c digo se ejecutar en modo kernel n cleo y no como parte de un proceso de usuario modo usuario e MODULE Esto le dice a los ficheros de cabeceras que le den las definiciones apropiadas para un m dulo del n cleo e LINUX T cnicamente hablando esto no es necesario Sin embargo si quisieras escribir un m dulo serio que se compile en m s de un sistema operativo ser s feliz si lo haces Esto te permitir hacer compilaci n condicional en las partes que son dependientes del S O Hay otros s mbolos que tienen que ser incluidos o no dependiendo de las banderas con las que se haya compilado el n cleo Si no est s seguro de c mo fue compilado el n cleo mira en usr include linux config h e __SMP__ Multiproceso sim trico Esto tiene que estar definido si el n cleo fue compilado para soportar multiproceso sim trico incluso si s lo se est ejecutando en una CPU Si usas Multiproceso sim trico hay otras cosas que tienes que hacer ver cap tulo 12 e CONFIG _MODVERSIONS Si CONFIG MODVERSIONS es
20. 9 mayor del controlador de dispositivo 9 mayor del dispositivo f sico 9 n mero del dispositivo 9 mayor 9 n mero mayor del dispositivo 9 NDICE DE MATERIAS 88 no bloqueante 52 secuencial 9 acceso 9 O_NONBLOCK 52 segmentos de memoria 23 ocupado 52 shutdown 46 Par metros 76 ONL 52 M dulo 76 sistema 46 par metros de inicio 43 y Ri Par metros de M dulo 76 sistema de ficheros 18 param c source file 43 ip pres 18 partici n 9 registro 23 E sistema de ficheros proc 18 permisos 23 f sistema de ficheros proc 18 plani DA 52 sleep c source file 53 planificando tareas 64 sleep on 52 64 pol tica de devoluci n 75 SME hee poniendo procesos a dormir 52 source 4 8 10 18 24 31 39 40 43 47 53 61 64 70 printk 6 reemplazando 61 printk c source file 61 proc usando para entrada 23 proc_dir_entry structure 23 proc_register 18 76 proc_register_dynamic 18 76 proceso 74 multi 74 procesos 52 despertando 52 matando 52 poniendo a dormir 52 procesos bloqueantes 52 procfs c source file 18 24 puerto serie 31 puntero actual 23 put_user 23 76 queue_task 64 70 76 queue_task_irq 70 76 read 76 reemplazando printk s 61 registro de sistema de ficheros 23 request_irq 69 rmmod 6 46 47 64 previniendo 10 root 6 SA_INTERRUPT 69 SA_SHIRQ 69 salut mundi 4 sched c source file 64 tilde nal 52 tilde nales 76 chardev c 10 31 c
21. CLEO 1 2 M dulos del n cleo de varios ficheros 13 Message_Ptr Message Nos aseguramos de que el m dulo no es borrado mientras el fichero est abierto incrementando el contador de uso el n mero de referencias abiertas al m dulo si no es cero rmmod fallar MOD_INC_USE_COUNT return SUCCESS Esta funci n es llamada cuando un proceso cierra el fichero del dispositivo No tiene un valor de retorno en la versi n 2 0 x porque no puede fallar SIEMPRE debes de ser Capaz de cerrar un dispositivo En la versi n 2 2 x est permitido que falle pero no le dejaremos if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 static int device_release struct inode inode struct file file else static void device_release struct inode inode struct file file endif ifdef DEBUG printk dispositivo_liberado p p n inode file fendif Ahora estamos listos para la siguiente petici n Device_Open Decrementamos el contador de uso en otro caso una vez que hayas abierto el fichero no volver s a coger el m dulo MOD_DEC_USE_COUNT RSION_CODE gt KERNEL_VERSION 2 2 0 if LINUX_VI return 0 endif Gl Esta funci n es llamada cuando un proceso que ya
22. EBUSY Si habia un proceso tendremos que tener m s cuidado aqu En el caso de procesos el peligro es que un proceso quiz s est chequeando Device_Open y ntonces sea reemplazado por el planificador por otro proceso qu jecuta esta funci n Cuando el primer proceso regrese a la CPU asumir que el dispositivo no est abierto todav a De todas formas Linux garantiza que un proceso no ser reemplazado mientras se est ejecutando en el contexto del n cleo En el caso de SMP una CPU quiz s incremente Device_Open mientras otra CPU est aqu correcto despu s de chequear De todas formas en la versi n 2 0 del n cleo esto no es un problema por que hay un cierre que garantiza que s lamente una CPU estar en el m dulo del n cleo en un mismo instante Esto es malo en t rminos de rendimiento por lo tanto la versi n 2 2 lo cambi Desgraciadamente no tengo acceso a un equipo SMP para comprobar si funciona con SMP vice_Open Inicializa el mensaje rintf Message Si te lo dije una vez te lo digo d veces s counter Hola mundo n El nico motivo por el que se nos permite hacer est sprintf es porque la m xima longitud del mensaje asumiendo enteros de 32 bits hasta 10 d gitos con el signo menos es menor que BUF_LEN el cual es 80 lt lt TEN CUIDADO NO HAGAS DESBORDAMIENTO DE PILA EN LOS BUFFERS ESPECIALMENTE EN EL N
23. conversi n de los ejemplos o m s bien adaptando los cambios de Emmanuel Papirakis me encontr con las siguientes diferencias Las relaciono aqu todas juntas para ayudar a los programadores de m dulos especialmente aquellos que aprendieron de versiones previas de este libro y que est n m s familiarizados con las t cnicas que utilizo a convertirse a la nueva versi n Un recurso adicional para la gente que quiera convertirse a 2 2 est en http ww atnf csiro au rgooch linux docs porting to 2 2 html 1 asm uaccess h Si necesitas put_user o get_user tienes que incluir include sus ficheros de cabeceras 2 get_user En la versi n 2 2 get_user recibe tanto el puntero a la memoria de usuario como la variable en la memoria del n cleo para rellenarla con la informaci n El motivo por el que esto es as es que get_user ahora puede leer dos o cuatro bytes al mismo tiempo si la variable que leemos es de una longitud de dos o cuatro bytes 3 file_operations Esta estructura ahora tiene una funci n de borrado entre las funciones open y close 4 close en file_operations En la versi n 2 2 la funci n close devuelve un entero por lo tanto se permite que falle 5 read y write en file operations Las cabeceras de estas funciones han cambiado Ahora devuelven ssize_t en vez de un entero y su lista de par metros es diferente El inodo ya no es un par metro y en cambio s lo es el desplazamiento dentro del fichero 6 proc_regist
24. count 10 1 st count 10 2 nd count 10 3 2 rd 2 MERO J3 count Dice a la funci n que llamamos d nde est el buffer buffer_location my_buffer Devolvemos la longitud return len struct proc_dir_entry Our_Proc_File 0 N mero de Inodo ign ralo ser rellenado por proc_register _dynamic 4 Longitud del nombre del fichero test El nombre del fichero 2 1 Ficheros fuente para varias versiones del nucleo 21 S_IFREG S_IRUGO Modo del fichero este es un fichero regular que puede ser le do por su due o por su grupo y por todo el mundo 1 Numero d nlaces directorios donde el fichero esta referenciado 0 0 El uid y gid para el fichero se lo damos a root 80 El tama o del fichero devuelto por ls NULL funciones que pueden ser realizadas en el inodo enlazado borrado etc no soportamos ninguna procfile_read La funci n read para este fichero la funci n llamada cuando alguien intenta leer algo de el NULL Podemos tener aqu un funci n que rellene el inodo del fichero para habilitarnos el jugar con los permisos due o etc y Inicializa el m dulo registra el fichero proc int init_module Tiene xito si proc_register _dynamic tiene xito falla en otro caso if LINUX_VERSION_CODE gt KERNEL_VERSIO
25. de la arquitectura Intel donde Linux se origin 2queue_task_irq est protegida de esto mediante un bloqueo global en 2 2 no hay queue_task_irg y queue_task est 69 11 1 Teclados en la arquitectura Intel 70 porque las versiones anteriores de Linux s lo ten an un array de 32 bottom half s y ahora uno de ellos BH_IMMEDIATE se usa para la lista enlazada de bottom half s para los controladores que no tenian una entrada de bottom half asignada 11 1 Teclados en la arquitectura Intel El resto de este cap tulo es completamente espec fico de Intel Si no est s trabajando en una plataforma Intel no funcionar Ni siquiera intentes compilar el siguiente c digo Tuve un problema escribiendo el c digo de ejemplo para este cap tulo Por una parte para que un ejem plo sea til tiene que ejecutarse en las computadoras de todo el mundo con resultados significativos Por otra parte el n cleo ya incluye controladores de dispositivo para todos los dispositivos comunes y esos controladores de dispositivo no coexistir n con lo que voy a escribir La soluci n que encontr fue es cribir algo para la interrupci n del teclado y deshabilitar primero el manejador normal de interrupci n del teclado Como est definido como un s mbolo est tico en los ficheros fuente del n cleo concretamente drivers char keyboard c no hay forma de restaurarlo Antes de instalar este c digo haz en otro terminal sleep 120 reboot si e
26. define MESSAGE_LENGTH 80 static char Message MESSAGE H ENGTH Desde que usamos la estructura de operaciones de fichero podemos usar las provisiones de salida especiales de proc tenemos que usar una funci n de lectura est ndar y es 2 1 Ficheros fuente para varias versiones del nucleo 25 esta funci n if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 static ssize_t module_output struct file file El fichero le do char buf El buffer donde se van a poner los datos en el segmento de usuario size_t len La longitud del buffer loff_t offset Desplazamiento en el fichero ign ralo else static int module_output struct inode inode El inodo leido struct file file El fichero le do char buf El buffer donde se van a poner los datos en el segmento de usuario int len La longitud del buffer endif static int finished 0 int i H char message MESSAGE_LENGTH 30 Retornamos 0 para indicar el final del fichero que no tenemos m s informaci n En otro caso los procesos continuar n leyendo de nosotros en un bucle sin fin if finished finished 0 return 0 Usamos put_user para copiar la cadena de caracteres del segmento de memoria del nucleo al segmento de memoria de proceso
27. el n mero de bytes realmente insertados en el buffer return bytes_read Se llama a esta funci n cuando alguien intenta escribir en nuestro fichero de dispositivo no soportado en este ejemplo if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 static ssize_t device _write struct file file const char buffer El buffer 1 2 M dulos del nucleo de varios ficheros 15 size_t length La longitud del buffer loff_t offset Nuestro desplazamiento en el fichero else static int device_write struct inode inode struct file file const char buffer int length fendif return EINVAL Declaraciones del M dulo KKKKKKKKKKKKKKKKKKKKKKKKKKKKK El numero mayor para el dispositivo Esto es global bueno est tico qu n este contexto es global dentro de este fichero porque tiene que ser accesibl para el registro y para la liberaci n static int Major Esta estructura mantendr las funciones que son llamadas cuando un proceso hace algo al dispositivo que nosotros creamos Ya que un puntero a esta estructura se mantiene en la tabla de dispositivos no puede ser local a init_module NULL es para funciones no implementadas struct file operations Fops NULL b squeda device_read device_write NULL readdir NULL seleccionar NULL ioctl NULL mmap d
28. en el verano del 99 Si ya es verano y quieres este libro impreso puedes dejar descansar a tu impresora y comprarlo encuadernado y reluciente 78 Ap ndice D Mostrando tu gratitud ste es un documento libre No tienes obligaciones m s all de las dadas en la Licencia P blica GNU Ap ndice E En todo caso si quieres hacer algo como recompensa por la obtenci n de este libro he aqu algunas cosas que puedes hacer e Env ame una tarjeta postal a Ori Pomerantz Apt 1032 2355 N Hwy 360 Grand Prairie TX 75050 USA Si quieres recibir un gracias de mi parte incluye tu direcci n de correo electr nico e Aporta dinero o mejor todav a tiempo a la comunidad de software libre Escribe un programa o un documento y publ calo bajo la GPL Ense a a otras personas a usar software libre como Linux o Perl e Explica a la gente c mo el ser ego stas no es incompatible con el vivir en sociedad o con la ayuda a los dem s Yo he disfrutado escribiendo este documento y creo que su publicaci n me aportar algo en el futuro Al mismo tiempo he escrito un libro que si has llegado hasta aqu te ayudar Recuerda que las personas felices normalmente son m s tiles para s mismas que las desgraciadas y las personas capaces son mucho mejores que las incapaces e S feliz Si alguna vez nos encontramos esto har que el encuentro sea mejor para m te har m s til para m 79 Ap ndice E La Licencia General
29. en la arquitectura Intel 72 Inicializa el m dulo registra el manejador de IRQs int init_module Como el manejador de teclado no coexistira con otro manejador tal como nosotros tenemos que deshabilitarlo liberar su IRQ antes de hacer algo Ya que nosotros no conocemos d nde est no hay forma de reinstalarlo despu s por lo tanto la computadora tendr que ser reiniciada cuando halla sido realizado free_irq 1l NULL Petici n IRQ 1 la IRQ del teclado para nuestro irq_ handler return request_irq fe D 1 El n mero de la IRQ del teclado en PCs irq_handler nuestro manejador SA_SHIRO SA_SHIRQ significa que queremos tener otro manejador en este IRQ SA _ INTERRUPT puede ser usado para manejarla en una interrupci n r pida test_keyboard_irg_handler NULL impieza void cleanup_module Esto est aqu s lo para completar Es totalmente irrelevante ya que no tenemos forma de restaurar la interrupci n normal de teclado por lo tanto la computadora est totalmente inservible y tiene qu ser reiniciada free_irq 1 NULL 11 1 Teclados en la arquitectura Intel 73 Capitulo 12 Multiproceso sim trico Una de las formas m s f ciles y baratas de aumentar el rendimiento del hardware es poner m s de una CPU en la placa
30. funci n de entrada de la misma forma que incluye un puntero a una funci n de sal ida En vez de esto para escribir en un fichero proc necesitamos usar el mecanismo est ndar del sistema de ficheros En Linux hay un mecanismo est ndar para el registro de sistemas de ficheros Como cada sistema de ficheros tiene que tener sus propias funciones para manejar las operaciones de inodos y ficheros hay una estructura especial para mantener los punteros a todas estas funciones struct inode_operations que incluye un puntero a struct file operations En proc cuando registramos un nuevo fichero se nos permite especificar qu struct inode_operations se usar para acceder a l ste es el mecanismo que usaremos una struct inode operations que incluya punteros a nuestras funciones module_input y module_output Es importante destacar que los papeles est ndar de lectura y escritura est n invertidos en el n cleo Las funciones de lectura se usan para la salida mientras que las funciones de escritura se usan para la entrada El motivo de esto es que la lectura y escritura se refieren al punto de vista del usuario si un proceso lee algo del n cleo entonces el n cleo necesita sacarlo y si un proceso escribe algo en el n cleo entonces el n cleo lo recibe como entrada Otro punto interesante aqui es la funci n module_permission Esta funci n se llama cuando un proceso intenta hacer algo con el fichero proc y puede decidir si permitir el acceso
31. ha abierto el fichero del dispositivo intenta leer de l i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 static ssize_t device_read struct file file char buffer El buffer a rellenar con los datos size_t length La longitud del buffer 1 2 M dulos del n cleo de varios ficheros 14 loff_t offset Nuestro desplazamiento en el fichero else static int device_read struct inode inode struct file file char buffer El buffer para rellenar con los datos int length La longitud del buffer lt no debemos escribir m s all de l endif N mero de bytes actualmente escritos en el buffer int bytes_read 0 si estamos al final del mensaje devolvemos 0 lo cual significa el final del fichero if Message_Ptr 0 return 0 Ponemos los datos en el buffer while length amp amp Message_Ptr Porque el buffer est en el segmento de datos del usuario y no en el segmento de datos del n cleo la asignaci n no funcionar En vez d so tenemos que usar put_user el cual copia datos desd l segmento de datos del n cleo al segmento de datos del usuario put_user Message_Ptr buffer length bytes_read ifdef DEBUG printk Sd bytes leidos quedan d n bytes_read length endif Las funciones de lectura se supone que devuelven
32. module h gt Espec ficamente un m dulo T Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS 1 define MODVERSIONS include lt linux modversions h gt endif Necesario porque usamos el sistema de ficheros proc include lt linux proc_fs h gt Planificamos tareas aqu include lt linux tqueue h gt Tambi n necesitamos la habilidad para ponernos a dormir y despertanos m s tarde include lt linux sched h gt En 2 2 3 usr include linux version h se incluye una macro para esto pero 2 0 35 no lo hace por lo tanto lo a ado aqui si es necesario ifndef KERNEL_VERSION define KERNEL_VERSION a b c a 65536 b 256 c endif El n mero de veces que la interrupci n del reloj ha sido llamada static int TimerIntrpt 0 Esto lo usa cleanup para evitar que el mddulo sea descargado mientras intrpt_routine est a n en la cola de tareas static struct wait_queue WaitQ NULL static void intrpt_routine void La estructura de cola de tareas para esta tarea de tqueue h static struct tq_struct Task NULL Pr ximo elemento en la lista queue_task har esto por nosotros 0 Una bandera significando que todav a no hemos insertado en la cola de tareas intrpt_routine La funci n a ejecutar NULL El par metro void para esta funci
33. nuestro dispositivo define BUF_LEN 80 gt Est el dispositivo correctamente abierto ahora Usado para evitar acceso concurrente al mismo dispositivo static int Device_Open 0 El mensaje que el dispositivo nos dar cuando preguntemos static char Message BUF_LEN gt Cuanto puede coger el proceso para leer el mensaje til si el mensaje es m s grande que el tama o del buffer que tenemos para rellenar en device_read static char Message_Ptr Esta funci n es llamada cuando un proceso intenta abrir el fichero de dispositivo static int device_open struct inode inode struct file file ifdef DEBUG printk device_open p n file endif No queremos hablar con dos procesos a la vez if Device_Open return EBUSY Si esto era un proceso tenemos que tener m s cuidado aqu porque un proceso quiz s haya chequeado Device_Open correctamente antes de que el otro intentara incrementarlo De cualquier forma estamos en el n cleo por lo tanto estamos protegidos contra los cambios de contexto Esta NO es la actitud correcta a tomar porque quiz s estemos ejecut ndonos en un sistema SMP pero trataremos con SMP en un cap tulo posterior S Device_Open Inicializa el mensaje 2 1 Ficheros fuente para varias versiones del nucleo 34 Message_Ptr Message MOD_INC_USE_COUNT return
34. o no Ahora mismo est solamente basado en la operaci n y el uid del usuario actual tal como est disponible en current un puntero a una estructura que incluye informaci n del proceso actualmente en ejecuci n pero puede estar basado en cualquier cosa que queramos como lo que otros procesos est n haciendo con el mismo fichero la hora del d a o la ltima entrada recibida El motivo para put_user y get_user es que la memoria de Linux bajo la arquitectura Intel quiz s sea diferente bajo otros procesadores est segmentada Esto significa que un puntero por s mismo no referencia una nica posici n en memoria s lo una posici n en un segmento de memoria y necesitas saber qu segmento es para poder usarlo Hay un segmento de memoria para el n cleo y uno para cada proceso El nico segmento de memoria accesible a un proceso es el suyo por lo tanto cuando escribimos progra mas normales para ejecutarse como procesos no hay necesidad de preocuparse por los segmentos Cuando escribes un m dulo del n cleo normalmente quieres acceder al segmento de memoria del n cleo que es manejado autom ticamente por el sistema Sin embargo cuando el contenido de un b fer de memoria nece La diferencia entre ellas es que las operaciones de ficheros tratan con el propio fichero y las operaciones de inodo tratan con las formas de referenciar el fichero tales como crear enlaces a l 23 2 1 Ficheros fuente para varias versiones del nu
35. of MERCHANTABILITY or FITNESS FOR A PARTICU LAR PURPOSE See the GNU General Public License for more details You should have received a copy of the GNU General Public License along with this program if not write to the Free Software Foundation Inc 675 Mass Ave Cambridge MA 02139 USA Also add information on how to contact you by electronic and paper mail If the program is interactive make it output a short notice like this when it starts in an interactive mode Gnomovision version 69 Copyright C 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY for details type show w This is free software and you are welcome to redistribute it under certain conditions type show c for details The hypothetical commands show w and show c should show the appropriate parts of the General Public License Of course the commands you use may be called something other than show w and show c they could even be mouse clicks or menu items whatever suits your program You should also get your employer if you work as a programmer or your school if any to sign a copyright disclaimer for the program if necessary Here is a sample alter the names Yoyodyne Inc hereby disclaims all copyright interest in the program Gnomovision which makes passes at compilers written by James Hacker signature of Ty Coon 1 April 1989 Ty Coon President of Vice This General Public License does not permit incorporating your progr
36. place then offering equivalent access to copy the source code from the same place counts as distribution of the source code even though third parties are not compelled to copy the source along with the object code 4 You may not copy modify sublicense or distribute the Program except as expressly provided under this License Any attempt otherwise to copy modify sublicense or distribute the Program is void and will automatically terminate your rights under this License However parties who have received copies or rights from you under this License will not have their licenses terminated so long as such parties remain in full compliance 5 You are not required to accept this License since you have not signed it However nothing else grants you permission to modify or distribute the Program or its derivative works These actions are prohibited by law if you do not accept this License Therefore by modifying or distributing the Program or any work based on the Program you indicate your acceptance of this License to do so and all its terms and conditions for copying distributing or modifying the Program or works based on it 6 Each time you redistribute the Program or any work based on the Program the recipient automatically receives a license from the original licensor to copy distribute or modify the Program subject to these terms and conditions You may not impose any further restrictions on the recipients exercise of the rig
37. por algo que no puedes hacer en el acto Si eres un humano y est s te est molestando un humano lo nico que puedes decir es Ahora no Estoy ocupado Vete Pero si eres un m dulo del n cleo y un proceso te est molestando tienes otra posibilidad Puedes poner el proceso a dormir hasta que lo puedas atender Despu s de todo los procesos son puestos a dormir por el n cleo y todos son despertados al mismo tiempo esta es la forma en la que varios procesos aparentan ejecutarse a la vez en una sola CPU Este m dulo del n cleo es un ejemplo de esto El fichero llamado proc sleep s lo puede ser abierto por un solo proceso a la vez Si el fichero ya est abierto el m dulo del n cleo llama a 1 module_interruptible_sleep_on Esta funci n cambia el estado de la tarea una tarea es la es tructura de datos del n cleo que mantiene informaci n sobre un proceso y la llamada al sistema en la que est si es que est en alguna a TASK_INTERRUPTIBLE lo que significa que la tarea no se ejecutar hasta que sea despertada de alguna forma y se a ade a Wait la cola de tareas esperando acceder al fichero Entonces la funci n llama al planificador para hacer un cambio de contexto a un proceso diferente uno que tenga alguna utilidad para la CPU Cuando un proceso ha acabado con el fichero lo cierra y se llama a module_close Esta funci n despierta a todos los procesos en la cola no hay un mecanismo para desper
38. por lo tanto volver n a dormir Already_Open 0 Despertamos a todos los procesos en WaitQ por lo tanto si alguien est esperando por el fichero lo puede tener module_wake_up amp WaitQ MOD_DEC_USE_COUNT if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 return 0 finalizado con xito endif Gl Esta funci n decide cuando permite una operaci n retorna cero o no la permite retorna distinto de cero lo cual indica porque no es permitida Las operaciones pueden ser una de los siguientes valores 0 Ejecuta ejecuta el file sin p rdida de significado en E nuestro caso 2 Escribe entrada al m dulo del n cleo 4 Lectura salida desde el m dulo del n cleo Esta es la funci n real que chequea los permisos del fichero Los permisos retornados por ls 1 son s lo para referencia y pueden ser sobreescritos aqu 2 1 Ficheros fuente para varias versiones del nucleo 58 af static int module_permission struct inode inode int op Permitimos a todo el mundo leer de nuestro m dulo pero s lo root uid 0 puede escribir en el if op 4 op 2 amp amp current gt euid 0 return 0 Si es otro l acceso es denegado return EACCES Estructuras para registrar como fichero proc con punteros a todas las funciones relevantes
39. proceso para usar las ioctls para controlar el m dulo del n cleo Hasta ahora pod amos usar cat para entrada y salida Pero ahora necesitamos realizar ioctls los cuales requieren escribir en nuestro proceso Copyright C 1998 by Ori Pomerantz espec fico del dispositivo tales como n meros ioctl 2 1 Ficheros fuente para varias versiones del nucleo 41 y el fichero del dispositivo mayor include chardev h include lt fcntl h gt abrir include lt unistd h gt salir include lt sys ioctl h gt ioctl Funciones para las llamadas ioctl loctl_set_msg int file _desc char message int ret_val ret_val ioctl file_desc IOCTL_SET_MSG message if ret_val lt 0 printf ioctl_set_msg fallido d n ret_val exit 1 ioctl_get_msg int file _desc int ret_val char message 100 Peligro esto es peligroso porque no decimos al n cleo cuanto le est permitido escribir por lo tanto quiz s desborde el buffer En la creaci n de un programa real deberemos usar dos ioctls uno para decir al n cleo la longitud del buffer y otro para darle el buffer a rellenar ret_val ioctl file _ desc IOCTL_GET_MSG message if ret_val lt 0 printf ioctl_get_msg fallido d n ret_val exit 1 printf get_msg mensaje s n message loctl_get_nth_byte int file _desc
40. relacionar aqu a todo el mundo que me escribi un correo e y si te he dejado fuera lo siento por adelantado Las siguientes personas fueron especialmente tiles e Frodo Looijaard de Holanda Por un mont n de sugerencias tiles y sobre informaci n sobre los n cleos 2 1 x e Stephen Judd de Nueva Zelanda Correcciones tipogr ficas e Magnus Ahltorp de Suiza Corrigiendo un fallo m o sobre la diferencia entre dispositivos de bloque y de car cter 0 4 2 Para la versi n 1 1 0 e Emmanuel Papirakis de Qu bec Canad Por portar todos los ejemplos a la versi n 2 2 del n cleo e Frodo Looijaard de Holanda Por decirme c mo crear un m dulo del n cleo con varios ficheros 1 2 Por supuesto cualesquiera errores remanentes son m os y si piensas que stos hacen el libro inutilizable eres bienvenido a apuntarte a recibir un reintegro total del dinero que me has pagado por l Capitulo 1 Hola mundo Cuando el primer programador de las cavernas cincel el primer programa en las paredes de la primera computadora de las cavernas era un programa para imprimir la cadena de caracteres Hola mundo en las pinturas de los Ant lopes Los libros de texto de los romanos sobre programaci n empezaban con el programa Salut Mundi No s qu puede ocurrirle al que rompa esta tradici n y creo que es m s seguro no averiguarlo Un m dulo del n cleo tiene que tener por lo menos dos funciones init_module que se llama cuando el
41. se utilizan nicamente con el prop sito de identificaci n y son marcas registradas de sus respectivos propietarios No he hecho ninguna demanda de propiedad o asociaci n corporativa con los productos o compa as que las poseen Copyright 1999 Ori Pomerantz Ori Pomerantz Apt 1032 2355 N Hwy 360 Grand Prairie TX 75050 USA E mail mog simple tech com La Gu a de Programaci n de M dulos de N cleo Linux es un documento libre puedes reproducirlo y o modificarlo bajo los t rminos de la versi n 2 o a tu elecci n cualquier versi n posterior de la Licencia General P blica de GNU tal como ha sido publicada por la Free Software Foundation La versi n 2 est incluida en este documento en el Ap ndice E Este libro se distribuye con la esperanza de que sea til pero sin ninguna garant a ni siquiera la garant a impl cita de comerciabilidad o adecuaci n a un prop sito particular El autor anima a la amplia distribuci n de este libro para uso personal o comercial con tal de que el anterior anuncio de copyright permanezca intacto y que el m todo se adhiera a las previsiones de la Licencia General P blica GNU ver Ap ndice E En resumen puedes copiar y distribuir este documento sin cobrar o a cambio de una contraprestaci n No se requiere permiso expl cito del autor para la reproducci n de este libro en cualquier medio ya sea f sico o electr nico Ten en cuenta que las traducciones y obras derivadas de este docum
42. su tipo Esto es por lo que los ficheros de cabeceras son necesarios 43 2 1 Ficheros fuente para varias versiones del nucleo 44 Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERS IONS define MODVERSIONS include lt linux modversions h gt endif include lt stdio h gt Necesito NULL En 2 2 3 usr include linux version h se incluye una macro para esto pero 2 0 35 no lo hace por lo tanto lo afiado aqui si es necesario ifndef KERNEL VERSION define KERNEL VERSION a b c a 65536 b 256 c endif Emmanuel Papirakis Los nombres de par metros son ahora 2 2 manejados en una macro El nucleo no resuelve los nombres de los simbolos como parecia que tenia que hacer Para pasar par metros a un m dulo tienes que usar una macro definida en include linux modules h linea 176 La macro coge dos par metros El nombre del par metro y su tipo El tipo es una letra entre comillas Por ejemplo i deber a de ser un entero y s deber a de ser una Cadena de caracteres char strl str2 if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 MODULE_PARM strl s MODULE_PARM str2 s endif Inicializa el m dulo muestra los par metros int init_module if strl NULL str2 NULL printk La pr xima vez haz insmod pa
43. tenemos dos posibilidades La primera es poner un proceso en el fichero crontab que despertar al m dulo mediante una llamada al sistema cuando sea necesario por ejemplo abriendo un fichero Sin embargo esto es terriblemente ineficiente ejecutamos un proceso a partir de crontab leemos un ejecutable nuevo hacia la memoria y todo esto para despertar a un m dulo del n cleo que de todas formas est en memoria En vez de hacer eso podemos crear una funci n que ser llamada una vez en cada interrupci n del reloj La forma en la que hacemos esto es creando una tarea mantenida en una estructura tq_struct que mantendr un puntero a la funci n Entonces usamos queue_task para poner esta tarea en una lista de tareas llamada t q_t imer que es la lista de tareas que han de ejecutarse en la siguiente interrupci n de reloj Como queremos que la funci n siga siendo ejecutada necesitamos ponerla otra vez en tq_timer al ser llamada para la siguiente interrupci n del reloj Hay un punto m s que necesitamos recordar aqu Cuando un m dulo es quitado mediante rmmod primero se verifica su contador de referencias Si es cero se llama a module_cleanup Entonces se quita el m dulo de la memoria con todas sus funciones Nadie controla si la lista de tareas del reloj contiene un puntero a una de estas funciones que ya no estar n disponibles A os despu s desde la perspectiva de la computadora para la perspectiva de un humano no es nada menos de una
44. 1 and 2 above on a medium customarily used for software interchange or b Accompany it with a written offer valid for at least three years to give any third party for a charge no more than your cost of physically performing source distribution a complete machine readable copy of the corresponding source code to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange or c Accompany it with the information you received as to the offer to distribute corresponding source code This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer in accord with Subsection b above The source code for a work means the preferred form of the work for making modifications to it For an executable work complete source code means all the source code for all modules it contains plus any associated interface definition files plus the scripts used to control compilation and installation of the executable However as a special exception the source code distributed need not include anything that is normally distributed in either source or binary form with the major components compiler kernel and so on of the operating system on which the executable runs unless that component itself accompanies the executable If distribution of executable or object code is made by offering access to copy from a designated
45. DITIONS FOR COPYING DISTRIBUTION AND MODIFICATION 80 La Licencia General P blica GNU 81 0 This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The Program be low refers to any such program or work and a work based on the Program means either the Program or any derivative work under copyright law that is to say a work containing the Program or a por tion of it either verbatim or with modifications and or translated into another language Hereinafter translation is included without limitation in the term modification Each licensee is addressed as gt you Activities other than copying distribution and modification are not covered by this License they are outside its scope The act of running the Program is not restricted and the output from the Program is covered only if its contents constitute a work based on the Program independent of having been made by running the Program Whether that is true depends on what the Program does 1 You may copy and distribute verbatim copies of the Program s source code as you receive it in any medium provided that you conspicuously and appropriately publish on each copy an appropriate copy right notice and disclaimer of warranty keep intact all the notices that refer to this License and to the absence of any warranty and give an
46. Esto se puede realizar haciendo que CPUs diferentes tengan trabajos diferentes multipro ceso asim trico o haciendo que todos se ejecuten en paralelo realizando el mismo trabajo multiproceso sim trico o SMP El hacer multiproceso asim trico requiere un conocimiento especializado sobre las tareas que la computadora debe ejecutar lo que no est a nuestro alcance en un sistema operativo de prop sito general como Linux En cambio el multiproceso sim trico es relativamente f cil de implementar Por relativamente f cil quiero decir exactamente eso no que sea realmente f cil En un entorno de multiproceso sim trico las CPUs comparten la misma memoria y como resultado el c digo que corre en una CPU puede afectar a la memoria usada por otra Ya no puedes estar seguro de que una variable que has establecido a un cierto valor en la l nea anterior todav a tenga el mismo valor la otra CPU quiz s haya estado jugando con ella mientras no mir bamos Obviamente es imposible programar algo de esta manera En el caso de la programaci n de procesos esto no suele ser un problema porque un proceso normalmente s lo se ejecutar en una CPU a la vez El n cleo sin embargo podr a ser llamado por diferentes procesos ejecut ndose en CPUs diferentes En la versi n 2 0 x esto no es un problema porque el n cleo entero est en un gran spinlock Esto significa que si una CPU est dentro del n cleo y otra CPU quiere entrar en l por ejemplo
47. Guia de Programacion de Modulos del Nucleo Linux 1999 Ori Pomerantz Version 1 1 0 26 Abril 1999 Este libro trata sobre c mo escribir M dulos del N cleo Linux Se espera que sea de utilidad para programadores que saben C y quieren aprender a escribir m dulos del n cleo Est escrito a la manera de un manual de instrucciones C mo How To con ejemplos de todas las t cnicas importantes Aunque este libro toca muchos puntos del dise o del n cleo no se supone que venga a cumplir dicho prop sito hay otros libros sobre el tema tanto impresos como en el proyecto de documentaci n de Linux Usted puede copiar y redistribuir libremente este libro bajo ciertas condiciones Por favor lea los enunciados del copyright y de la distribuci n Names of all products herein are used for identification purposes only and are trademarks and or registered trademarks of their respective owners I make no claim of ownership or corporate association with the prod ucts or companies that own them Copyright 1999 Ori Pomerantz Ori Pomerantz Apt 1032 2355 N Hwy 360 Grand Prairie TX 75050 USA E mail mog simple tech com The Linux Kernel Module Programing Guide is a free book you may reproduce and or modify it under the terms of version 2 or at your option any later version of the GNU General Public License as published by the Free Software Foundation Version 2 is enclosed with this document at Appendix E This book
48. N 2 2 0 En la versi n 2 2 proc_register asigna un n mero de inodo autom ticamente si hay cero en la estructura por lo tanto no necesitamos nada m s para proc_register_dynamic y return proc_register amp proc_root amp Our_Proc_File else return proc_register_dynamic amp proc_root amp Our_Proc_File fendif proc_root es el directorio raiz para el sistema de ficheros proc proc Aqu es d nde queremos que nuestro fichero est localizado el Limpieza liberamos nuestro fichero de proc void cleanup_module proc_unregister amp proc_root Our_Proc_File low_ino 2 1 Ficheros fuente para varias versiones del n cleo 22 Capitulo 4 Usando proc para la entrada Hasta ahora tenemos dos formas de producir una salida a partir de los m dulos del n cleo podemos registrar un controlador de dispositivo y mknod el fichero de dispositivo o podemos crear un fichero proc Esto permite al m dulo del n cleo decirnos cualquier cosa que quiera El nico problema es que no tenemos ninguna forma de responderle La primera forma en que enviaremos entrada a los m dulos del n cleo ser volviendo a escribir en el fichero proc Como el sistema de ficheros proc se escribi principalmente para permitir al n cleo informar de su situaci n a los procesos no hay medidas especiales para la entrada La estructura proc_dir_entry no incluye un puntero a una
49. NGTH 1 amp amp i lt length i i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 get_user Message i buf i En la versi n 2 2 la sem ntica de get_user cambi no volver a devolver un car cter excepto una variable para rellenar como primer argumento y un puntero al segmento de usuario para rellenarlo como segundo El motivo para este cambio es que en la versi n 2 2 get_user puede leer un short o un int La forma en la que conoce el tipo de la variable que deber a de leer es usando sizeof y para lo que necesita la variable else Message i get_user buf 1 endif Message i 0 queremos un est ndar cadena de caracteres terminada en cero Necesitamos devolver el n mero de caracteres de entrada usados return 1 Esta funci n decide si permite una operaci n retorna cero o no la permite retornando distinto de cero lo cual indica porqu no est permitido La operaci n puede ser uno de los siguientes valores 0 Ejecuta ejecuta el fichero sin sentido en nuestro caso 2 1 Ficheros fuente para varias versiones del n cleo 27 2 Escribe entrada en el m dulo del n cleo 4 Lee salida desde el m dulo del n cleo Esta es la funci n real que chequea los permisos del fichero Los permisos retornados po
50. P blica GNU Lo que aparece a continuaci n es la Licencia General P blica GNU la GPL o copyleft bajo la que est licenciado este libro GNU GENERAL PUBLIC LICENSE Version 2 June 1991 Copyright 1989 1991 Free Software Foundation Inc 675 Mass Ave Cambridge MA 02139 USA Everyone is permitted to copy and distribute verbatim copies of this license document but changing it is not allowed PREAMBLE The licenses for most software are designed to take away your freedom to share and change it By contrast the GNU General Public License is intended to guarantee your freedom to share and change free software to make sure the software is free for all its users This General Public License applies to most of the Free Software Foundation s software and to any other program whose authors commit to using it Some other Free Software Foundation software is covered by the GNU Library General Public License instead You can apply it to your programs too When we speak of free software we are referring to freedom not price Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software and charge for this service if you wish that you receive source code or can get it if you want it that you can change the software or use pieces of it in new free programs and that you know you can do these things To protect your rights we need to make restrictions that forbid anyone to deny you these
51. RAL SPECIAL INCIDENTAL OR CONSEQUENTIAL DAM AGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES END OF TERMS AND CONDITIONS APPENDIX HOW TO APPLY THESE TERMS TO YOUR NEW PROGRAMS La Licencia General P blica GNU 84 If you develop a new program and you want it to be of the greatest possible use to the public the best way to achieve this is to make it free software which everyone can redistribute and change under these terms To do so attach the following notices to the program It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty and each file should have at least the copyright line and a pointer to where the full notice is found one line to give the program s name and a brief idea of what it does Copyright 19yy name of author This program is free software you can redistribute it and or modify it under the terms of the GNU General Public License as published by the Free Software Foundation either version 2 of the License or at your option any later version This program is distributed in the hope that it will be useful but WITHOUT ANY WARRANTY without even the implied warranty
52. SUCCESS E Esta funci n se llama cuando un proceso cierra el fichero del dispositivo No tiene un valor de retorno porque no puede fallar Sin p rdida de consideraci n de lo que pudiera pasar deber as de poder cerrar siempre un dispositivo en 2 0 un fichero de dispositivo 2 2 puede ser imposible de cerrar if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 static int device_release struct inode inode struct file file else static void device_release struct inode inode struct file file fendif ifdef DEBUG printk device_release p p n inode file endif Ahora estamos listos para la siguiente llamada Device_Open p MOD_DEC_USE_COUNT Gl if LINUX_V return 0 endif RSION_CODE gt KERNEL VERSION 2 2 0 Esta funci n se llama cuando un proceso que ya ha abierto el fichero del dispositivo intenta leer de l i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 static ssize_t device_read struct file file char buffer El buffer para rellenar con los datos size_t length La longitud del buffer loff_t offset desplazamiento en el fichero else static int device_read struct inode inode struct file file char buffer El buffer para rellenar con los datos 2 1 Ficheros fuente par
53. WCEP U Ce te ets Shad wh bees Gade deat eae ten thet ees eee ds soe ganado egret Bt rt ariete to eR 70 12 Multiproceso sim trico 74 13 Problemas comunes 75 A Cambios entre 2 0 y 2 2 76 B Desde aqu hasta d nde 77 C Beneficios y servicios 78 C 1 Obteniendo este libro impreso 20 00 0000 002 eee eee 78 D Mostrando tu gratitud 79 E La Licencia General P blica GNU 80 F Sobre la traducci n 85 Indice 85 Capitulo 0 Introduccion As que quieres escribir un m dulo del n cleo Sabes C has escrito algunos programas corrientes que se ejecutan como procesos y ahora quieres ir donde est la verdadera acci n donde un simple puntero salvaje puede destruir tu sistema de ficheros y donde un volcado de memoria core dump significa un reinicio de la m quina Bueno pues bienvenido al club A m en una ocasi n un puntero salvaje me hizo un estropicio en un directorio importante bajo DOS gracias que ahora significa Dead Operating System Sistema Operativo Muerto y no veo por qu vivir bajo Linux deber a ser algo m s seguro que esto Advertencia He escrito esto y verificado el programa bajo versiones 2 0 35 y 2 2 3 del n cleo funcio nando en un Pentium Para la mayor parte deber a funcionar en otras CPUs y en otras versiones del n cleo siempre que sean 2 0 x o 2 2 x pero no puedo prometer nada Una excepci n es el cap tulo 11 que no deber a funcionar en ninguna arquitectura excepto x86 0 1 Qui n deber a leer es
54. a varias versiones del nucleo 35 int length La longitud del buffer lt no debemos de escribir m s all de l endif N mero de bytes actualmente escritos en el buffer int bytes_read 0 ifdef DEBUG printk device_read p p d n file buffer length endif Si estamos al final del mensaje retornamos 0 lo cual significa el final del fichero if Message_Ptr 0 return 0 Realmente ponemos los datos en el buffer while length amp amp Message_Ptr Como el buffer est en el segmento de datos del usuario y no en el segmento de datos del n cleo la asignaci n no funcionar En vez de ello tenemos que usar put_user el cual copia datos desd l segmento de datos del n cleo al segmento de datos del usuario put_user Message_Ptr buffer length bytes_read ifdef DEBUG printk Le dos d bytes quedan d n bytes_read length endif Las funciones de lectura se supone que devuelven el numero de bytes realmente insertados en el buffer return bytes_read Esta funci n se llama cuando alguien intenta escribir en nuestro fichero de dispositivo if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 static ssize_t device _write struct file file const char buffer size_t length loff_t offset else static int device_write stru
55. am into proprietary programs If your program is a subroutine library you may consider it more useful to permit linking proprietary applica tions with the library If this is what you want to do use the GNU Library General Public License instead of this License Ap ndice F Sobre la traduccion Este documento es la traducci n de Linux Kernel Module Programing Guide 1 1 0 y el proceso de traducci n ha sido llevado a cabo por e Traductor Rub n Melc n Fari a lt melkon terra es gt e Revisor scar Sanz Lorenzo lt gaaldornik Oterra es gt e Encargado de Calidad Francisco Javier Fern ndez lt franciscojavier fernandez serradorOhispalinux es gt e Traducci n posterior Francisco Vila lt francisco vila hispalinux es gt Documento publicado por el proyecto de documentaci n de Linux http www es tldp org N mero de revisi n 0 15 Agosto de 2003 Si tienes comentarios y o sugerencias sobre la traducci n ponte en contacto con Francisco Javier Fern ndez lt franciscojavier fernandez serrador O hispalinux es gt 85 Indice de Materias dev 9 proc 23 usando para entrada 23 proc interrupts 69 proc ksyms 75 proc meminfo 18 proc modules 6 10 18 JO 31 IOR 31 JOW 31 IOWR 31 NSIG_WORDS 76 KERNEL__ 5 NO_VERSION__ 6 SMP_ 5 2 2 cambios 76 abrir 47 llamada al sistema 47 acceso secuencial 9 actual 23 puntero 23 argc 43 argv 43 arquitectura Intel 70 teclado 70 asignaci
56. an estrictamente al est ndar ASCII De acuerdo con ASCII para mover una nueva linea necesitas dos caracteres un retorno de carro y un salto de linea En Unix en cambio el salto de linea ASCII es usado para ambos prop sitos por lo tanto no podemos usar Ain porque no tendr un retorno de carro y la siguiente linea empezar en la columna siguiente despu s del paso de linea BTW este es el motivo por el que el formato de un fichero de texto es diferent ntre Unix y Windows En CP M y sus derivados tales como MS DOS y Windows el est ndar ASCII fue estrictamente adherido y entonces una nueva linea requiere un salto de linea y un retorno de carro my_tty gt driver write 2 1 Ficheros fuente para varias versiones del nucleo 63 my_tty 0 015 012 2 Inicializaci n y Limpieza del m dulo XXXXXXXXRKAXX amp Inicializa el m dulo registra el fichero proc int init_module print_string M dulo insertado return 0 Limpieza libera nuestro fichero de proc void cleanup_module print_string M dulo borrado Capitulo 10 Planificando tareas Muy frecuentemente tenemos tareas de labores dom sticas que tienen que ser realizadas en un cierto tiempo o todas frecuentemente Si la tarea tiene que ser realizada por un proceso lo haremos poni ndolo en el fichero crontab Si la tarea es realizada por un m dulo del n cleo
57. ario porque usamos el sistema de ficheros proc include lt linux proc_fs h gt Para poner los procesos a dormir y despertarlos include lt linux sched h gt include lt linux wrapper h gt En 2 2 3 usr include linux version h se incluye una macro para esto pero 2 0 35 no lo hace por lo tanto lo a ado aqu si es necesario ifndef KERNEL_VERSION define KERNEL_VERSION a b c a 65536 b 256 c endif if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 include lt asm uaccess h gt para get_user y put_user endif Las funciones de fichero del m dulo KKKKKKKKKKKKKKKKKKK x Aqu mantenemos el ltimo mensaje recibido para probar que podemos procesar nuestra entrada define MESSAGE_LENGTH 80 H static char Message MESSAGE_LENGTH Como usamos las estructuras de operaciones de ficheros no 2 1 Ficheros fuente para varias versiones del n cleo 54 podemos usar las provisiones de salida de proc especiales tenemos que usar una funci n est ndar de lectura que es esta if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 static ssize_t module_output struct file file El fichero a leer char buf El buffer donde poner los datos en el segmento de usuario size_t len La longitud del buffer loff_t offset Desp
58. az de discos Sin embargo he escogido no hacerlo Mi prop sito al escribir este libro era dar una iniciaci n en los misterios de la programaci n de m dulos del n cleo y ense ar las t cnicas m s comunes para ese prop sito Para la gente seriamente interesada en la programaci n del n cleo recomiendo la lista de recursos del n cleo de Juan Mariano de Goyeneche que est en http jungla dit upm es jmseyas linux kernel hackers docs html Tambi n como dijo Linus la mejor forma de aprender el n cleo es leer t mismo el c digo fuente Si est s interesado en m s ejemplos de m dulos cortos del n cleo te recomiendo la revista Phrack Incluso si no est s interesado en seguridad y como programador deber as estarlo los m dulos del n cleo son buenos ejemplos de lo que puedes hacer dentro del n cleo y son lo bastante peque os como para que su comprensi n no requiera demasiado esfuerzo Espero haberte ayudado en tu misi n de convertirte en un mejor programador o al menos divertirte a trav s de la tecnolog a Y si escribes m dulos del n cleo tiles espero que los publiques bajo la GPL para que yo tambi n pueda utilizarlos 77 Ap ndice C Beneficios y servicios Espero que a nadie le importen las presentes promociones descaradas Todo son cosas probablemente tiles para los programadores noveles de m dulos del n cleo Linux C 1 Obteniendo este libro impreso El grupo Coriolis va a imprimir este libro varias veces
59. bles globales en el m dulo del n cleo e insmod las rellenar por nosotros En este m dulo del n cleo definimos dos de ellas str1 y str2 Todo lo que necesitas hacer es compilar el m dulo del n cleo y entonces ejecutar insmod strl xxx str2 yyy Cuando se llama a init module str1 apuntar a la cadena de caracteres xxx y str2 a la cadena de caracteres y y y En la versi n 2 0 no hay comprobaci n de tipos de estos argumentos Si el primer car cter de str1 o st r2 es un d gito el n cleo rellenar la variable con el valor del entero en vez de con un puntero a la cadena de caracteres En una situaci n de la vida real tienes que verificar esto En cambio en la versi n 2 2 usas la macro MACRO_PARM para decir a insmod lo que esperas como par metros su nombre y su tipo Esto resuelve el problema de los tipos y permite a los m dulos del n cleo recibir cadenas de caracteres que empiezan con un d gito por ejemplo param c param c Recib n linea de comandos los par metros en la instalaci n del m dulo Copyright C 1998 99 by Ori Pomerantz Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo No puede haberlos ya que bajo C el fichero objeto s lo tiene la localizaci n de las variables globales no de
60. cleo 24 sita passarse entre el proceso actualmente en ejecuci n y el n cleo la funci n del n cleo recibe un puntero al b fer de memoria que est en el segmento del proceso Las macros put_user y get_user nos permiten acceder a esa memoria procfs c procfs c crea un fichero en proc que permite entrada y salida Copyright C 1998 1999 by Ori Pomerantz Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo T Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif Necesario porque usamos el sistema de ficheros proc include lt linux proc_fs h gt En 2 2 3 usr include linux version h se incluye una macro para eso pero 2 0 35 no lo hace por lo tanto lo a ado aqu si es necesario ifndef KERNEL_VERSION define KERNEL_VERSION a b c a 65536 b 256 c endif if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 include lt asm uaccess h gt para get_user y put_user endif Las funciones del fichero del m dulo KKKKKKKKKKKKKKKKKKKK Aqu mantenemos el ltimo mensaje recibido para comprobar que podemos procesar nuestra entrada
61. ct inode inode struct file file const char buffer 2 1 Ficheros fuente para varias versiones del n cleo 36 int length fendif int i ifdef DEBUG printk device_write p s d file buffer length endif for i 0 i lt length amp amp i lt BUF_LEN i if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 get_user Message i buffer i else Message i get_user buffer i endif Message_Ptr Message De nuevo retornamos el n mero de caracteres de entrada usados return i Esta funci n es llamada cuando un proceso intenta realizar una ioctl en nuestro fichero de dispositivo Cogemos dos par metros extra en adici n al inodo y a las estructuras del fichero los cuales cogen todas las funciones de dispositivo el n mero de ioctl llamado y el par metro dado a la funci n ioctl Si el ioctl es de escritura o de lectura escritura significa que la salida es devuelta al proceso que llama la llamada ioctl retorna la salida de esta funci n y int device_ioctl struct inode inode struct file fite unsigned int ioctl_num El n mero de ioctl unsigned long ioctl_param El par metro a l int 1 char temp if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 char ch endif Se intercambia de acuerdo al ioctl llamado switch ioctl_num case IOCTL_SET_MSG
62. ctura del inodo anterior y Inicializaci n y Limpieza del m dulo XXXXXXXX XX X Inicializa el m dulo registra el fichero proc int init_module Tiene xito si proc_register_dynamic tiene xito 2 1 Ficheros fuente para varias versiones del nucleo 60 falla en otro caso if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 return proc_register amp proc_root amp Our_Proc_File else return proc_register_dynamic amp proc_root amp Our_Proc_File endif proc_root es el directorio raiz para el sistema de x ficheros proc proc Es decir donde queremos que sea localizado nuestro fichero Limpieza libera nuestro fichero en proc Esto puede ser peligroso si a n hay procesos esperando en WaitQ porque ellos est n dentro de nuestra funci n open la cual ser descargada Explicar que hacer para quitar un m dulo del n cleo en tal caso en el cap tulo 10 void cleanup_module proc_unregister amp proc_root Our_Proc_File low_ino Capitulo 9 Reemplazando printk s Al principio cap tulo 1 dije que X y la programaci n de m dulos del n cleo no se mezclaban Esto es verdad para el desarrollo de m dulos del n cleo pero en el uso real quieres poder enviar mensajes a cualquiera que sea el tty de donde vino la orden que carg el m dulo La forma de hacer esto es usando current un puntero a la tar
63. dir mknod ULL renombrar ULL leer enlace ULL seguir el enlace ULL leer pagina ULL escribir p gina ULL bmap ULL cortar E an Pe a a a a Z C module _permission chequeo para permisos 2 1 Ficheros fuente para varias versiones del nucleo 29 y Entrada de directorio static struct proc_dir_entry Our_Proc_File 0 N mero de inodo ign ralo ser autom ticamente rellenado por proc_register _dynamic 7 Longitud del nombre del fichero rw_test El nombre del fichero S_IFREG S_IRUGO S_IWUSR Modo del fichero este es un fichero normal el cual puede ser le do por su due o su grupo y por todo el mundo Tambi n su due o puede escribir en l Realmente este campo es s lo para referencia es module_permission el que hac 1 chequeo actual Puede usar este campo pero en nuestra implementaci n no lo hace por simplificaci n 1 N mero d nlaces directorios donde el fichero est referenciado 0 0 El uid y gid para el fichero se lo damos a root 80 El tama o del fichero reportado por ls amp Inode_Ops_4 Our_Proc_File Un puntero a la estructura del inodo para el fichero si lo necesitamos En nuestro caso lo hacemos porque necesitamos una funci n de
64. e conviene al hardware no a la CPU Los dispositivos hardware t picamente tienen una peque a cantidad de RAM y si no lees su informaci n cuando est disponible se pierde Bajo Linux las interrupciones hardware se llaman IRQs abreviatura de Interrupt Requests Hay dos tipos de IRQs cortas y largas Una IRQ corta es la que se espera que dure un periodo de tiempo muy corto durante el cual el resto de la m quina estar bloqueado y ninguna otra interrupci n ser manejada Una IRQ larga es una que puede durar m s tiempo y durante la cual otras interrupciones pueden ocurrir pero no interrupciones que vengan del mismo dispositivo Si es posible siempre es mejor declarar un manejador de interrupciones como largo Cuando la CPU recibe una interrupci n detiene lo que quiera que est haciendo a menos que se encuentre procesando una interrupci n m s prioritaria en cuyo caso tratar con esta interrupci n s lo cuando la m s prioritaria se haya acabado salva ciertos par metros en la pila y llama al manejador de interrupciones Esto significa que ciertas cosas no se permiten dentro del propio manejador de interrupciones porque el sistema se encuentra en un estado desconocido La soluci n a este problema es que el manejador de interrupciones haga lo que necesite hacer inmediatamente normalmente leer algo desde el hardware o enviar algo al hardware y despu s planificar el manejo de la nueva informaci n en un tiempo posterior esto se lla
65. e h gt include lt linux version h gt Estamos haciendo trabajo del n cleo Este no es el fichero del m dulo del n cleo Espec ficamente un m dulo No incluido por module h debido a __ NO _VERSION__ 1 2 M dulos del nucleo de varios ficheros Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif Limpieza deshacemos todo aquello que hizo init_module void cleanup_module printk La vida de un m dulo del n cleo es corta n Makefile Makefile para un m dulo multiarchivo del n cleo CC gcc MODCFLAGS Wall DMODULE D__KERNEL__ DLINUX hello o start o stop o ld m elf_i386 r o hello o start o stop o start o start c usr include linux version h CC MODCFLAGS c start c stop o stop c usr include linux version h CC MODCFLAGS c stop c Capitulo 2 Ficheros de dispositivos de caracter As que ahora somos unos valientes programadores del n cleo y sabemos escribir m dulos que no hacen nada Estamos orgullosos de nosotros mismos y llevamos la cabeza bien alta Pero de alg n modo sentimos que falta algo Los m dulos catat nicos no son muy divertidos Hay dos formas principales de que un m dulo del n cleo se comunique con los procesos Una es a trav s de los ficheros de dispositivos como los que est n en el di
66. e practices Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system it is up to the author donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License If the distribution and or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries so that distribution is permitted only in or among countries not thus excluded In such case this License incorporates the limitation as if written in the body of this License The Free Software Foundation may publish revised and or new versions of the General Public License from time to time Such new versions will be similar in spirit to the present version but may differ in detail to address new problems or concerns Each version is given a distinguishing version number If the Program specifies a version number of this License which applies to it and any later version you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation If
67. ea actualmente en ejecuci n para obtener la estructura tty de la tarea actual Despu s miramos dentro de la estructura tty para encontrar un puntero a una funci n de escritura de cadenas de caracteres que usamos para escribir una cadena de caracteres a la tty printk c printk c env a salida textual al tty en el que est s ahora sin importarle cuando es pasado a trav s de X11 telnet etc Copyright C 1998 por Ori Pomerantz Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif T Necesarios aqu include lt linux sched h gt Para el actual include lt linux tty h gt Para las declaraciones de tty Imprime la cadena de caracteres al tty apropiado el gue usa la tarea actual Teletype originalmente una combinaci n de teclado e impresora usada para comunicarse con un sistema Unix y hoy una abstrac ci n para el flujo de texto usado para un programa Unix ya sea un terminal f sico un xterm una pantalla X una conexi n de red usada con telnet etc 61 2 1 Ficheros fuente para varias versiones del nucleo 62 void print_string cha
68. eber a de funcionar xg if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 for i 0 i lt _NSIG_WORDS amp amp is_sig i is_sig current gt signal siglil amp current gt blocked siglil if is_sig else if current gt signal amp current gt blocked endif Es importante poner MOD_DEC_USE_COUNT aqu porque los procesos d nde open es interrumpido no tendr n nunca un close correspondiente Si no decrementamos el contador de uso aqu lo dejaremos con un valor positivo el cual no nos dar la oportunidad de llegar hasta 0 d ndonos un m dulo inmortal que s lo se puede matar reiniciando la m quina MOD_DEC_USE_COUNT return EINTR 2 1 Ficheros fuente para varias versiones del n cleo 57 Si estamos aqui Already_Open debe ser cero Abre el fichero Already_Open 1 return 0 Permit l acceso Llamado cuando el fichero proc se cierra if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 int module _close struct inode inode struct file file else void module_close struct inode inode struct file file endif Establece Already_Open a cero por lo tanto uno de los procesos en WaitQ ser capaz d stablecer Already_Open otra vez a uno y abrir el fichero Todos los otros procesos ser n llamados cuando Already_Open vuelva a ser uno
69. ejecuta sync justo antes de hacer el insmod y el rmmod Olv date de los ficheros proc olv date de los ficheros de los dispositivos Son s lo detalles menores El mecanismo real de comunicaci n entre los procesos y el n cleo el que usan todos los procesos son las llamadas al sistema Cuando un proceso pide un servicio al n cleo tal como abrir un fichero ramificarse en un nuevo proceso o pedir m s memoria ste es el mecanismo que se usa Si quieres cambiar el compor tamiento del n cleo de formas interesantes ste es el sitio para hacerlo Por cierto si quieres ver las llamadas al sistema que usa un programa ejecuta strace orden argumentos En general un proceso se supone que no puede acceder al n cleo No puede acceder a la memoria del n cleo y no puede llamar a las funciones del n cleo El hardware de la CPU fuerza esto por eso se le llama modo protegido Las llamadas al sistema son una excepci n a esta regla general Lo que sucede es que el proceso rellena los registros con los valores apropiados y entonces llama a una instrucci n especial que salta a una posici n previamente definida dentro del n cleo por supuesto la posici n es legible por los procesos de usuario pero no pueden escribir en ella Bajo las CPUs de Intel esto se hace por medio de la interrupci n 0x80 El hardware sabe que una vez que saltas a esta localizaci n ya no te estar s ejecutando en el modo restringido de usuario sino como el n cle
70. el n cleo sea borrado cuando root quiera El motivo es que si el fichero del dispositivo es abierto por un proceso y entonces quitamos el m dulo del n cleo el uso del fichero causar a una llamada a la posici n de memoria donde la funci n apropiada read write usada deber a estar Si tenemos suerte ning n otro c digo fue cargado all y obtendremos un feo mensaje Si no tenemos suerte otro m dulo del n cleo fue cargado en la misma posici n lo que significar un salto en mitad de otra funci n del n cleo El resultado ser a imposible de predecir pero no ser a positivo Normalmente cuando no quieres permitir algo devuelves un c digo de error un n mero negativo desde la funci n que se supone que lo tendr a que hacer Con cleanup module esto es imposible porque es una funci n void Una vez que se llama a cleanup_module el m dulo est muerto En todo caso hay un contador que cuenta cu ntos otros m dulos del n cleo est n usando el m dulo llamado contador de referencia que es el ltimo n mero de la l nea en proc modules Si este n mero es distinto de cero rmmod fallar La cuenta de referencia del m dulo est disponible en la variable mod_use_count_ Como hay macros definidas para manejar esta variable MOD_INC_USE_COUNT y MOD_DEC_USE_COUNT preferimos usarlas mejor que utilizar mod_use_count_ directamente por lo tanto ser m s seguro si la implementaci n cambia en el futuro chardev c
71. ento deben ponerse bajo la Licencia General P blica de GNU y el anuncio original de copyright debe permanecer intacto Si has aportado material nuevo a este libro debes hacer que el c digo fuente p ej c digo XTFX est disponible libremente para que te lo puedan revisar Por favor pon las revisiones y actualizaciones a disposici n del mantenedor del documento Ori Pomerantz directamente Esto permitir la fusi n de las actualizaciones y suministrar unas revisiones consistentes a la comunidad Linux Si est s pensando publicar y distribuir este libro comercialmente las donaciones el pago de derechos y o copias impresas ser n enormemente agradecidos por parte del autor y del Proyecto de Documentaci n de Linux LDP La contribuci n hecha de esta manera demuestra tu soporte al software libre y al LDP Si tienes preguntas o comentarios que hacer por favor pornte en contacto con la direcci n anterior Indice General 0 Introducci n 0 T Qui n deberidileer esto la a E eee a A A AAA EM ape he 0 2 Un apunte sobreelestilo bir weet pi a Be Sh ee ee e wel ee ido 037 CAMDIOS ia ica Se aks i eee kA Gas Bele Bead a SRS HGR Se degen hes 0 3 1 Nuevoenla versi n 1 0 1 ee ee 0 3 2 Nuevoenla versi n 1 1 0 e 0 4 Agradecimientos e a a a ee ba eee ee 0 4 1 Parala versi n LOL 2 2 05 244 9 24 a a eR A BS wea ee aS 042 Para la versi n TAO z tdt eds anche hae a edt Goldy a wee tne WRT 1 H
72. er_dynamic Esta funci n ya no existe En vez de ello llamas al proc_register normal y pones cero en el campo de inodo de la estructura 7 Se ales Las se ales en la estructura de tareas ya no son un entero de 32 bits sino un array de enteros NSIG_WORDS 8 queue_task_irq Incluso si quieres planificar una tarea para que suceda dentro de un manejador de interrupciones usa queue task no queue_task_ird 9 Par metros del M dulo Ya no hay que simplemente declarar los par metros del m dulo como vari ables globales En 2 2 tienes que usar tambi n MODULE_PARM para declarar su tipo Esto es una gran mejora porque permite que el m dulo reciba par metros de cadenas de caracteres que empiezan con un d gito por ejemplo sin que esto le confunda 10 Multiproceso sim trico El n cleo ya no est dentro de un solo spinlock grande lo que significa que los m dulos del n cleo tienen que tener en cuenta el SMP 76 Ap ndice B Desde aqu hasta d nde Podr a haber introducido f cilmente unos cuantos cap tulos m s en este libro Podr a haber a adido un cap tulo sobre c mo crear nuevos sistemas de ficheros o sobre c mo a adir nuevas pilas de protocolos como si hubiera necesidad de esto tendr as que excavar bajo tierra para encontrar una pila de protocolos que no est n soportados por Linux Podr a haber a adido explicaciones sobre los mecanismos del n cleo que no hemos tocado tales como el arranque o la interf
73. es separadas la parte del m dulo que registra el dispositivo y la parte del controlador del dispositivo La funci n init module llama a module register _chrdev para a adir el controlador de dispositivo a la tabla de controladores de dispositivos de car cter del n cleo Tambi n devuelve el n mero mayor que usar el controlador La funci n cleanup_module libera el dispositivo Esto registrar y liberar algo es la funcionalidad general de estas dos funciones Las cosas en el n cleo 1 2 M dulos del n cleo de varios ficheros 10 no funcionan por su propia iniciativa como los procesos sino que son llamados por procesos a trav s de las llamadas al sistema o por los dispositivos hardware a trav s de las interrupciones o por otras partes del n cleo simplemente llamando a funciones espec ficas Como resultado cuando a ades c digo al n cleo se supone que es para registrarlo como parte de un manejador o para un cierto tipo de evento y cuando lo quitas se supone que lo liberas El controlador del dispositivo se compone de cuatro funciones device_ lt acci n gt que se llaman cuando alguien intenta hacer algo con un fichero de dispositivo con nuestro n mero mayor La forma en que el n cleo sabe c mo llamarlas es a trav s de la estructura file operations Fops que se dio cuando el dispositivo fue registrado e incluye punteros a esas cuatro funciones Otro punto que hemos de recordar aqu es que podemos permitir que el m dulo d
74. escritura NULL La funci n de lectura para el fichero Irrelevante porque lo ponemos en la estructura de inodo anterior Inicializaci n del m dulo y limpieza KKKKKKKKKK KKK KK Inicializa el m dulo registra el fichero proc int init_module Tiene xito si proc_register _dynamic tiene xito falla en otro caso if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 En la versi n 2 2 proc_register asigna din micamente un numero de inodo autom ticamente si hay un cero en la estructura por lo tanto no se necesita m s para proc_register_dynamic EL return proc_register proc_root 0ur_Proc_File else return proc_register_dynamic amp proc_root amp Our_Proc_File fendif 2 1 Ficheros fuente para varias versiones del nucleo Limpieza liberamos nuestro fichero de proc void cleanup_module proc_unregister amp proc_root Our_Proc_File low_ino Capitulo 5 Hablando con los ficheros de dispositivo escrituras y IOCTLs Los ficheros de dispositivos se supone que representan dispositivos fisicos La mayoria de los dispositivos f sicos se utilizan para salida y para entrada por lo tanto tiene que haber alg n mecanismo para que los controladores de dispositivos que est n en el n cleo obtengan la salida a enviar al dispositivo desde los procesos Esto se hace abriendo el fichero del dispositivo para salida y e
75. evice_open if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 NULL borrar fendif device_releas a k a cerrar y Inicializa el m dulo Registra el dispositivo de car cter int init_module Registra el dispositivo de car cter por lo menos lo intenta Major module_register_chrdev 0 DEVICE_NAME amp FoOps 2 1 Ficheros fuente para varias versiones del nucleo 16 Valores negativos significan un error if Major lt 0 printk dispositivo s fall con d n Lo siento registrando el car cter Major return Major printk s El n mero mayor del dispositivo es d n El registro es un xito Major printk si quieres hablar con el controlador del dispositivo n printk tendr s que crear un fichero de dispositivo An mknod lt nombre gt c d lt menor gt n Major printk Te sugerimos que uses n printk Puedes probar diferentes n meros menores s printk y ver que pasa n return 0 Limpieza liberamos el fichero correspondiente desde proc void cleanup_module int ret liberamos el dispositivo ret module_unregister_chrdev Major DEVICE_NAMBE Si hay un error lo indicamos if ret lt 0 printk Error en unregister_chrdev d n ret 2 1 Ficheros fuente para varias versiones del n cleo
76. har buf El buffer con la entrada int length La longitud del buffer fendif int i Pone la entrada en Message donde module_output mas tarde serd capaz de usarlo for i 0 i1 lt MESSAGE_LENGTH 1 amp amp i lt length i i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 get_user Message i bufti else Message i get_user buf i endif queremos un est ndar cadena de caracteres terminada en cero Message i X0 Necesitamos devolver el numero de caracteres de entrada usados return i 1 si el fichero esta actualmente abierto por alguien int Already_Open 0 Cola de procesos que quieren nuestro fichero static struct wait_queue WaitQ NULL Llamado cuando el fichero proc se abre static int module_open struct inode inode struct file file Si las banderas del fichero incluyen O_NONBLOCK esto significa que el proceso no quiere esperar al fichero En este caso si el fichero ya est abierto deberemos fallar con EAGAIN significando que tienes que intentarlo otra vez en vez de bloquear un proceso que tendr a que estar despierto if file gt f_flags amp O_NONBLOCK 88 Already_Open return EAGAIN Este es el sitio correcto para MOD_INC_USE_COUNT porque si un proceso est en el bucle que est dentro del m dulo el m dulo del
77. hardev h 39 hello c 4 intrpt c 70 ioctl c 40 Makefile 5 8 param c 43 printk c 61 procfs c 18 24 sched c 64 sleep c 53 start c 6 stop c 7 syscall c 47 ssize_t 76 start c source file 6 stop c source file 7 strace 46 struct file_operations 10 23 struct inode_operations 23 struct proc_dir_entry 23 struct tq_struct 64 sync 46 sys_call table 46 sys_open 47 syscall c source file 47 system_call 46 tarea 61 64 actual 61 tarea actual 61 tareas planificando 64 task structure 52 TASK_INTERRUPTIBLE 52 INDICE DE MATERIAS 89 teclado 70 terminal 9 terminal virtual 6 tq_immediate 70 tq_struct struct 64 tq_timer 64 tty_struct 61 uaccess h asm 76 varios ficheros fuente 6 version en desarrollo 17 nucleo 17 version estable 17 nucleo 17 version h 6 versiones nucleo 76 versiones del n cleo 16 versiones soportadas 17 virtual 6 terminal 6 write 76 X 6 porqu las deberias evitar 6 xterm C 6
78. hts granted herein You are not responsible for enforcing compliance by third parties to this License 7 Tf as a consequence of a court judgment or allegation of patent infringement or for any other reason not limited to patent issues conditions are imposed on you whether by court order agreement or otherwise that contradict the conditions of this License they do not excuse you from the conditions of this License If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations then as a consequence you may not distribute the Program at all For example if a patent license would not permit royalty free redistribution of the Program by all those who receive copies directly or indirectly through you then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program If any portion of this section is held invalid or unenforceable under any particular circumstance the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances La Licencia General P blica GNU 83 10 11 12 It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public licens
79. ifndef KERNEL_VERSION define KERNEL_VERSION a b c endif Bottom Half esto ser lla tan pronto como sea seguro permitido por los m dulos del n cleo static void got_char void sca printk C digo le do x s int char scancode char scancode amp 0x8 version h se incluye una 5 no lo hace por lo tanto Ap Os a 65536 b 256 c mado por el n cleo hacer todo lo normalmente ncode ant amp Ox7F 0 Liberado Presionado interrupciones de teclado Lee Esta funci n sirve para las la informaci n relevante desd planifica el bottom half pa lo considere seguro void irq_handler int irq void dev_id struct pt_reg Estas variables son est t accesibles a trav s de punteros half 1 teclado y entonces ra ejecutarse cuando el n cleo s regs icas porque necesitan ser por la rutina bottom static unsigned char scancode static struct tq_struct task NULL 0 unsigned char status got_char Lee el estado del teclado inb 0x64 inb 0x60 status scancode Planifica el bot amp scancode E tom half para ejecutarse if LINUX_VERSION_CODE gt K ERN EL_V ERSION 2 2 0 queue_task amp task else queue_task_irgq amp task endif mark_bh IMMEDIATE_BH tq_immediate amp tq_immediate 11 1 Teclados
80. ipo start c start c Copyright C 1999 by Ori Pomerantz Hola mundo la versi n m dulo del n cleo Este fichero incluye justamente la rutina de comienzo Los ficheros de cabeceras necesarios 1E motivo por el que prefiero no compilar como root es que cuanto menos cosas se hagan como root m s seguro estar el equipo Trabajo en seguridad inform tica as que soy un paranoico 1 2 M dulos del nucleo de varios ficheros Est ndar en los m dulos del n cleo include lt linux kernel h gt include lt linux module h gt Estamos haciendo trabajo del n cleo Espec ficamente un m dulo Distribuido con CONFIG_MODVERSIONS Hif CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif Inicializa el m dulo int init _module printk Hola mundo este es el n cleo hablando n Si retornamos un valor distinto de cero significa que init_module fall y el m dulo del n cleo no puede ser cargado return 0 stop c stop c Copyright C 1999 by Ori Pomerantz x Hola mundo la versi n m dulo del n cleo Este fichero incluye justamente la rutina de parada ol Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt define __NO_VERSION__ include lt linux modul
81. ir ULL mknod ULL renonmbrar leer enlace ULL seguir enlace ULL lee pagina ULL excribe p gina ULL bmap ULL corta module_permission chequea los permisos y 2224224 z 22242 Entrada del directorio static struct proc_dir_entry Our_Proc_File 0 N mero de inodo ign ralo ser rellenado por proc_register _dynamic 5 Longitud del nombre del fichero Sleep El nombre del fichero S_IFREG S_IRUGO S_IWUSR Modo del fichero este es un fichero normal que puede ser le do por su due o su grupo y por todo el mundo Adem s su due o puede escribir en l Realmente ste campo es s lo para referencia es module_permission el que realiza el chequeo actual Puede usar este campo pero en nuestra implementaci n no lo hace por simplificaci n 1 N mero d nlaces directorios donde el fichero es referenciado 0 0 El uid y gid para el fichero se los damos a root 80 El tama o del fichero indicado por ls amp Inode_Ops_4 Our_Proc_File Un puntero a la estructura de inodos para el fichero si lo necesitamos En nuestro caso lo hacemos porque necesitamos una funci n write de escritura NULL La funci n read para el fichero Irrelevante porque lo ponemos en la estru
82. is distributed in the hope it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose The author encourages wide distribution of this book for personal or commercial use provided the above copyright notice remains intact and the method adheres to the provisions of the GNU General Public License see Appendix E In summary you may copy and distribute this book free of charge or for a profit No explicit permission is required from the author for reproduction of this book in any medium physical or electronic Note derivative works and translations of this document must be placed under the GNU General Public License and the original copyright notice must remain intact If you have contributed new material to this book you must make the source code e g BIEX source available for your revisions Please make revisions and updates available directly to the document maintainer Ori Pomerantz This will allow for the merging of updates and provide consistent revisions to the Linux community If you plan to publish and distribute this book commercially donations royalties and or printed copies are greatly appreciated by the author and the Linux Documentation Project Contributing in this way shows your support for free software and the Linux Documentation Project If you have questions or comments please contact the address above Los nombres de todos los productos adjuntos
83. l n cleo 47 e imprimir un mensaje con printk cuando el usuario abra un fichero Para conseguir dicha meta reem plazamos la llamada al sistema que abre un fichero con nuestra propia funci n llamada our_sys_open Esta funci n verifica el uid identificaci n del usuario del proceso actual y si es igual al uid que queremos espiar llama a printk para mostrar el nombre del fichero que se va a abrir Luego llama a la funci n original open con los mismos par metros para realmente abrir el fichero La funci n init_module sustituye la localizaci n apropiada que est en sys_call_table y mantiene el puntero original en una variable La funci n cleanup_module utiliza dicha variable para devolver todo a su estado normal Esta aproximaci n es peligrosa por la posibilidad de que dos m dulos del n cleo cambien la misma llamada al sistema Imag nate que tenemos dos m dulos del n cleo A y B La llamada al sistema de A ser A_open y la de B ser B_open Ahora cuando A se inserta en el n cleo la llamada al sistema es reemplazada con A_open la cual llamar a la sys_open original cuando haya acabado A continuaci n B es insertado en el n cleo que reemplaza la llamada al sistema con B_open que a su vez ejecutar la llamada al sistema que l piensa que es la original A open cuando haya terminado Ahora si B se quita primero todo estar bien simplemente restaurar la llamada al sistema a A_open la cual llama a la original En cambi
84. lazamiento en el fichero ign ralo else static int module_output struct inode inode El inodo a leer struct file file El fichero a leer char buf El buffer donde poner los datos en el segmento de usuario int len La longitud del buffer fendif static int finished 0 int i H ENGTH 30 char message MESSAGE Retorna 0 para significar el final del fichero que no tenemos nada m s que decir en este punto if finished finished 0 return 0 Si no entiendes esto ahora eres un programador del nucleo sin esperanza sprintf message Ultima entrada s n Message for i 0 i lt len amp amp message i i put_user message i buf i finished 1 return i Retorna el n mero de bytes le dos Esta funci n recibe la entrada del usuario cuando el usuario escribe el fichero proc if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 static ssize_t module_input struct file file El mismo fichero const char buf El buffer con la entrada size_t length La longitud del buffer loff_t offset desplazamiento del fichero ign ralo else static int module_input struct inode inode El inodo del fichero struct file file El mismo fichero 2 1 Ficheros fuente para varias versiones del nucleo 55 const c
85. m dulo se inserta en el n cleo y cleanup_module que se llama justo antes de ser quitado T picamente init_module o bien registra un manejador para algo que tiene que ver con el n cleo o reemplaza una de las funciones del n cleo con su propio c digo normalmente c digo para hacer algo y luego llamar a la funci n original La funci n cleanup_module se supone que deshace lo que init_module ha hecho de forma que el m dulo pueda ser descargado de una forma segura hello c hello c Copyright C 1998 by Ori Pomerantz Hello world la versi n m dulo del n cleo E Los archivos de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos realizando trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif Inicializa el m dulo int init _module 1 1 Makefiles para los m dulos del n cleo 5 printk Hola mundo este es el n cleo hablando n Si retornamos un valor distinto de cero significa que init_module fall y el m dulo del n cleo no puede ser cargado return 0 Limpieza deshacemos todo aquello que hizo init_module void cleanup_module printk La vida de un m dulo del n cleo es corta n 1
86. ma bottom half y retorna El n cleo est garantizado que llamar al bottom half tan pronto como sea posible y cuando lo haga todo lo que est permitido en los m dulos del n cleo estar permitido La forma de implementar esto es llamar a request_irq para que se llame a tu manejador de inter rupciones cuando se reciba la IRQ relevante hay 15 de ellas m s una que se utiliza para disponer en cascada los controladores de interrupci n en las plataformas Intel Esta funci n recibe el n mero de IRQ el nombre de la funci n banderas un nombre para proc interrupts y un par metro para pasarle al manejador de interrupciones Las banderas pueden incluir SA_SHTRO para indicar que est s permitiendo compartir la IRQ con otro manejador de interrupciones normalmente porque un n mero de dispositivos hardware est n en la misma IRQ y SA INTERRUPT para indicar que esta es una interrupci n r pida Esta funci n s lo tendr xito si no hay ya un manejador para esta IRQ o si ya la estais compartiendo Entonces desde dentro del manejador de interrupciones nos comunicamos con el hardware y despu s usamos queue task _irq con tq_immediate y mark_bh BH_IMMEDIATE para planificar el bottom half El motivo por el que no podemos usar la queue_task est ndar en la versi n 2 0 es que la interrupci n podr a producirse en el medio de la queue task de alguien Necesitamos mark_bh Esta es una nomenclatura est ndar
87. mero mayor del dispositivo el tipo de la ioctl la orden y el tipo del par metro Este n mero ioctl es normalmente creado por una llamada a una macro _IO _IOR IOW o _IOWR dependiendo del tipo en el fichero de cabeceras Este fichero de cabeceras deber a ser incluido include tanto en los programas que van a usar ioct 1 para que puedan generar los ioct 1s apropia dos como por el m dulo del n cleo para que lo entienda En el ejemplo siguiente el fichero de cabeceras es chardev h y el programa que lo usa es ioctl c Si quieres usar ioctls en tus propios m dulos del n cleo es mejor recibir un asignaci n ioctl oficial por que si accidentalmente coges los ioct1s de alguien o alguien coge los tuyos sabr s que algo est mal Para m s informaci n consulta el rbol del c digo fuente del n cleo en Documentation ioctl number txt chardev c chardev c Crea un dispositivo de entrada salida de car cter Ten en cuenta que aqu los papeles de leer y escribir se han intercambiado otra vez por lo tanto en las lecturas ioct 1 se env a informaci n al n cleo y las escrituras reciben informaci n desde el n cleo 2Esto no es exacto No podr s pasarle una estructura por ejemplo a trav s de un ioctl pero podr s pasarle un puntero a la estructura 31 2 1 Ficheros fuente para varias versiones del n cleo 32 Ed Copyright C 1998 99 por Ori Pomerantz Los ficheros de cabeceras necesarios
88. mil sima de segundo el n cleo tiene una interrupci n de reloj e intenta llamar a la funci n que est en la lista de tareas Desgraciadamente la funci n ya no est all En la mayor a de los casos la p gina de memoria donde resid a est sin utilizar y obtienes un feo mensaje de error Pero si alg n otro c digo est ahora situado en la misma posici n de memoria las cosas podr an ponerse muy feas Desgraciadamente no tenemos una forma f cil de eliminar una tarea de una lista de tareas Como cleanup_module no puede retornar con un c digo de error es una funci n void la soluci n es no dejar que retorne En vez de ello llama a sleep_on o module sleep on para poner el proceso rmmod a dormir Antes de eso informa a la funci n llamada por la interrupci n del reloj para que pare de apuntarse estableciendo una variable global Entonces en la siguiente interrupci n del reloj el proceso rmmod ser despertado cuando nuestra funci n ya no est en la cola y es seguro quitar el m dulo sched c sched c planifica una funci n para ser llamada en cada interrupci n del reloj Copyright C 1998 por Ori Pomerantz 1 Ambas son realmente lo mismo 64 2 1 Ficheros fuente para varias versiones del n cleo 65 Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux
89. n cleo no deber a ser quitado MOD_INC_USE_COUNT Si el fichero ya est abierto espera hasta que no lo est while Already_Open if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 2 1 Ficheros fuente para varias versiones del nucleo 56 int i is_sig 0 endif Esta funci n pone el proceso actual incluyendo algunas llamada al sistema como nosotros a dormir La ejecuci n ser retomada correctamente despu s de la llamada a la funci n o porque alguien llam a wake_up amp WaitQ s lo module_close hac sto cuando el fichero se cierra o cuando una se al como Ctrl C es enviada al proceso module_interruptible_sleep_on amp WaitQ Si despertamos porque tenemos una se al no estamos bloqueando retornamos EINTR falla la llamada al sistema Esto permite a los procesos ser matados o parados Emmanuel Papirakis Esta es una peque a actualizaci n para trabajar con 2 2 Las se ales son ahora contenidas en dos palabras 64 bits y son almacenadas en una estructura que contiene un array de dos unsigned longs Ahora tenemos que realizar 2 chequeos en nuestro if Ori Pomerantz Nadie me prometi que no usar an nunca m s de 64 bits o que este libro no ser a usado para una versi n de Linux con un tama o de palabra de 16 bits En cualquier caso este c digo d
90. o si se quita A y despu s se quita B el sistema se caer El borrado de A restaurar la llamada original al sistema sys_open sacando a B fuera del bucle Entonces cuando B es borrado restaurar la llamada al sistema a la que l piensa que es la original A open que ya no est en memoria A primera vista parece que podr amos resolver este problema particular verificando si la llamada al sistema es igual a nuestra funci n open y si lo es no cambi ndola de forma que B no cambie la llamada al sistema cuando se borre lo que causar un problema peor a n Cuando se borra A a l le parece que la llamada al sistema fue cambiada a B_open y as que ya no apunta a A_open y por lo tanto no la restaurar a sys_open antes de ser borrado de memoria Desgraciadamente B_open a n intentar llamar a A_open que ya no est all por lo que incluso sin quitar B el sistema se caer Se me ocurren dos formas de prevenir este problema La primera es restaurar la llamada al valor orig inal sys_open Desgraciadamente sys_open no es parte de la tabla del sistema del n cleo que est en proc ksyms por tanto no podemos acceder a ella La otra soluci n es usar el contador de referencias para evitar que root pueda borrar el m dulo una vez cargado Esto es bueno para de m dulos de producci n pero malo para un ejemplo de aprendizaje que es por lo que no lo hice aqu syscall c syscall c Ejemplo de llamada al sistema robando
91. o del sistema operativo Y entonces se te permite hacer todo lo que quieras A la posici n en el n cleo a la que un proceso puede saltar se le llama system_ca11 El procedimiento en esa posici n verifica el n mero de la llamada al sistema que le dice al n cleo qu servicio ha pedido el pro ceso Despu s mira en la tabla de llamadas al sistema sys_ca11_table para ver la direcci n de la funci n del n cleo a llamar A continuaci n llama a la funci n y despu s de retornar hace unas pocas comproba ciones del sistema y luego regresa al proceso o a un proceso diferente si el tiempo del proceso ha finalizado Si quieres leer este c digo est en el fichero fuente arch lt architecture gt kernel entry S de spu s de la l nea ENTRY system_call Por lo tanto si queremos cambiar la forma en que funciona una cierta llamada al sistema lo que ten emos que hacer es escribir nuestra propia funci n para implementarla normalmente a adiendo un poco de nuestro c digo y despu s llamando a la funci n original y entonces cambiar el puntero que est en sys call table para que apunte a nuestra funci n Como es posible que seamos eliminados m s tarde y no queremos dejar el sistema en un estado inestable es importante que cleanup_module restaure la tabla a su estado original El presente c digo fuente es un ejemplo de m dulo del n cleo Queremos espiar a un cierto usuario 46 2 1 Ficheros fuente para varias versiones de
92. o que fue leyendo el c digo que lo utiliza Justamente mir para ver para qu usa el campo get_info de la struct proc_dir_entry Us una combinaci n de find y grep por si est s interesado y vi que se usa en lt directorio del c digo del n cleo gt fs proc array c Si algo no es conocido sobre el n cleo esta es la forma habitual de hacerlo En Linux tenemos la gran ventaja 2 1 Ficheros fuente para varias versiones del nucleo 20 de tener el c digo fuente del n cleo gratis usalo E int procfile_read char buffer char buffer_location off_t offset int buffer_length int zero int len El n mero de bytes usados realmente Esto es static por lo tanto permanecer en memoria cuando abandonemos esta funci n static char my_buffer 80 static int count 1 Damos toda nuestra informaci n de una vez por lo tanto si el usuario nos pregunta si tenemos m s informaci n la respuesta deber a de ser no Esto es importante porque la funci n est ndar de lectura de la librer a deber a continuar emitiendo la llamada al sistema read hasta que el n cleo responda que no hay m s informaci n o hasta que el buffer est lleno if offset gt 0 return 0 Rellenamos el buffer y cogemos su longitud len sprintf my_buffer Para la vez d s vete n count 100 gt 10 amp amp count 100 lt 14 th count
93. ola mundo hello cia dd ak Be els eee rd q Cease Rhy ae Reg he Ege he Bact al ae reel Mass Mate epee vet 1 1 Makefiles para los m dulos del n cleo ee ee Makefile 0000 shade a beg nhs Shae See Se ah eed ised ge eels aa Boe age oe Ele A aed 2 Ficheros de dispositivos de car cter Chardevics pi ee Sea aera A ee E A Eee BOR A ew ee 2 1 Ficheros fuente para varias versiones del nticleo 02 20 0002 ee ee 3 El sistema de ficheros proc PIOC S C ek a ar A id e A e dow Be 4 Usando proc para la entrada DIOCESE o Ae A E A A A Tee inde Ree Bat tarts 5 Hablando con los ficheros de dispositivo escrituras y IOCTLs a A icles Rae he Go Ee a Eee ean Bede BAIE a E nk OR ER D E Chardev Pi 40 0 ci A A amp Ga ark eb ak S abate aa a Wha et TOGO Mess ie Se OE Ape ee A hee bo de AA eek eh AA ee de hes 6 Par metros de inicio Patan Cre csc O A Pete O li wa eee ee ts Het vo 7 Llamadas al sistema SyYsCalli io a a Bak by esl te Rend he SL ei BP a he eB ered oem eg sea 8 Procesos bloqueantes Sleep Cre maua O E as ah ee de ea a eee ws Ta WWW UY YU NN DN NY Oo NADAMA RA 18 18 23 24 NDICE GENERAL 1 9 Reemplazando printk s 61 PEIMUK Cs a Searle ae A ee Be ee BE Te ee AOR Hag Oe E ae 61 10 Planificando tareas 64 A eee a asia co eet cee a ae Gay ets he ae atk dy ote pe ee Ge RENA 64 11 Manejadores de interrupciones 69 11 1 Teclados en la arquitectura Intel 2 2 2 0 2 0 2 0000000000 70
94. oner todos los detalles importantes en destacado 0 3 Cambios 3 0 3 Cambios 0 3 1 Nuevo en la version 1 0 1 1 Secci n de cambios 0 3 2 C mo encontrar el n mero menor del dispositivo 2 3 Arreglada la explicaci n de la diferencia entre caracteres y ficheros de dispositivo 2 4 Makefiles para los m dulos del n cleo 1 1 5 Multiproceso sim trico 12 6 Un Cap tulo de Malas Ideas 13 0 3 2 Nuevo en la versi n 1 1 0 1 Soporte para la versi n 2 2 del n cleo todo sobre el sitio 2 Ficheros fuente para varias versiones del n cleo 2 1 3 Cambios entre 2 0 y 2 2 A 4 M dulos del n cleo en varios ficheros fuente 1 2 5 Sugerencia de no dejar m dulos que implementan llamadas al sistema que pueden ser quitadas Ta 0 4 Agradecimientos Quisiera agradecer a Yoav Weiss por tantas discusiones e ideas tiles as como por encontrar fallos en este documento antes de su publicaci n Por supuesto cualquier error remanente es s lo culpa m a El esqueleto T X para este libro fue descaradamente robado de la gu a Linux Installation and Getting Started donde el trabajo de TX fue realizado por Matt Welsh Mi gratitud a Linus Torvalds Richard Stallman y al resto de las personas que me dieron la posibilidad de ejecutar un sistema operativo de calidad en mi ordenador y obtener el c digo fuente sin decirlo vale de acuerdo entonces por qu lo dije 0 4 1 Para la versi n 1 0 1 No he podido
95. os determinar el n mero de inodo usado para nuestro fichero por adelantado sino permitir al n cleo que lo determine para prevenir colisiones Los sistemas de ficheros normales est n localizados en un disco en vez de en memoria que es donde est proc y en ese caso el n mero de inodo es un puntero a una posici n de disco donde el nodo ndice del fichero abreviadamente inodo est localizado El inodo contiene informaci n sobre el fichero por ejemplo los permisos del fichero junto con un puntero a la posici n o posiciones del disco donde se pueden encontrar los datos del fichero Como a nosotros no se nos llama cuando el fichero se abre o se cierra no podemos poner MOD_INC_USE_COUNT y MOD_DEC_USE_COUNT en este m dulo ya que si el fichero es abierto y despu s el m dulo es borrado no hay forma de evitar las consecuencias En el siguiente cap tulo veremos una forma m s dif cil de implementar pero m s flexible de tratar con los ficheros proc que nos permitir protegernos tambi n de este problema procfs c procfs c crea un fichero en proc Copyright C 1998 1999 by Ori Pomerantz ey Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo T Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS
96. por una llamada al sistema tiene que esperar hasta que la primera CPU haya acabado Esto es lo que hace al SMP en Linux seguro pero terriblemente ineficiente En la versi n 2 2 x varias CPUs pueden estar dentro del n cleo al mismo tiempo Esto es algo que los escritores de m dulos tienen que tener en cuenta La excepci n son los procesos con hilos que pueden ejecutarse en varias CPUs a la vez 2Fn el sentido de que es seguro usarlo con SMP 74 Capitulo 13 Problemas comunes Antes de enviarte al mundo exterior y escribir m dulos del n cleo hay algunas cosas sobre las que te tengo que avisar Si me equivoco al avisarte y sucede algo malo por favor env ame el problema para que te devuelva ntegramente lo que me pagaron por tu copia del libro 1 Usar bibliotecas est ndar No puedes hacer esto En un m dulo del n cleo s lo puedes usar las funciones del n cleo que son las funciones que puedes ver en proc ksyms 2 Deshabilitar las interrupciones Podr as necesitar hacerlo por un momento y es correcto pero si no las habilitas posteriormente tu sistema se quedar muerto y tendr s que apagarlo 3 Meter tu cabeza dentro de la boca de un gran carn voro Es algo que probablemente no tendr a por qu advertirte pero pens que deb a hacerlo de todas formas por si acaso 75 Ap ndice A Cambios entre 2 0 y 2 2 No conozco todo el n cleo tan bien como para documentar todos los cambios En el transcurso de la
97. que nos llam get_user BTW es usado para lo contrario sprintf message Last input s Message for i 0 i lt len amp amp message i i put_user message i buf i Nota asumimos aqui que el tamafio del mensaje esta por debajo de la longitud o se recibir cortado En una situaci n de la vida real si el tama o del mensaj s menor que la longitud entonces retornamos la longitud y en la segunda llamada empezamos a rellenar el buffer con el byte longitud 1 del mensaje finished 1 return i Retornamos el n mero de bytes leidos Esta funci n recibe la entrada del usuario cuando el usuario escribe en el fichero proc 2 1 Ficheros fuente para varias versiones del nucleo 26 if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 static ssize_t module_input struct file file El mismo fichero const char buf El buffer con la entrada size_t length La longitud del buffer loff_t offset desplazamiento del fichero ign ralo else static int module_input struct inode inode El inodo del fichero struct file file El mismo fichero const char buf El buffer con la entrada int length La longitud del buffer endif TAE T Pone la entrada en Message donde module_output posteriormente ser capaz de usarlo for i 0 i1 lt MESSAGE_LE
98. r str struct tty_struct my_tty La tty para la tarea actual my tty Current tty Si my_tty es NULL significa que la actual tarea no tiene tty en la que puedas imprimir esto es posible por ej emplo si es un demonio En este caso no hay nada que se pueda hacer if my_tty NULL str strlen x my_tty gt driver es una estructura que mantiene las funciones de tty una de las cuales write es usada para escribir cadenas de caracteres a la tty Puede ser usada para coger una Cadena de caracteres del segmento de memoria del usuario o del segmento de memoria del n cleo El primer par metro de la funci n es la tty en la que hay que escribir porque la misma funci n puede ser normalmente usada para todas las ttys de un cierto tipo El segundo par metro controla cuando la funci n recibe una cadena de caracteres de la memoria del n cleo falsa 0 o desde la memoria del usuario verdad distinto de cero El tercer par metro es un puntero a la cadena de caracteres y el cuarto par metro es la longitud de la cadena de caracteres my_tty gt driver write my_tty La misma tty 0 No cogemos la cadena de caracteres de la memoria de usuario Cadena de caracteres str Longitud Las ttys fueron originalmente dispositivos hardware las cuales usualmente se adher
99. r ls 1 son s lo para referencia y pueden ser sobreescritos aqu E static int module _permission struct inode inode int op Permitimos a todo el mundo leer desde nuestro m dulo pero s lo root uid 0 puede escribir en el if op 4 op 2 amp amp current gt euid 0 return 0 Si es alg n otro el acceso es denegado return EACCES El fichero est abierto realmente no nos preocupamos de esto pero significa que necesitamos incrementar el contador de referencias del m dulo int module_open struct inode inode struct file file MOD_INC_USE_COUNT return 0 El fichero est cerrado otra vez interesante s lo por el contador de referencias i LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 int module _close struct inode inode struct file file else void module_close struct inode inode struct file file endif MOD_DEC_USE_COUNT i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 return 0 realizado con xito endif Gl Estructuras para registrar el fichero proc con punteros a todas las funciones relevantes x 2 1 Ficheros fuente para varias versiones del nucleo 28 Las operaciones del fichero para nuestro fichero proc Es aqui donde colocamos los punteros a todas las funciones llamadas
100. ram strl lt algo gt printk str2 lt algo gt n else printk Cadenas de caracteres s y s n stri str2 2 1 Ficheros fuente para varias versiones del nucleo 45 if LINUX_VERSION_CODE gt KERNEL_VERSION 2 2 0 printk Si intentas hacer insmod a este m dulo dos veces printk sin borrar antes rmmod n printk al primero quiz s obtengas el mensaje printk de error n printk el s mbolo para el par metro strl no ha sido encontrado In endif return 0 Limpieza void cleanup_module Capitulo 7 Llamadas al sistema Hasta ahora lo nico que hemos hecho ha sido usar mecanismos bien definidos del n cleo para registrar ficheros proc y manejadores de dispositivos Esto est muy bien si quieres hacer algo que los programadores del n cleo pensaron que querr as hacer como escribir un controlador de dispositivo Pero y si quieres escribir algo inusual cambiar el comportamiento del sistema de alguna forma Entonces te encuentras solo Aqu es d nde la programaci n del n cleo se vuelve peligrosa Al escribir el ejemplo siguiente elimin la llamada al sistema open Esto significa que no podr a abrir ning n fichero no podr a ejecutar ning n programa y no podr a apagar la computadora Tuve que pulsar el interruptor Afortunadamente no se muri ning n fichero Para asegurate de que t tampoco pierdas ning n fichero por favor
101. rectorio dev y la otra es usar el sistema de ficheros proc Ya que uno de los principales motivos para escribir algo en el n cleo es soportar alg n tipo de dispositivo de hardware empezaremos con los ficheros de dispositivos El prop sito original de los ficheros de dispositivo es permitir a los procesos comunicarse con los con troladores de dispositivos en el n cleo y a trav s de ellos con los dispositivos f sicos m dems terminales etc La forma en la que esto se implementa es la siguiente A cada controlador de dispositivo que es responsable de alg n tipo de hardware se le asigna su propio numero mayor La lista de los controladores y de sus n meros mayores est disponible en proc devices A cada dispositivo f sico administrado por un controlador de dispositivo se le asigna un n mero menor El directorio dev se supone que incluye un fichero especial llamado fichero de dispositivo para cada uno de estos dispositivos tanto si est realmente instalado en el sistema como si no Por ejemplo si haces 1s 1 dev hd ab ver s todas las particiones de discos duros IDE que posiblemente est n conectadas a una m quina Date cuenta de que todos ellos usan el mismo n mero mayor 3 pero el n mero menor cambia de uno a otro Nota Esto es as suponiendo que est s usando una arquitec tura PC No s nada sobre dispositivos en Linux ejecut ndose en otras arquitecturas Cuando el sistema se instal todos esos ficheros de dispositi
102. rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the software or if you modify it For example if you distribute copies of such a program whether gratis or for a fee you must give the recipients all the rights that you have You must make sure that they too receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two steps 1 copyright the software and 2 offer you this license which gives you legal permission to copy distribute and or modify the software Also for each author s protection and ours we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed on we want its recipients to know that what they have is not the original so that any problems introduced by others will not reflect on the original authors reputations Finally any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses in effect making the program proprietary To prevent this we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for copying distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CON
103. ro mayor del dispositivo No podemos dejar nada m s en el registro din mico porque ioctl necesita conocerlo define MAJOR_NUM 100 Establec 1 mensaje del controlador del dispositivo define IOCTL_SET_MSG _IOR MAJOR_NUM 0 char _TOR significa que estamos creando un n mero de comando ioctl para pasar informaci n desde un proceso de usuario al m dulo del n cleo 2 1 Ficheros fuente para varias versiones del n cleo El primer argumento MAJOR_NUM es el numero mayor de dispositivo que estamos usando El segundo argumento es el numero del comando puede haber varios con significado distintos El tercer argumento es el tipo que queremos coger desde el proceso al n cleo El JX SCOG l mensaje del controlador de dispositivo define IOCTL_GET_MSG _IOR MAJOR_NUM 1 char Este IOCTL es usado para salida para coger el mensaj del controlador de dispositivo De cualquier forma a n necesitamos el buffer para colocar el mensaj n la entrada tal como es asignado por el proceso E Cog l byte n esimo del mensaje define IOCTL_GET_NTH_BYTE _IOWR MAJOR_NUM 2 int El IOCTL es usado para entrada y salida Recibe T del usuario un n mero n y retorna Message n El nombre del fichero del dispositivo define DEVICE_FILE_NAME char_dev endif ioctl c ioctl c el
104. s que valoras en algo tu sistema de ficheros Este c digo se registra para la IRQ 1 que es la IRQ controlada por el teclado bajo las arquitecturas Intel Entonces cuando recibe una interrupci n de teclado lee el estado del teclado que es el prop sito de inb 0x64 y el c digo de barrido scan code que es el valor devuelto por el teclado Tan pronto como el n cleo cree que es factible ejecuta got_char que da el c digo de la tecla usada los siete primeros bits del c digo de barrido y si ha sido presionado si el octavo bit es cero o soltado si es uno intrpt c intrpt c Un manejador de interrupciones Copyright C 1998 por Ori Pomerantz Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif T include lt linux sched h gt include lt linux tqueue h gt Queremos una interrupci n include lt linux interrupt h gt include lt asm io h gt protegida por un bloqueo 11 1 Teclados en la arquitectura Intel 71 En 2 2 3 usr include linux macro para esto pero 2 0 3 lo a ado aqu si es necesar
105. scribiendo en l igual que se escribe en un fichero En el siguiente ejemplo esto se implementa mediante device_write Esto no es siempre suficiente Imag nate que tienes un puerto serie conectado a un m dem incluso si tienen un m dem interno todav a se implementa desde la perspectiva de la CPU como un puerto serie conectado a un m dem por lo tanto no tienes que hacer que tu imaginaci n trabaje mucho Lo natural ser a usar el fichero del dispositivo para escribir cosas al m dem tanto comandos del m dem como datos que se enviar n a trav s de la l nea telef nica y leer cosas desde el m dem respuestas a rdenes o datos recibidos a trav s de la l nea telef nica De todos modos esto deja abierta la pregunta de qu hacer cuando necesitas hablar con el puerto serie por ejemplo para enviarle la velocidad a la que los datos se env an y se reciben La respuesta en Unix es usar una funci n especial llamada oct 1 abreviatura de input output control Cada dispositivo tiene sus propias rdenes ioct 1 que pueden leer ioct 1 s para enviar informaci n desde un proceso al n cleo escribir i oct 1 s para devolver informaci n a un proceso ambas o ninguna La funci n se llama con tres par metros el descriptor del fichero del dispositivo apropiado el n mero de ioctl y un par metro que es de tipo long y al que le puedes hacer una conversi n cast para usarlo para pasar cualquier cosa El n mero ioctl codifica el n
106. ser m s probable que cojas los mensajes de depuraci n sin las X Fuera de X printk va directamente desde el n cleo a la consola En X en cambio los printks van a un proceso de modo usuario xterm C Cuando este proceso recibe tiempo de CPU se supone que lo env a al proceso servidor de X Entonces cuando el servidor X recibe la CPU se supone que lo muestra pero un n cleo inestable normalmente significa que el sistema se va a estrellar o a reiniciar por lo tanto no quieres que se retrasen los mensajes de error los que podr an explicarte qu es lo que fue mal durante mucho m s tiempo del que necesitas 1 2 M dulos del n cleo de varios ficheros A veces tiene sentido dividir el m dulo del n cleo en varios ficheros de c digo En este caso tienes que hacer lo siguiente 1 En todos lo ficheros fuente menos en uno a ade la l nea define _NO_VERSION_ Esto es im portante porque module h normalmente incluye la definici n de kernel_version una variable global con la versi n del n cleo para la que se compila el m dulo Si necesitas version h tienes que incluirla porque module h no lo har por ti con _NO_VERSION_ 2 Compila todos los ficheros fuente de la forma normal 3 Combina todos los ficheros objeto en uno solo Bajo x86 hazlo con 1d m elf_i386 r o lt nombre del m dulo gt o lt primer fichero fuente gt o lt segundo fichero fuente gt o He aqu un ejemplo de m dulo de este t
107. taba habilitado necesitas tenerlo definido cuando compiles el m dulo del n cleo e incluir usr include linux modversions h Esto tambi n puede ser realizado por el propio c digo Makefile Makefile para un m dulo b sico del n cleo CC gcc MODCFLAGS Wall DMODULE D__KERNEL__ DLINUX hello o hello c usr include linux version h CC MODCFLAGS c hello c 1 2 M dulos del n cleo de varios ficheros 6 echo insmod hello o para conectarlo echo rmmod hello para desconectarlo echo echo X y la programaci n del n cleo no se mezclan echo Haz insmod y rmmod desde fuera de X As que ahora s lo falta hacer su a root no compilaste como root a que no Viviendo en el limite y entonces haz insmod hello y rmmod hello para la satisfacci n de tu alma Mientras lo haces observa la presencia de tu nuevo m dulo del n cleo en proc modules Por cierto el motivo por el que Makefile recomienda no hacer insmod desde X es porque cuando el n cleo tiene que imprimir un mensaje con printk lo env a a la consola Cuando no utilizas X va al terminal virtual que est s usando el que escogiste con Alt F lt n gt y lo ves Si utilizas X en cambio hay dos posibilidades que tengas una consola abierta con xterm C en cuyo caso la salida ser enviada all o que no en cuyo caso la salida ir al terminal virtual 7 el que est cubierto por X Si tu n cleo se vuelve inestable
108. tales como abrir el fichero en este ejemplo El programa cat_noblock disponible en el directorio fuente de este cap tulo puede utilizarse para abrir el fichero con O_NONBLOCK La forma m s f cil de mantener un fichero abierto es con tail f 2Esto significa que el proceso a n est en modo n cleo en lo que concierne al proceso ste emiti la llamada al sistema open y la llamada al sistema no ha regresado todav a El proceso no conoce a nadie que usara la CPU durante la mayor a del tiempo entre el momento en el que hizo la llamada y el momento en el que regres 3Esto es porque nosotros usamos module_interruptible_sleep_on Pod amos haber usado module_sleep_on en vez de ella pero lo que conseguir amos ser an usuarios extremadamente enfadados cuyos Ctrl Cs ser an ignorados 52 2 1 Ficheros fuente para varias versiones del nucleo 53 sleep c sleep c crea un fichero proc y si varios procesos intentan abrirlo al mismo tiempo los pone a todos a dormir Copyright C 1998 99 por Ori Pomerantz Los ficheros de cabeceras necesarios Est ndar en los m dulos del n cleo include lt linux kernel h gt Estamos haciendo trabajo del n cleo include lt linux module h gt Espec ficamente un m dulo Distribuido con CONFIG_MODVERSIONS if CONFIG_MODVERSIONS define MODVERSIONS include lt linux modversions h gt endif T Neces
109. tar s lo a uno de ellos Entonces retorna y el proceso que acaba de cerrar el fichero puede continuar ejecut ndose A la vez el planificador decide que ese proceso ya tuvo suficiente tiempo y le da el control de la CPU a otro proceso Eventualmente a uno de los procesos que estaba en la cola le ser concecido el control de la CPU por parte del planificador ste empieza en el punto justo despu s de la llamada a module_interruptible_sleep_on Puede proceder a establecer un variable global para decirles a todos los dem s procesos que el fichero a n est abierto y seguir con su vida Cuando los otros procesos obtienen un poco de CPU ver n la variable global y volver n a dormirse Para hacer nuestra vida m s interesante module_close no tiene el monopolio de despertar a los proce sos que est n esperando a acceder al fichero Una se al tal como Ctrl C SIGINT tambi n puede despertar a un proceso En este caso queremos regresar inmediatamente con EINTR Esto es importante para que los usuarios puedan por ejemplo matar el proceso antes de que reciba el fichero Hay un punto m s que recordar Algunas veces los procesos no quieren dormir quieren o bien coger lo que quieren inmediatamente o bien que les digan que ello no es posible Tales procesos usan la bandera O_NONBLOCK cuando abren el fichero Se supone que el n cleo responde retornando con el c digo de error EAGAIN desde operaciones que en caso contrario se bloquearian
110. the Program does not specify a version number of this License you may choose any version ever published by the Free Software Foundation If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different write to the author to ask for permission For software which is copyrighted by the Free Software Foundation write to the Free Software Foundation we sometimes make exceptions for this Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally NO WARRANTY BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE THERE IS NO WARRANTY FOR THE PROGRAM TO THE EXTENT PERMITTED BY APPLICABLE LAW EXCEPT WHEN OTH ERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND OR OTHER PARTIES PRO VIDE THE PROGRAM AS IS WITHOUT WARRANTY OF ANY KIND EITHER EXPRESSED OR IMPLIED INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MER CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU SHOULD THE PRO GRAM PROVE DEFECTIVE YOU ASSUME THE COST OF ALL NECESSARY SERVICING REPAIR OR CORRECTION IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER OR ANY OTHER PARTY WHO MAY MODIFY AND OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE BE LIABLE TO YOU FOR DAM AGES INCLUDING ANY GENE
111. to Este documento es para personas que quieran escribir m dulos del n cleo Aunque tratar en varios sitios sobre c mo se hacen las cosas en el n cleo ste no es mi prop sito Hay fuentes bastante buenas que hacen un trabajo mejor que el que yo pudiera haber hecho Este documento tambi n es para personas que saben escribir m dulos del n cleo pero que no se han adaptado a la versi n 2 2 de ste Si eres una de estas personas te sugiero que mires en el ap ndice A todas las diferencias que he encontrado mientras actualizaba los ejemplos La lista est lejos de ser amplia pero creo que cubre la mayor a de las funcionalidades b sicas y te bastar para empezar El n cleo es un magn fico trabajo de programaci n y creo que todo programador deber a leer al menos algunos ficheros fuente del n cleo y entenderlos Dicho esto tambi n creo en el valor de jugar primero con el sistema y hacer las preguntas despu s Cuando aprendo un nuevo lenguaje de programaci n no empiezo leyendo el c digo de la biblioteca sino escribiendo un peque o programa hola mundo No veo por qu el jugar con el n cleo tendr a que ser diferente 0 2 Un apunte sobre el estilo Me gusta poner tantas bromas como sea posible en la documentaci n Estoy escribiendo esto porque me gusta y asumo que la mayor a de vosotros est is leyendo esto por el mismo motivo Si quieres saltarte este punto ignora todo el texto normal y lee el c digo fuente Prometo p
112. to requiere compilaci n condicional dependiendo de la versi n del n cleo La forma con la que hacemos esto es usando la macro LINUX _VERSION_COD E En la versi n a b c del n cleo el valor de esta macro deber a ser 216a 28b c Para obtener el valor espec fico de una versi n espec fica del n cleo podemos usar la macro KERNEL_VERSION Como no est definida en 2 0 35 la definiremos nosotros mismos si es necesario Capitulo 3 El sistema de ficheros proc En Linux hay un mecanismo adicional para que el n cleo y los m dulos del n cleo env en informaci n a los procesos el sistema de ficheros proc Originalmente dise ado para permitir un f cil acceso a la infor maci n sobre los procesos de aqu el nombre ahora lo utiliza cualquier elemento del n cleo que tiene algo interesante que informar como proc modules que tiene la lista de los m dulos y proc meminfo que tiene las estad sticas de uso de la memoria El m todo para usar el sistema de ficheros proc es muy similar al usado con los controladores de dis positivos creas una estructura con toda la informaci n que necesita el fichero proc incluyendo punteros a cualquier funci n manejadora en nuestro caso s lo hay una la que se llama cuando alguien intenta leer del fichero proc Entonces init_module registra la estructura con el n cleo y cleanup_module la libera El motivo por el que usamos proc_register_dynamic es porque no querem
113. tramos primero la funci n original es en fs open c En teor a esto significa que estamos enlazados a la versi n actual del n cleo En la pr ctica las llamadas al sistema nunca cambian se destruir an naufragando y requerir an que los programas fuesen recompilados ya que las llamadas al sistema son las interfaces entr 1 n cleo y los procesos asmlinkage int our_sys_open const char filename 4 int flags int mode int i 0 char ch Checkea si est s el usuario que estamos espiando if uid getuid_call getuid_call es la llamada al sistema getuid la cual nos da el uid del usuario que ejecut el proceso que llam a la llamada al sistema que tenemos Indica el fichero si es relevante printk Fichero abierto por d uid do if LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 get_user ch filename i else ch get_user filename i endif itt printk Sc ch while ch 0 printk WXn 2 1 Ficheros fuente para varias versiones del n cleo 50 Llamamos a la sys_open original en otro caso perdemos la habilidad para abrir ficheros return original_call filename flags mode Inicializa el m dulo reemplaza la llamada al sistema int init_module Peligro muy tarde para l ahora pero quiz s la pr xima vez
114. tware Foundation 80 General Public License 80 84 get_user 23 76 GNU General Public License 80 84 Licencia General Publica 80 hello c source file 4 hola mundo 4 IDE 9 discos duros 9 inb 70 inicio 43 par metros de 43 init module 4 10 prop sito general 10 inode 18 inode_operations structure 23 insmod 6 43 46 interrupci n 69 deshabilitando 75 manejador 69 interrupci n 0x80 46 interruptible_sleep_on 52 interrupts 76 intrpt c source file 70 ioctl 31 asignaci n oficial 31 definiendo 40 fichero de cabeceras para 40 us ndolo en un proceso 42 ioctl c source file 40 irgs 76 KERNEL_VERSION 17 kernel _version 6 ksyms 75 fichero proc 75 ld 6 lectura 23 en el n cleo 23 Licencia General P blica 80 LINUX 5 Linux copyright 84 LINUX_VERSION CODE 17 llamadas al sistema 46 m dem 31 MACRO_PARM 43 makefile 5 Makefile source file 5 8 manejadores de interrupciones 69 mark _bh 70 mayor 9 n mero 9 memoria 23 segmento 23 menor 9 n mero 9 mknod 9 MOD_DEC_USE_COUNT 10 MOD_INC_USE_COUNT 10 47 mod_use_count_ 10 modem 9 MODULE 5 module h 6 module_cleanup 64 MODULE_PARM 76 module _permissions 23 module_register_chrdev 9 module_sleep_on 52 64 module_wake_up 52 modversions h 5 multi tarea 52 multiproceso 74 Multiproceso sim trico 76 multiproceso sim trico 74 multitarea 52 n cleo 2 0 x 17 n cleo 2 2 x 17 n mero
115. uffer Retorna la longitud return len struct proc_dir_entry Our_Proc_File 0 N mero de inodo ign ralo ser rellenado por proc_register_dynamic 5 Longitud del nombre del fichero Sched El nombre del fichero S_IFREG S_IRUGO Modo del fichero este es un fichero normal que puede ser leido por su duefio su grupo y por todo el mundo 1 N mero d nlaces directorios donde el fichero es referenciado 0 0 El uid y gid para el fichero se lo damos a root 80 El tama o del fichero indicado por ls NULL funciones que pueden ser realizadas en el x inodo enlace borrado etc no soportamos ninguna procfile_read La funci n read para este fichero la funci n llamada cuando alguien intenta leer algo de l NULL Podemos tener aqu una funci n para rellenar el inodo del fichero para permitirnos jugar con los permisos due o etc y Inicializa el m dulo registra el fichero proc int init_module Pone la tarea en la cola de tareas tq_timer por lo tanto ser ejecutado en la siguiente interrupci n del reloj queue_task amp Task amp tq_timer Tiene xito si proc_register_dynamic tiene xito falla en otro caso i LINUX_VERSION_CODE gt KERNEL VERSION 2 2 0 return proc_register amp proc_root amp Our_Proc_File
116. vos se crearon mediante la orden mknod No existe un motivo t cnico por el que tienen que estar en el directorio dev es s lo una convenci n til Cuando creamos un fichero de dispositivo con el prop sito de prueba como aqu para un ejercicio probablemente tenga m s sentido colocarlo en el directorio en donde compilas el m dulo del n cleo Los dispositivos est n divididos en dos tipos los dispositivos de car cter y los dispositivos de bloque La diferencia es que los dispositivos de bloque tienen un b fer para las peticiones por lo tanto pueden escoger en qu orden las van a responder Esto es importante en el caso de los dispositivos de almacenamiento donde es m s r pido leer o escribir sectores que est n cerca entre s que aquellos que est n m s desperdigados Otra diferencia es que los dispositivos de bloque s lo pueden aceptar bloques de entrada y de salida cuyo tama o puede variar seg n el dispositivo en cambio los dispositivos de car cter pueden usar muchos o unos pocos bytes como ellos quieran La mayor a de los dispositivos del mundo son de car cter porque no necesitan este tipo de buffering y no operan con un tama o de bloque fijo Se puede saber cu ndo un fichero de dispositivo es para un dispositivo de car cter o de bloque mirando el primer car cter de la salida de 1s 1 Si es b entonces es un dispositivo de bloque y si es c es un dispositivo de car cter Este m dulo est dividido en dos part
117. y other recipients of the Program a copy of this License along with the Program You may charge a fee for the physical act of transferring a copy and you may at your option offer warranty protection in exchange for a fee 2 You may modify your copy or copies of the Program or any portion of it thus forming a work based on the Program and copy and distribute such modifications or work under the terms of Section 1 above provided that you also meet all of these conditions a You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change b You must cause any work that you distribute or publish that in whole or in part contains or is derived from the Program or any part thereof to be licensed as a whole at no charge to all third parties under the terms of this License c If the modified program normally reads commands interactively when run you must cause it when started running for such interactive use in the most ordinary way to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty or else saying that you provide a warranty and that users may redistribute the program under these conditions and telling the user how to view a copy of this License Exception if the Program itself is interactive but does not normally print such an announcement your work based on the Program is not required to print an announcement

Download Pdf Manuals

image

Related Search

Related Contents

  Russound MDK-C5 Manual  Shelf Manager ACB-V R1.0 24.09.08.book    Manual_de_Instalacao_ROAI.: Manual de instalação  MICRON  第62回大会についての注意事項    

Copyright © All rights reserved.
Failed to retrieve file