Modulos Kernel

Si has detenido en los Foros de Hardkernel el tiempo suficiente, la expresión "módulo kernel" debería serte bastante familiar. Sin embargo, si eres nuevo en el mundo de Linux, los detalles sobre qué son exactamente los módulos de kernel podrías no tenerlos muy claros. El objetivo de este artículo no es solo que sepas que es exactamente un Módulo Kernel, sino también conocer cómo interactuar y compilar el tuyo propio.

¿Qué es un módulo kernel?

El kernel de Linux es monolítico o poco flexible, lo que significa que todo lo que necesita el sistema operativo forma parte del espacio del kernel. Esto tiene la ventaja de ser más rápido que otros diseños de kernel como un micro-kernel, pero se paga el precio de carecer de modulación y flexibilidad. Los módulos kernel están diseñados para ayudar a solucionar este problema de modulación. Para añadir funcionalidades al kernel, como un nuevo controlador o formato de sistema de archivos, el código con esa nueva funcionalidad en particular se compila en un módulo kernel y luego se carga en el kernel de Linux.

Ejemplo Hello World

Para el código de ejemplo y el resto del artículo, usare el nombre de archivo "examplemod.c"

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>

MODULE_DESCRIPTION("Example kernel module");
MODULE_AUTHOR("ODROID");

static int example_init(void)
{
      printk(KERN_ALERT "Hello World!\n");
      return 0;
}

static void example_exit(void)
{
      printk(KERN_ALERT "Goodbye World\n");
}

module_init(example_init);
module_exit(example_exit);
El código incluye un simple "hello world", ya que el objetivo de este artículo está centrado con la definición y la funcionalidad de los módulos kernel. Este ejemplo utiliza las funciones de registro del kernel para mostrar un simple saludo después de la inicialización y un adiós cuando es retirado el kernel. El código tiene dos partes que destacan y a las que hago referencia a continuación.
MODULE_DESCRIPTION("Example kernel module");
MODULE_AUTHOR("ODROID");
Estas macros ayudan a completar la información sobre el módulo, existen tipos de campos adicionales que se pueden usar como "MODULE_VERSION", "MODULE_LICENSE", etc. Más adelante veremos comandos sobre cómo ver esta información para cualquier módulo dado.
module_init(simple_init);
module_exit(simple_cleanup);
Las funciones module_init y module_exit registran las funciones simple_init y simple_cleanup que se han definido anteriormente. Estas llamadas registran qué funciones creadas por el usuario serán llamadas en la inicialización y en la salida del código. printk (), aunque a primera vista puede parecer similar o intercambiable con printf (), debemos pensar en ella de manera diferente. Como hemos mencionado anteriormente, printk es un mecanismo para el registro de mensajes del kernel y no para interactuar directamente o mostrar información al usuario. El nivel de registro, que varía de 0 a 7 (7 menos importante) se coloca antes de la cadena sin un comando, ya que forman un único parámetro que pasa a printk ().

Compilando

Después de escribir el módulo, hay un par de notas a tener en cuenta antes de simplemente llamar "gcc". Los módulos kernel son bastante delicados a la hora de compilarse, se deben cumplir las siguientes reglas:

  • No se pueden incluir cabeceras que no sean del kernel
  • El módulo no debe estar vinculado a ninguna librería
  • Los flags del compilador utilizados para el módulo deben coincidir con los utilizados para el kernel.

Para simplificar las cosas, podemos usar el siguiente archivo MAKE:

obj-m += examplemod.o

all:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
El archivo MAKE es bastante sencillo, la parte más importante es la siguiente línea:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
La ruta apunta a una ubicación donde están ubicados los Makefiles y las cabeceras del kernel. El Makefile simplemente llama al que se encuentra en esta ubicación para proporcionar la funcionalidad de cara a la compilación y también a la limpieza. Después de ejecutar el Makefile, deberíamos quedarnos con un archivo llamado examplemod.ko, este es nuestro módulo kernel compilado.

Comandos

Ahora que hemos creado nuestro Módulo Kernel, es hora de cargarlo en el kernel Linux. El siguiente comando es el que se usa para cargar un archivo * .ko. Cuando se carga el módulo, se llamará a la función fijada por module_init.

$ sudo insmod ./examplemod.ko
Si eliminamos un Módulo Kernel que ha sido cargado, llamará a la función fijada por module_exit. Para eliminar nuestro Módulo Kernel o cualquier Módulo que haya sido cargado, podemos usar el siguiente comando.
$ sudo rmmod examplemod
Aunque no es un comando específico del Módulo Kernel, el siguiente comando nos permite ver lo que ha sido registrado por el kernel. Si hemos ejecutado los dos comandos anteriores, deberíamos ver las dos declaraciones printk () cerca de la parte inferior (más reciente) del registro log.
$ dmesg
O para ver solo las últimas 2 líneas que se imprimieron..
$ dmesg | tail -2
Figura 1: Cargando y eliminando el módulo kernel, luego imprimiendo el registro del kernel

Esto mostrará todos los módulos kernel cargados actualmente. Sin embargo, esta información es bastante limitada. Si queremos profundizar podemos usar el nombre de un módulo de la lista con el siguiente comando.

$ lsmod
Figura 2: Impresión de lsmod que muestra el ejemplomod cargado

Esto mostrará una vista más detallada del módulo. Si miramos la información del módulo de ejemplo que hemos creado, veremos la información que fijamos al comienzo del código de nuestro módulo.

$ modinfo examplemod
Figura 3: Impresión modinfo de la información para nuestro módulo kernel

Conclusión

Estos son solo los conceptos básicos para comprender qué es un Módulo Kernel y cómo crearlos e interactuar con ellos. En futuros artículos analizaremos los usos y aplicaciones más complejos de los Módulos de Kernel y cómo llegar a cierto nivel de interacción con ellos para que proporcionen una funcionalidad significativa.

Be the first to comment

Leave a Reply