wandres.dev
COMPILAR (KBUILD) · Imagen, módulos, obj-m

Kbuild: compilar el kernel

El sistema de build del kernel: cómo se compila la imagen y los módulos, los targets de make que necesitas, y el Makefile mínimo para tu propio módulo fuera del árbol.

⏱ 13 min

Con el kernel configurado, toca compilarlo. El kernel usa Kbuild, un sistema construido sobre Make con reglas propias. No necesitas dominarlo entero, pero sí saber compilar la imagen, los módulos, y —lo más importante para ti— construir tu propio módulo contra un kernel existente.

🎯 Al terminar esta lección sabrás
  • Compilar la imagen del kernel y los módulos.
  • Los targets de make esenciales.
  • El Makefile mínimo de un módulo out-of-tree.
  • Acelerar la compilación.

Compilar el kernel completo

make -j$(nproc)      # compila la imagen usando todos los núcleos
make modules         # compila los módulos (si no lo hizo ya 'make')
sudo make modules_install   # instala los .ko en /lib/modules/
sudo make install    # instala la imagen y actualiza el bootloader

-j$(nproc) paraleliza usando todos tus núcleos — imprescindible, porque compilar el kernel entero puede tardar de minutos a horas según la config y la máquina. El resultado principal es vmlinux (la imagen sin comprimir) y una imagen comprimida y arrancable (en x86, arch/x86/boot/bzImage).

Targets útiles de make

Comando Qué hace
make -j$(nproc) compila imagen y módulos
make modules solo los módulos
make clean borra objetos, conserva .config
make mrproper limpieza total (borra también .config)
make M=ruta compila un módulo externo en esa ruta
make menuconfig (recordatorio) reconfigurar

Tu propio módulo: out-of-tree

Aquí está lo que más usarás. No necesitas compilar el kernel entero para desarrollar un módulo: lo compilas contra un kernel ya construido (o los headers instalados). El Makefile mínimo:

obj-m += mimodulo.o        # dile a Kbuild que construya mimodulo.ko

# KDIR apunta a los headers del kernel en ejecución
KDIR := /lib/modules/$(shell uname -r)/build

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules   # compila usando el Kbuild del kernel

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean
make            # produce mimodulo.ko
El truco del M= : Kbuild construye TU código

Fíjate en la línea clave: $(MAKE) -C $(KDIR) M=$(PWD) modules. Le dice a make que entre en el directorio del kernel (-C $(KDIR), donde vive Kbuild) pero que construya los módulos de tu directorio (M=$(PWD)). Así tu código se compila con exactamente las mismas reglas, flags y configuración que el kernel contra el que va a cargarse — algo esencial, porque un módulo debe coincidir con la versión y config del kernel o no cargará. Esta es la razón por la que un módulo del kernel no se compila con un gcc suelto (como en userspace): necesita el andamiaje de Kbuild para tener las definiciones, la ABI interna y los símbolos correctos. Con este Makefile de seis líneas tienes tu ciclo de desarrollo: editas, make, insmod (nivel 7), pruebas, rmmod, repites.

Acelerar la compilación

💡
Compila rápido para iterar rápido

Recompilar el kernel entero para probar un cambio es agónico. Las claves para un ciclo ágil: (1) desarrolla como módulo out-of-tree (compilas solo tu .ko, segundos, no el kernel entero). (2) Usa make localmodconfig (nivel 4) para un kernel base mínimo. (3) Instala ccache para cachear compilaciones repetidas. (4) Compila con -j$(nproc). Un buen setup convierte “esperar 40 minutos” en “esperar 5 segundos”, y esa diferencia es lo que hace viable aprender el kernel iterando de verdad, no en teoría.

⚔️ Compila de verdad
  1. Instala los headers del kernel (linux-headers-$(uname -r) o equivalente).
  2. Escribe el Makefile mínimo de módulo (obj-m, KDIR, la regla con M=).
  3. Aunque aún no tengas el código del módulo (nivel 7), entiende cada línea del Makefile.
  4. Si te atreves y tienes tiempo/VM: compila un kernel completo con make -j$(nproc) y observa el proceso.