Tutorial del controlador de dispositivos de Linux para principiantes

Tutorial del controlador de dispositivos de Linux para principiantes
El sistema operativo Linux contiene 3 secciones principales: sistema de archivos raíz, kernel y gotador de arranque.

Sistema de archivos raíz:

Esta parte del sistema operativo contiene binarios de aplicación, bibliotecas, scripts, archivos de configuración y archivos de módulos cargables de kernel, etc

Núcleo:

Esta parte es el corazón del sistema operativo, el kernel es responsable de manejar todas las operaciones necesarias para ejecutar el sistema operativo, como la gestión de la memoria, la gestión de procesos y las operaciones de hardware de entrada/salida, etc

Bootloader:

Esta es la primera parte que se ejecuta por la CPU en el arranque. Bootloader contiene el código fuente para inicializar el sistema y comenzar a ejecutar el núcleo y contiene comandos para la depuración y modificación del entorno del núcleo, también contiene los comandos para descargar y actualizar las imágenes del núcleo y el sistema en la memoria flash.

Los controladores actúan como un puente entre el hardware y una aplicación de usuario, el núcleo proporciona un mecanismo llamado llamadas del sistema para hablar con el núcleo. En Linux, los controladores se pueden implementar de dos maneras, uno es los controladores se pueden compilar como parte del núcleo y otro es que los controladores se pueden compilar como módulos y cargar en tiempo de ejecución.

Comencemos con un simple módulo de kernel hello world. Aquí está el código fuente para un simple módulo de kernel hello world.

Hola.C

#Include // necesario para Module_init y Module_Exit
#include // necesario para kern_info
#Include // Necesario para las macros
int __init hw_init (void)
printk (kern_info "Hello World \ n");
regresar 0;

void __exit hw_exit (void)
printk (kern_info "Bye World \ n");

MODULE_LICENSE ("GPL");
módulo_init (hw_init);
MODULE_EXIT (HW_EXIT);

Makfile

obj-m: = hola.O
todo:
make -c/lib/modules/$ (shell uname -r)/construir m = $ (pwd) módulos
limpio:
hacer -c/lib/módulos/$ (shell uname -r)/construir m = $ (pwd) limpio

Crea una carpeta llamada Hola y luego colocar el Hola.C y Makfile dentro de eso. Abre el Terminal Aplicación y cambio de directorio a hola. Ahora ejecuta el comando hacer y si es exitoso, entonces debe generar un archivo de módulo de kernel cargado llamado Hola.KO.

Cuando ejecuta la marca si obtienes la salida hacer: nada que hacer para 'todos'. Entonces, asegúrese de que en la pestaña MakEfile haya ingresado (sin espacios) antes de make -c. Si Make es exitoso, debe obtener la salida como se muestra a continuación.

hacer [1]: ingresar directorio '/usr/src/linux-headers-3.13.0-128-Genérico '
CC [M]/Home/John/Desktop/Hello/Hello.O
Módulos de construcción, etapa 2.
Módulos modpost 1
CC/Home/John/Desktop/Hello/Hola.modificación.O
Ld [m]/home/John/Desktop/MVS/Pers/Kern/Hello/Hello.KO
hacer [1]: dejar el directorio '/usr/src/linux-headers-3.13.0-128-Genérico '

Ahora probemos el módulo cargándolo en el núcleo. Para cargar y descargar módulos de núcleo necesitamos tener permiso de Superuser. Use el siguiente comando para cargar el módulo del núcleo en el kernel.

sudo insmod hola.KO

Para ver el mensaje Printk, debe verificar el registro del núcleo, para verificar el registro del núcleo use el siguiente comando.

dmesg

Este comando emitirá los mensajes de registro del kernel, al final debe ver que nuestro mensaje Hola Mundo impreso.

Para descargar el módulo, use el siguiente comando.

sudo rmmod hola

Para ver el mensaje Printk, use el comando dmesg nuevamente y en el registro del núcleo puede ver nuestro mensaje Adiós mundo.

Ahora comprendamos el código fuente.

Hola.C

Para comenzar a escribir el controlador del núcleo, puede usar cualquier editor o ide de su elección, pero más comúnmente los desarrolladores del núcleo prefieren usar VI editor.

Cada módulo de kernel debe incluir el archivo de encabezado Linux/módulo.H Esto tiene las declaraciones y macros para las funciones del núcleo como módulo_init y módulo_exit etc. Las dos funciones más necesarias para un controlador de kernel son las funciones Module_init y Module_Exit. La función cuyo puntero se pasa a Module_init se ejecutará cuando cargamos el módulo en el núcleo, y la función cuyo puntero se pasa a módulo_exit se llamará cuando descargamos o eliminemos el módulo del kernel.

Dentro del núcleo para depurar e imprimir el registro, usamos imprimir función que es similar a la función printf que usamos en la aplicación. Puede usar las macros como kern_info, kern_err, etc. para especificar un nivel de registro.

Si estamos escribiendo un controlador para hablar con un hardware específico, entonces la función init debe tener el código para inicializar el hardware antes de comenzar a usarlo y la función de salida debe tener un código para limpiar los recursos (memoria dinámica, etc.) que utilizamos en el controlador Antes de salir del núcleo.

Aquí en este ejemplo, solo estamos imprimiendo mensajes de depuración en funciones de inicio y salida.

Makfile

Para construir el módulo del núcleo necesitamos escribir un archivo que guíe hacer utilidad cómo compilar el módulo. La sintaxis obj-M se usa para decirle al kernel makfile que el controlador debe compilarse como módulo utilizando el archivo de objeto especificado. Cuando solo ejecutas el comando hacer Entonces el control llega al todo: Sección del makfile y si se ejecuta el comando hacer limpia Entonces el control va al limpio: Sección de MakFile. A partir de este makfile, en realidad estamos ejecutando Make dentro del directorio de origen del núcleo utilizando la opción -C. Asegúrese de tener el directorio de origen del núcleo instalado en su sistema. Aquí en este ejemplo usamos el comando desanimado -r Para encontrar la versión actual del kernel Linux de su sistema.

Hemos utilizado la opción M = $ (PWD) para indicar en el kernel makfile que la fuente para el controlador está en el directorio de trabajo actual y estamos especificando la palabra módulos para decirle a Kernel Makefile que simplemente construya módulos y no construya el código fuente completo del núcleo. En limpio: Sección de Makefile Estamos diciendo que el kernel Makefile que limpie los archivos de objetos generados para construir este módulo.

Esto debería comenzar a compilar y ejecutar su primer módulo de núcleo.