Вы находитесь на странице: 1из 40

Kernel Hacking

Conociendo al Kernel Linux

QUE VAMOS A CONOCER? * Como compilar un Kernel Vanilla. * Como compilar un Kernel Vanilla. * Que son las syscalls y como utilizarlas. * Que son las syscalls y como utilizarlas. * Que son los modulos y cuales son los tipos * Que son los modulos y cuales son los tipos de modulos. de modulos. * Ejemplo basico de un modulo. * Ejemplo basico de un modulo. * Registro y operaciones de un modulo. * Registro y operaciones de un modulo. * Estructura del codigo fuente del kernel. * Estructura del codigo fuente del kernel.

Conocimientos previos
* Comandos basicos de Linux. * Comandos basicos de Linux. * Lenguaje C, assembler inline. * Lenguaje C, assembler inline. * * Arquitectura Arquitectura computador. computador. o o componentes componentes del del

CONCEPTOS BASICOS
Hacking Hacking Conocer el funcionamiento interno de un sistema, Conocer el funcionamiento interno de un sistema, en particular en particular de computadoras y redes de computadoras y redes informticas. informticas. Kernel o nucleo Kernel o nucleo El kernel de un sistema operativo, es un programa El kernel de un sistema operativo, es un programa encargado de administrar los recursos de un encargado de administrar los recursos de un sistema. Ejemplo: Administracin de la memoria, sistema. Ejemplo: Administracin de la memoria, administrador de discos, etc. administrador de discos, etc.

CONCEPTOS BASICOS
Modo usuario (user mode): En modo usuario se Modo usuario (user mode): En modo usuario se prohibe el uso de ciertas instrucciones consideradas prohibe el uso de ciertas instrucciones consideradas privilegiadas. Un proceso de usuario no puede acceder privilegiadas. Un proceso de usuario no puede acceder a los puertos de E/S ni capturar interrupciones. a los puertos de E/S ni capturar interrupciones. Modo kernel (kernel mode): En modo kernel el CPU Modo kernel (kernel mode): En modo kernel el CPU permite la ejecucin de todas las instrucciones permite la ejecucin de todas las instrucciones mquina, es posible acceder a todas las direcciones mquina, es posible acceder a todas las direcciones de memoria, programar los perifricos. de memoria, programar los perifricos.

CONCEPTOS BASICOS
ACCESO RESTRINGIDO

MODO USUARIO

MODO KERNEL

ACCESO TOTAL

HARDWARE

HERRAMIENTAS NECESARIAS
$ sudo apt-get install build-essential wget bzip2 $ sudo apt-get install build-essential wget bzip2 kernel-package libncurses-dev fakeroot kernel-package libncurses-dev fakeroot modulemoduleinit-tools init-tools
$ wget -C http://www.kernel.org/pub/linux/kernel/ $ wget -C http://www.kernel.org/pub/linux/kernel/ v2.6/linux-2.6.37.tar.bz2 v2.6/linux-2.6.37.tar.bz2

RECOPILANDO INFORMACION
** Manual de la tarjeta madre. Abrir el gabinete Manual de la tarjeta madre. Abrir el gabinete del PC y tomar nota de los componentes. del PC y tomar nota de los componentes.

$ lspci -v -t $ lspci -v -t $ lsusb $ lsusb $ lsmod $ lsmod $ cat /proc/cpuinfo $ cat /proc/cpuinfo $ cat /proc/meminfo $ cat /proc/meminfo $ cat /proc/partitions $ cat /proc/partitions

COMPILANDO EL KERNEL # cp linux-2.6.37.tar.bz2 /usr/src/ # cp linux-2.6.37.tar.bz2 /usr/src/ # tar -xjf linux-2.6.37.tar.bz2 # tar -xjf linux-2.6.37.tar.bz2 # cd /usr/src/linux-2.6.37 # cd /usr/src/linux-2.6.37 # cp /boot/config-$(uname -r) .config # cp /boot/config-$(uname -r) .config # make menuconfig # make menuconfig

COMPILANDO EL KERNEL

COMPILANDO EL KERNEL
Configurar el kernel para cargar y descargar Configurar el kernel para cargar y descargar modulos modulos

COMPILANDO EL KERNEL
Guardamos las modificaciones realizadas Guardamos las modificaciones realizadas

