Los módulos del kernel son piezas de código, normalmente drivers o soporte para sistemas de archivos y protocolos de red, que se cargan y descargan en el kernel en marcha sin reiniciar. En este tutorial aprenderás a consultar los módulos cargados, a cargarlos y descargarlos con modprobe, a fijar sus parámetros, a cargarlos en el arranque, a bloquear los que no quieres y a compilar un módulo externo con DKMS para que se reconstruya solo con cada kernel nuevo, todo en Ubuntu 24.04.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Los comandos
lsmod,modinfoymodprobeson iguales en Debian 12 y Rocky Linux 9; cambian los paquetes de DKMS y el comando para regenerar el initramfs (dracut -fen Rocky). - Un usuario no root con privilegios
sudo. - Acceso a la consola del servidor (la consola VNC del panel en un VPS) por si un cambio en los módulos de red o de disco impide acceder por SSH.
Paso 1: Consultar los módulos cargados
lsmod lista los módulos cargados en este momento:
lsmod | head -5
Module Size Used by
tls 155648 0
xt_conntrack 12288 2
nf_conntrack 196608 1 xt_conntrack
ip6t_REJECT 12288 1
La columna Used by indica cuántas referencias tiene el módulo y qué otros módulos dependen de él. No podrás descargar un módulo mientras ese contador sea mayor que 0.
Para ver la información de un módulo concreto, su archivo, licencia, dependencias y parámetros, usa modinfo:
modinfo dummy
filename: /lib/modules/6.8.0-45-generic/kernel/drivers/net/dummy.ko.zst
alias: rtnl-link-dummy
description: Dummy netdevice driver which discards all packets sent to it
license: GPL
depends:
intree: Y
name: dummy
parm: numdummies:Number of dummy pseudo devices (int)
Los módulos de Ubuntu 24.04 están comprimidos (.ko.zst) en /lib/modules/$(uname -r)/. Algunas funciones no son módulos sino que están compiladas dentro del kernel; modinfo también las encuentra, y la lista completa está en modules.builtin:
grep -c . /lib/modules/$(uname -r)/modules.builtin
Un módulo integrado no aparece en lsmod y no se puede descargar.
Paso 2: Cargar y descargar módulos con modprobe
Usa siempre modprobe en lugar de insmod y rmmod: resuelve dependencias automáticamente y aplica la configuración de /etc/modprobe.d/.
Como ejemplo usarás dummy, un driver de interfaces de red virtuales que no afecta a nada. Cárgalo:
sudo modprobe dummy
Comprueba que está cargado y que ha creado una interfaz:
lsmod | grep dummy
ip link show type dummy
dummy 12288 0
5: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 3e:91:7c:08:5a:d2 brd ff:ff:ff:ff:ff:ff
Para ver qué haría modprobe sin ejecutarlo, incluidas las dependencias que cargaría, usa --show-depends:
modprobe --show-depends nf_nat
Descarga el módulo:
sudo modprobe -r dummy
Si el módulo está en uso, modprobe -r falla con Module ... is in use. Detén primero el servicio o elimina el dispositivo que lo utiliza.
Paso 3: Pasar parámetros a un módulo
Muchos módulos aceptan parámetros. modinfo -p los lista:
modinfo -p dummy
numdummies:Number of dummy pseudo devices (int)
Parámetros al cargar
Puedes pasarlos directamente a modprobe:
sudo modprobe dummy numdummies=3
ip -br link show type dummy
dummy0 DOWN 3e:91:7c:08:5a:d2 <BROADCAST,NOARP>
dummy1 DOWN a6:12:4f:9e:03:77 <BROADCAST,NOARP>
dummy2 DOWN d2:5b:81:6c:e4:19 <BROADCAST,NOARP>
Los parámetros solo se leen al cargar el módulo, así que para cambiarlos hay que descargarlo y volver a cargarlo:
sudo modprobe -r dummy
Parámetros persistentes
Para que se apliquen siempre que se cargue el módulo, crea un archivo en /etc/modprobe.d/ (debe terminar en .conf):
sudo nano /etc/modprobe.d/dummy.conf
options dummy numdummies=2
Carga el módulo sin parámetros y comprueba que se ha usado el valor del archivo:
sudo modprobe dummy
ip -br link show type dummy
Deberías ver dummy0 y dummy1. Muchos módulos publican el valor activo de sus parámetros en /sys/module/<módulo>/parameters/; dummy no lo hace, por eso aquí se comprueba por su efecto.
Paso 4: Cargar módulos en el arranque
El kernel carga automáticamente la mayoría de drivers cuando detecta el hardware correspondiente. Para los que no se cargan solos (por ejemplo, br_netfilter que necesitan Kubernetes y otros entornos de contenedores), añádelos a un archivo en /etc/modules-load.d/, un módulo por línea:
sudo nano /etc/modules-load.d/custom.conf
br_netfilter
dummy
El servicio systemd-modules-load lee estos archivos en cada arranque. Aplícalo ahora sin reiniciar:
sudo systemctl restart systemd-modules-load.service
lsmod | grep -E 'br_netfilter|dummy'
Cuando termines las pruebas, quita dummy de este archivo y borra /etc/modprobe.d/dummy.conf para no crear interfaces innecesarias en cada arranque.
Si falla, revisa sus mensajes:
journalctl -b -u systemd-modules-load.service
Paso 5: Bloquear un módulo
A veces quieres impedir que se cargue un módulo: un driver que da problemas, un protocolo que no usas o un dispositivo que no existe. Como ejemplo, en máquinas virtuales a menudo se carga floppy sin que haya disquetera.
La directiva blacklist impide la carga automática por detección de hardware, pero no que otro módulo o un usuario lo cargue explícitamente. Para bloquearlo del todo, añade también una regla install que lo sustituya por /bin/false:
sudo nano /etc/modprobe.d/blacklist-floppy.conf
blacklist floppy
install floppy /bin/false
Si el módulo está incluido en el initramfs, se cargaría antes de leer esta configuración. Regenera el initramfs para que incluya el archivo:
sudo update-initramfs -u
Descárgalo si está cargado y comprueba que ya no se puede cargar:
sudo modprobe -r floppy
sudo modprobe floppy
El segundo comando debe fallar con un error Error running install command '/bin/false' for module floppy, y lsmod | grep floppy no debe devolver nada.
Para deshacer el bloqueo, borra el archivo y vuelve a ejecutar sudo update-initramfs -u.
Advertenciano bloquees módulos de disco (
virtio_blk,virtio_scsi,nvme...) ni de red (virtio_net...). El servidor dejaría de arrancar o de tener red, y solo podrías arreglarlo desde la consola o un sistema de rescate.
Paso 6: Compilar un módulo externo con DKMS
Los módulos que no vienen con el kernel (algunos drivers de hardware, VirtualBox, ZFS de terceros...) deben compilarse para cada versión del kernel. DKMS automatiza esto: registra el código fuente y lo recompila e instala cada vez que se instala un kernel nuevo.
Instalar DKMS
Instala DKMS, las herramientas de compilación y las cabeceras del kernel en uso:
sudo apt update
sudo apt install dkms build-essential linux-headers-$(uname -r)
Instala también el metapaquete de cabeceras para que se actualicen junto con el kernel; sin ellas, DKMS no puede compilar para un kernel nuevo:
sudo apt install linux-headers-generic
Crear un módulo de ejemplo
DKMS espera el código en /usr/src/<nombre>-<versión>. Crea un módulo mínimo llamado hello:
sudo mkdir -p /usr/src/hello-1.0
sudo nano /usr/src/hello-1.0/hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Ejemplo de modulo gestionado con DKMS");
MODULE_VERSION("1.0");
static int __init hello_init(void)
{
pr_info("hello: modulo cargado\n");
return 0;
}
static void __exit hello_exit(void)
{
pr_info("hello: modulo descargado\n");
}
module_init(hello_init);
module_exit(hello_exit);
Crea el Makefile que usa el sistema de compilación del kernel:
sudo nano /usr/src/hello-1.0/Makefile
obj-m := hello.o
Y el archivo dkms.conf, que describe el módulo a DKMS:
sudo nano /usr/src/hello-1.0/dkms.conf
PACKAGE_NAME="hello"
PACKAGE_VERSION="1.0"
BUILT_MODULE_NAME[0]="hello"
DEST_MODULE_LOCATION[0]="/updates/dkms"
MAKE[0]="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build"
CLEAN="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build clean"
AUTOINSTALL="yes"
AUTOINSTALL="yes" hace que DKMS lo recompile automáticamente al instalar un kernel nuevo.
Registrar, compilar e instalar
sudo dkms add -m hello -v 1.0
sudo dkms build -m hello -v 1.0
sudo dkms install -m hello -v 1.0
Comprueba el estado:
dkms status
hello/1.0, 6.8.0-45-generic, x86_64: installed
Carga el módulo y revisa su mensaje en el log del kernel:
sudo modprobe hello
sudo dmesg | tail -n 2
[ 8123.402117] hello: loading out-of-tree module taints kernel.
[ 8123.402391] hello: modulo cargado
El aviso de taints kernel es normal para cualquier módulo externo.
Mantenimiento
Para eliminar el módulo de todos los kernels y de DKMS:
sudo modprobe -r hello
sudo dkms remove hello/1.0 --all
Tras una actualización del kernel, dkms status debería mostrar el módulo como installed también para la nueva versión. Si no, revisa el log de compilación que DKMS indica en su mensaje de error.
Solución de problemas
modprobe: FATAL: Module xxx not found in directory /lib/modules/.... El módulo no existe para el kernel en uso. En Ubuntu, algunos drivers están en el paquete linux-modules-extra-$(uname -r); en imágenes cloud que usan otras variantes de kernel pueden no estar disponibles.
modprobe: ERROR: could not insert 'xxx': Key was rejected by service. Secure Boot está activo y el módulo no está firmado con una clave de confianza. Ubuntu firma los módulos DKMS con una clave MOK propia; debes registrarla con sudo mokutil --import /var/lib/shim-signed/mok/MOK.der y confirmar el registro desde la consola en el siguiente arranque.
dkms build falla con Kernel headers ... cannot be found. Faltan las cabeceras de ese kernel. Instala linux-headers-<versión> para la versión que indica el error.
El módulo bloqueado sigue cargándose tras reiniciar. Se carga desde el initramfs. Ejecuta sudo update-initramfs -u y reinicia.
Conclusión
Ahora sabes consultar, cargar y descargar módulos con modprobe, fijar sus parámetros, cargarlos en el arranque, bloquearlos y mantener un módulo externo con DKMS a través de las actualizaciones del kernel. Como siguientes pasos, puedes revisar los mensajes que generan los drivers con dmesg, explorar /sys/module/ para ver los parámetros activos o ajustar el kernel en tiempo real con sysctl.