Podemos seleccionar el archivo de configuracion para la Podemos seleccionar el archivo de configuracion para la arquitectura x86 32 bits en arch/x86/configs/i386_defconfig arquitectura x86 32 bits en arch/x86/configs/i386_defconfig

COMPILANDO EL KERNEL

# make-kpkg clean # make-kpkg clean # fakeroot make-kpkg # fakeroot make-kpkg

-initrd -initrd

kernel_image kernel_image # dpkg -i linux-image-2.6.37_i386.deb # dpkg -i linux-image-2.6.37_i386.deb

Puedes compilar la documentacion del kernel en Puedes compilar la documentacion del kernel en varios formatos. Para mas informacion ejecuta el varios formatos. Para mas informacion ejecuta el comando make help. comando make help.

VERIFICANDO ERRORES $ dmesg || grep "Err" $ dmesg grep "Err" $ dmesg || grep "warning" $ dmesg grep "warning" $ dmesg || grep "fail" $ dmesg grep "fail"

SOLUCION A ERRORES COMUNES


* Error: The UTS Release version in include/linux/version.h does not match current version:
* Solucion: Agrega esta linea en include/linux/version.h #define UTS_RELEASE 2.6.37

Este error se debe a que el archivo utsrelease.h ha sido cambiado de lugar, ahora se encuentra en include/generated/utsrelease.h

SOLUCION A ERRORES COMUNES


* Error: Kernel Panic - not syncing: VFS: Unable to mount root on fs unknown-block(0,0)
* Solucion: Verificar que el sistema de archivos y el controlador del disco duro se encuentren integrados en el kernel y no esten compilados como modulos. Se debe integrar el sistema de archivos y el controlador del disco duro en el kernel (no como modulo), debido a que una de las primeras tareas que hace el kernel es montar el sistema de archivos root (que es /).

QUE SON LAS SYSCALLS?


**Es el metodo por el cual Es el metodo por el cual un proceso de usuario un proceso de usuario interactua con el kernel. interactua con el kernel. ** Las syscalls estan Las syscalls estan definidas en arch/x86/ definidas en arch/x86/ include/asm/unistd_32.h include/asm/unistd_32.h (x86 32 bits), en la (x86 32 bits), en la version 2.6.37 hay 341 version 2.6.37 hay 341 syscalls definidas. syscalls definidas.

El numero de syscalls definidas se encuentra en la El numero de syscalls definidas se encuentra en la constante NR_syscalls en el fichero unistd_32.h constante NR_syscalls en el fichero unistd_32.h

QUE SON LAS SYSCALLS?


**Un comando puede ejecutar cientos de syscalls. Un comando puede ejecutar cientos de syscalls.
$ echo Hola Mundo $ echo Hola Mundo $ strace echo Hola Mundo $ strace echo Hola Mundo execve("/bin/echo", ["echo", "Hola Mundo"], [/* 39 vars */]) = 0 execve("/bin/echo", ["echo", "Hola Mundo"], [/* 39 vars */]) = 0 . .. .. . write(1, "Hola Mundo\n"..., 11Hola Mundo) = 11 write(1, "Hola Mundo\n"..., 11Hola Mundo) = 11 close(1) =0 close(1) =0 munmap(0xb7556000, 4096) = 0 munmap(0xb7556000, 4096) = 0 close(2) =0 close(2) =0 exit_group(0) =? exit_group(0) =?

Para ver las syscalls que utiliza un proceso Para ver las syscalls que utiliza un proceso utiliza el comando strace. utiliza el comando strace.

COMO LAS UTILIZO?


**Codigo C: Codigo C:
#include <stdio.h> // libreria estandar #include <stdio.h> // libreria estandar #include <string.h> // funcion strlen() #include <string.h> // funcion strlen() #include <unistd.h> // syscalls #include <unistd.h> // syscalls #include <sys/syscall.h> // funcion syscall() #include <sys/syscall.h> // funcion syscall() int main() int main() {{ const char *msg = "Hola mundo desde una syscall\n"; const char *msg = "Hola mundo desde una syscall\n"; ssize_t caracteres; ssize_t caracteres; printf("ID del usuario: %ld\n",syscall(__NR_getuid)); printf("ID del usuario: %ld\n",syscall(__NR_getuid)); caracteres = write(1, msg, strlen(msg)); caracteres = write(1, msg, strlen(msg)); return 0; return 0; }} El kernel devuelve un valor negativo en la variable global errno El kernel devuelve un valor negativo en la variable global errno para indicar un error. Los tipos de errores se encuentran en para indicar un error. Los tipos de errores se encuentran en include/asm-generic/errno-base.h e include/asm-generic/errno.h include/asm-generic/errno-base.h e include/asm-generic/errno.h

COMO LAS UTILIZO?


**Se utiliza la funcion syscall(), tomando como argumento el Se utiliza la funcion syscall(), tomando como argumento el
nombre exacto definido en unistd_32.h: nombre exacto definido en unistd_32.h: printf("ID del usuario: %ld\n",syscall(__NR_getuid)); printf("ID del usuario: %ld\n",syscall(__NR_getuid));

**Tambien se puede escribir directamente el nombre de la syscall Tambien se puede escribir directamente el nombre de la syscall
(sin __NR_): (sin __NR_): caracteres = write(1, msg, strlen(msg)); caracteres = write(1, msg, strlen(msg));

Se puede utilizar la funcion perror() definida en stdio.h, para Se puede utilizar la funcion perror() definida en stdio.h, para obtener los mensajes de error. La variable global errno esta obtener los mensajes de error. La variable global errno esta definida en errno.h en la libreria estandar C. definida en errno.h en la libreria estandar C.

COMO LAS UTILIZO?


**Asembler inline: Asembler inline:
#include <stdio.h> #include <stdio.h> // libreria estandar // libreria estandar

int pid; int pid; int main() {{ int main() __asm__( __asm__( "movl $20, %eax \n" // numero de la syscall (20 getpid) "movl $20, %eax \n" // numero de la syscall (20 getpid) "int $0x80 \n" // interrupcion 0x80, llama a la syscall "int $0x80 \n" // interrupcion 0x80, llama a la syscall "movl %eax, pid \n" // en eax queda el valor devuelto "movl %eax, pid \n" // en eax queda el valor devuelto ); ); printf("El pid del proceso es: %d\n", pid); printf("El pid del proceso es: %d\n", pid); return 0; return 0; }}
En los procesadores actuales, esta habilitado la instruccion SYSENTER En los procesadores actuales, esta habilitado la instruccion SYSENTER para ejecutar una syscall. Si la syscall recibe parametros, estos se para ejecutar una syscall. Si la syscall recibe parametros, estos se deben colocar en los registros %ebx, %ecx, %edx, %esi yy%edi. deben colocar en los registros %ebx, %ecx, %edx, %esi %edi.

QUE SON LOS MODULOS?


** Son una via eficiente para agregar controladores, Son una via eficiente para agregar controladores, sistema de archivos y otros componentes sin tener que sistema de archivos y otros componentes sin tener que compilar el kernel o reiniciar la maquina. compilar el kernel o reiniciar la maquina.

KERNEL KERNEL

(Lista doblemente enlazada del kernel) (Lista doblemente enlazada del kernel) FUNCIONES EXPORTADAS FUNCIONES EXPORTADAS

FUNCIONES EXPORTADAS FUNCIONES EXPORTADAS

modulo

insmod insmod

modulo

rmmod rmmod

MANEJO DE MODULOS
# insmod mimodulo.ko // carga un modulo # insmod mimodulo.ko // carga un modulo # rmmod mimodulo.ko // descarga un modulo # rmmod mimodulo.ko // descarga un modulo

# modinfo mimodulo.ko // muestra informacion sobre un # modinfo mimodulo.ko // muestra informacion sobre un modulo modulo # modprobe # modprobe
dependencias dependencias

// carga y descarga modulos junto con sus // carga y descarga modulos junto con sus

# lsmod # lsmod

// lista todos los modulos cargados // lista todos los modulos cargados

Existe el comando depmod que se utiliza para definir un archivo Existe el comando depmod que se utiliza para definir un archivo de dependencia de modulos. de dependencia de modulos.

TIPOS DE MODULOS
Existen diferentes formas en los cuales el kernel Existen diferentes formas en los cuales el kernel intercambia informacion con el hardware, estas se pueden intercambia informacion con el hardware, estas se pueden clasificar en: clasificar en: **Character Device: Maneja los datos en flujos de Character Device: Maneja los datos en flujos de bytes. bytes.
1110010101011010100110100

KERNEL
1110010101011010100110100

HARDWARE

Los dispositivos de caracter se denotan con la palabra c, Los dispositivos de caracter se denotan con la palabra c, en /dev. en /dev.

TIPOS DE MODULOS
**Block Device: Maneja los datos en bloques de bytes. Block Device: Maneja los datos en bloques de bytes.
01010 10101 10110 01010 10101 10110 01010 10101 10110

KERNEL
01010 10101 10110 01010 10101 10110 01010 10101 10110

HARDWARE

Los dispositivos de bloque se denotan con la palabra b, Los dispositivos de bloque se denotan con la palabra b, en /dev. en /dev.

TIPOS DE MODULOS
# ls -l /dev # ls -l /dev crw------- 1 root crw------- 1 root video video agpgart agpgart crw-rw---- 1 root audio 14, crw-rw---- 1 root audio 14, 10, 175 2011-03-24 10:30 10, 175 2011-03-24 10:30 4 2011-03-24 10:30 audio 4 2011-03-24 10:30 audio

.. .. .. ..

brw-rw---- 1 root disk brw-rw---- 1 root disk brw-rw---- 1 root disk brw-rw---- 1 root disk brw-rw---- 1 root disk brw-rw---- 1 root disk

8, 0 2011-03-24 06:00 sda 8, 0 2011-03-24 06:00 sda 8, 1 2011-03-24 06:00 sda1 8, 1 2011-03-24 06:00 sda1 8, 2 2011-03-24 06:00 sda2 8, 2 2011-03-24 06:00 sda2

Los dispositivos de caracter yybloque no son las unicas categorias Los dispositivos de caracter bloque no son las unicas categorias que administra el kernel. Las tarjetas de red ocupan una posicion que administra el kernel. Las tarjetas de red ocupan una posicion especial en el kernel. especial en el kernel.

IDENTIFICANDO LOS DISPOSITIVOS


MAJOR NUMBER: dispositivo en general.
sda

Se

utiliza

para

identificar

un

Major Major Number Number

tty0

Major Major Number Number

brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root crw--w---- 1 root crw--w---- 1 root crw------- 1 root crw------- 1 root

disk disk disk disk disk disk root root root root

8, 8, 8, 8, 8, 8, 4, 4, 4, 4,

0 2011-03-24 17:11 sda 0 2011-03-24 17:11 sda 1 2011-03-24 17:11 sda1 1 2011-03-24 17:11 sda1 2 2011-03-24 17:11 sda2 2 2011-03-24 17:11 sda2 0 2011-03-24 17:11 tty0 0 2011-03-24 17:11 tty0 1 2011-03-24 21:41 tty1 1 2011-03-24 21:41 tty1

En Documentation/devices.txt puedes ver los nombres de los En Documentation/devices.txt puedes ver los nombres de los dispositivos, sda se refiere a un dispositivo SCSI. dispositivos, sda se refiere a un dispositivo SCSI.

IDENTIFICANDO LOS DISPOSITIVOS


MINOR NUMBER: Se utiliza subsistemas de un dispositivo.
Minor Minor Number Number

para

identificar
Minor Minor Number Number

los

sda 0 1 sda1 sda2

0 1 2

tty0 tty1

brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root brw-rw---- 1 root crw--w---- 11root crw--w---- root crw------- 1 root crw------- 1 root

disk disk disk disk disk disk root root root root

8, 8, 8, 8, 8, 8, 4, 4, 4, 4,

0 2011-03-24 17:11 sda 0 2011-03-24 17:11 sda 1 2011-03-24 17:11 sda1 1 2011-03-24 17:11 sda1 2 2011-03-24 17:11 sda2 2 2011-03-24 17:11 sda2 0 2011-03-24 17:11 tty0 0 2011-03-24 17:11 tty0 1 2011-03-24 21:41 tty1 1 2011-03-24 21:41 tty1

Para obtener el Major yy Minor number se utilizan las macros Para obtener el Major Minor number se utilizan las macros MAJOR(dev_t dev) yy MINOR(dev_t dev), definidas en MAJOR(dev_t dev) MINOR(dev_t dev), definidas en include/linux/kdev_t.h. include/linux/kdev_t.h.

ESTRUCTURA DE UN MODULO
#include <linux/init.h> #include <linux/init.h> #include <linux/module.h> #include <linux/module.h> ////macros para el inicio yysalida de modulos macros para el inicio salida de modulos ////necesario para modulos necesario para modulos

MODULE_LICENSE("Dual BSD/GPL"); ////tipo de licencia MODULE_LICENSE("Dual BSD/GPL"); tipo de licencia MODULE_AUTHOR("z3r0d4y"); ////author del modulo MODULE_AUTHOR("z3r0d4y"); author del modulo MODULE_DESCRIPTION("Modulo de prueba"); ////descripcion MODULE_DESCRIPTION("Modulo de prueba"); descripcion MODULE_VERSION("Version 1.0"); ////version del modulo MODULE_VERSION("Version 1.0"); version del modulo ////funcion de entrada funcion de entrada int hola_mundo() { { int hola_mundo() printk(KERN_INFO "Hola Mundo desde un Modulo Linux\n"); printk(KERN_INFO "Hola Mundo desde un Modulo Linux\n"); return 0; return 0; }} ////funcion de salida funcion de salida void adios_mundo() { { void adios_mundo() printk(KERN_INFO "Adios Mundo desde un modulo Linux\n"); printk(KERN_INFO "Adios Mundo desde un modulo Linux\n"); }} module_init(hola_mundo); module_init(hola_mundo); module_exit(adios_mundo); module_exit(adios_mundo); ////definimos cual es la funcion de entrada definimos cual es la funcion de entrada ////definimos cual es la funcion de salida definimos cual es la funcion de salida

ESTRUCTURA DE UN MODULO
**Debido a que el kernel se ejecuta sobre si mismo debe definir sus Debido a que el kernel se ejecuta sobre si mismo debe definir sus propias funciones: propias funciones:
printk(KERN_INFO "Hola Mundo desde un Modulo Linux\n"); printk(KERN_INFO "Hola Mundo desde un Modulo Linux\n");

**Para pasarle un valor a un modulo se debe definir la variable Para pasarle un valor a un modulo se debe definir la variable como static: como static:
#include <linux/moduleparam.h> #include <linux/moduleparam.h> #include <linux/stat.h> #include <linux/stat.h> . .. .. . static int parametro_modulo ==1; static int parametro_modulo 1; module_param(parametro_modulo, int, S_IRUGO); module_param(parametro_modulo, int, S_IRUGO); . .. .. . printk(KERN_INFO El valor pasado es: %d,parametro_modulo); printk(KERN_INFO El valor pasado es: %d,parametro_modulo); ##insmod mimodulo.ko parametro_modulo=20 insmod mimodulo.ko parametro_modulo=20

Los loglevels del kernel estan definidos en linux/printk.h. Las Los loglevels del kernel estan definidos en linux/printk.h. Las constantes de permiso de un archivo estan definidas en linux/stat.h constantes de permiso de un archivo estan definidas en linux/stat.h

ESTRUCTURA DE UN MODULO
**Exportar simbolos de un modulo: Exportar simbolos de un modulo:
#include mimodulo.h #include mimodulo.h . .. .. .. . void Compartir(void) void Compartir(void) {{ printk(KERN_INFO Esta funcion va aaser compartida con el Kernel); printk(KERN_INFO Esta funcion va ser compartida con el Kernel); }} EXPORT_SYMBOL(Compartir); EXPORT_SYMBOL(Compartir); #include mimodulo.h #include mimodulo.h . .. .. .. . void Compartir(); void Compartir();

**Incluir un simbolo exportado: Incluir un simbolo exportado:

** Al compilar un modulo se generara un archivo llamado Al compilar un modulo se generara un archivo llamado Module.symvers, este archivo almacena las direcciones yyruta de los Module.symvers, este archivo almacena las direcciones ruta de los simbolos exportados. simbolos exportados. Las funciones exportadas se pueden ver en /proc/kallsysms. Las funciones exportadas se pueden ver en /proc/kallsysms.

REGISTRAR Y LIBERAR UN MODULO


**Al registrar un modulo, se le indica al kernel que reserve el Al registrar un modulo, se le indica al kernel que reserve el nmero del dispositivo para poder acceder al controlador. nmero del dispositivo para poder acceder al controlador. **El acceso a los dispositivos es a traves de archivos especiales en El acceso a los dispositivos es a traves de archivos especiales en la carpeta /dev. la carpeta /dev.

**Luego de reservar el numero del dispositivo, se debe eliminar Luego de reservar el numero del dispositivo, se debe eliminar este registro para que otro controlador pueda utilizarlo. este registro para que otro controlador pueda utilizarlo.

El comando mknod crea un fichero especial de un modulo. El comando mknod crea un fichero especial de un modulo.

REGISTRAR Y LIBERAR UN MODULO


#include <linux/init.h> #include <linux/init.h> #include <linux/module.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/fs.h> #define MAJOR_DRIVER 260 #define MAJOR_DRIVER 260 #define MINOR_DRIVER 00 #define MINOR_DRIVER ////macros para el inicio yysalida de modulos macros para el inicio salida de modulos ////necesario para modulos necesario para modulos ////para registrar yyliberar el modulo para registrar liberar el modulo ////major number libre para el modulo major number libre para el modulo ////minor number del dispositivo minor number del dispositivo

dev_t Driver; ////almacena el Major yyMinor number del dispositivo dev_t Driver; almacena el Major Minor number del dispositivo ////registramos el major number del modulo en /proc/devices registramos el major number del modulo en /proc/devices int iniciar_modulo() { { int iniciar_modulo() Driver ==MKDEV(MAJOR_DRIVER, MINOR_DRIVER); ////Inicia dev_t Driver MKDEV(MAJOR_DRIVER, MINOR_DRIVER); Inicia dev_t return register_chrdev_region(Driver, 1, Mi_Driver); return register_chrdev_region(Driver, 1, Mi_Driver); }} ////liberamos el modulo registrado liberamos el modulo registrado void finalizar_modulo() { { void finalizar_modulo() unregister_chrdev_region(Driver, 1); unregister_chrdev_region(Driver, 1); }} module_init(iniciar_modulo); module_init(iniciar_modulo); module_exit(finalizar_modulo); module_exit(finalizar_modulo); ////funcion de entrada funcion de entrada ////funcion de salida funcion de salida

**Se debe indicar al kernel las operaciones que puede realizar Se debe indicar al kernel las operaciones que puede realizar el modulo a traves de la estructura file_operations definida en el modulo a traves de la estructura file_operations definida en linux/fs.h. linux/fs.h.
ssize_t MiDriver_read(struct file *fOps, char __user *buff, size_t count, loff_t *pOff) ssize_t MiDriver_read(struct file *fOps, char __user *buff, size_t count, loff_t *pOff) {{ ////Realizar Operaciones de lectura Realizar Operaciones de lectura return 0; return 0; }} struct file_operations OperacionesDriver =={ { struct file_operations OperacionesDriver .owner ==THIS_MODULE, ////Puntero hacia la estructura del modulo .owner THIS_MODULE, Puntero hacia la estructura del modulo .read ==MiDriver_read, ////Lee datos del dispositivo .read MiDriver_read, Lee datos del dispositivo .write ==MiDriver_write, ////Escribe datos al dispositivo .write MiDriver_write, Escribe datos al dispositivo

OPERACIONES DE UN MODULO DE CARACTER

. .. .. .

.open ==NULL, .open NULL, .release ==NULL, .release NULL, };};

. .. .. .

////Primera operacion del dispositivo Primera operacion del dispositivo ////Libera al dispositivo Libera al dispositivo

OPERACIONES DE UN MODULO DE CARACTER


**Luego de crear las operaciones del modulo se debe registrar el Luego de crear las operaciones del modulo se debe registrar el dispositivo. dispositivo.
////registramos el major number del modulo en /proc/devices registramos el major number del modulo en /proc/devices int iniciar_modulo() { { int iniciar_modulo() return register_chrdev(MIDRIVER_MAJOR, DriverName, &OperacionesDriver); return register_chrdev(MIDRIVER_MAJOR, DriverName, &OperacionesDriver); }} ////liberamos el modulo registrado liberamos el modulo registrado void finalizar_modulo() { { void finalizar_modulo() unregister_chrdev(MIDRIVER_MAJOR, DriverName); unregister_chrdev(MIDRIVER_MAJOR, DriverName); }} module_init(iniciar_modulo); module_init(iniciar_modulo); module_exit(finalizar_modulo); module_exit(finalizar_modulo); ////funcion de entrada funcion de entrada ////funcion de salida funcion de salida

Existen diferentes formas de registrar un modulo yy depende del Existen diferentes formas de registrar un modulo depende del tipo de modulo a crear. tipo de modulo a crear.

COMPILACION DE UN MODULO
**Un modulo se puede compilar con el siguiente Makefile generico: Un modulo se puede compilar con el siguiente Makefile generico:
obj +:= modulo1.o, modulo2.o ////aqui podemos agregar los archivos obj necesarios obj +:= modulo1.o, modulo2.o aqui podemos agregar los archivos obj necesarios all: all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

##make make **Cargamos el modulo: Cargamos el modulo:


##insmod mimodulo.ko insmod mimodulo.ko

**Descargamos el modulo: Descargamos el modulo:


##rmmod mimodulo.ko rmmod mimodulo.ko

Se puede ver los mensajes de la funcion printk, utilizando el Se puede ver los mensajes de la funcion printk, utilizando el comando dmesg o en la ruta /var/log/syslog comando dmesg o en la ruta /var/log/syslog

ESTRUCTURA DEL KERNEL


ARCH DRIVERS FS INCLUDE SOURCE INIT KERNEL MM NET (CODIGO DEPENDIENTE DE LA ARQUITECTURA) (CODIGO DEPENDIENTE DE LA ARQUITECTURA) (CONTROLADORES DE DISPOSITIVOS) (CONTROLADORES DE DISPOSITIVOS) (SISTEMA DE ARCHIVOS) (SISTEMA DE ARCHIVOS) (ARCHIVOS DE DEFINICION *.H) (ARCHIVOS DE DEFINICION *.H) MAIN.C (ARCHIVO PRINCIPAL DEL KERNEL) (ARCHIVO PRINCIPAL DEL KERNEL)

(CODIGO DEL KERNEL, SCHEDULER, CPU, ETC) (CODIGO DEL KERNEL, SCHEDULER, CPU, ETC) (ADMINISTRACION DE LA MEMORIA) (ADMINISTRACION DE LA MEMORIA) (PROTOCOLOS DE RED, BLUETOOTH, ETC) (PROTOCOLOS DE RED, BLUETOOTH, ETC)

CONCLUSIONES
** Entender el funcionamiento interno del kernel no es una tarea Entender el funcionamiento interno del kernel no es una tarea facil ya que se requiere de un cierto conocimiento de sistemas facil ya que se requiere de un cierto conocimiento de sistemas operativos y de la comunicacion de este con el hardware. operativos y de la comunicacion de este con el hardware. **Puedes empezar entendiendo yydesarrollando modulos o realizar Puedes empezar entendiendo desarrollando modulos o realizar pequeas modificaciones al kernel. Por ejemplo: definir una nueva pequeas modificaciones al kernel. Por ejemplo: definir una nueva syscall, modificar el banner del kernel, etc. syscall, modificar el banner del kernel, etc. ** Si quieres ser un desarrollador del kernel linux o quieres Si quieres ser un desarrollador del kernel linux o quieres colaborar debes comenzar tu lectura en Documentation/HOWTO. colaborar debes comenzar tu lectura en Documentation/HOWTO. ** El kernel linux es portable vamos a mantenerlo asi. Utiliza los El kernel linux es portable vamos a mantenerlo asi. Utiliza los tipos de datos definidos por el kernel. tipos de datos definidos por el kernel.

Linus Tolvards: "La mejor forma de aprender el nucleo es leer tu Linus Tolvards: "La mejor forma de aprender el nucleo es leer tu mismo el codigo fuente." mismo el codigo fuente."

REFERENCIAS
**Linux Device Driver Third Edition. Linux Device Driver Third Edition. **http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/es/ http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/es/
**http://es.tldp.org http://es.tldp.org **http://www.kernel-labs.org http://www.kernel-labs.org **http://kernelnewbies.org http://kernelnewbies.org **http://www.kernel.org http://www.kernel.org **http://www.linuxquestions.org http://www.linuxquestions.org

Contacto: z3r0d4y.BoF@gmail.com Contacto: z3r0d4y.BoF@gmail.com

HAPPY HACKING!! HAPPY HACKING!!

Вам также может понравиться