Linux: navegando por los mares del código fuente
En este nuevo artículo de la serie Linux, me he decidido a dar una serie de material para que podáis analizar el código fuente de Linux línea a línea. Hacer esto desde cero es algo arduo, pero te daré materiales para que puedas analizarlo si quieres. De hecho, te animo a hacerlo, puesto que, como dije en mi curso C2GL, no aprenderás más sobre Linux que navegando por el código fuente del kernel…
Lo que haré es mostrar una guía sobre cómo te puedes mover por el kernel, con los directorios más comunes de las fuentes, qué contiene cada uno, e información sobre los ficheros más importantes. Y luego te mostraré unos recursos para que puedas analizar el código fuente línea a línea con comentarios. Creo que te va a gustar…
En mi curso tuve la suerte de contar con una ayudita VIP de John «maddog» Hall y un prólogo de Linus Torvalds que me hizo especial ilusión. Intenté mientras creaba C2GL atraer algunos VIPs para animar aún más a mis alumnos y conseguí estas y otras colaboraciones…
Código fuente Linux: jerarquía de directorios y contenido
La cantidad de directorios y ficheros varía en función de la versión que estés analizando. Pero aquí te incluyo los más populares que vas a encontrar cuando navegues por las fuentes. En versiones old del kernel encontrarás algunos directorios como Doc, Dependent, etc., que ahora han cambiado…
Recuerda que estarán alojadas en /usr/src/linux (enlace simbólico de /usr/src/<kernel-version>). Te animo a descargar las fuentes en tu distro, abrir un terminal e ir navegando por los distintos directorios y ficheros mientras vas leyendo este artículo. Aquí van los directorios:
- arch: contiene directorios de cada arquitectura de procesador soportada. Por ejemplo, x86, arm, arm64, mips, s360, ia64 (¡ojo! Lo repito una y otra vez, pero siguen confundiéndose algunos, no es x86-64), powerpc, sparc, avr32, etc. Cada uno tiene ficheros de código fuente específico para dicha arquitectura.
- block: contiene el código de controladores para dispositivos de bloque.
- crypto: código fuente para manejar algoritmos de cifrado, como sha512_generic.c.
- Documentation: documentación en distintos formatos. Puedes acudir aquí cuando necesites información sobre el kernel y sus componentes. Un fichero interesante es Changes con los requisitos mínimos y dependencias necesarias para compilar el kernel.
- drivers: directorio para el código de controladores de hardware, como bluetooth, ATA, ACPI, cpuidle, cpufreq, DMA, PCI, USB, IDE, etc.
- firmware: contiene código para que pueda la máquina pueda leer y entender señales de los dispositivos. Por ejemplo, para que una webcam se pueda relacionar con el resto del hardware y que éste entienda las señales que envía. También encontrarás aquí el firmware EFI/BIOS, etc., así como los famosos blobs binarios.
- fs: directorio con el código relacionado con los sistemas de archivos (ext4, xfs, btrfs,…).
- include: ficheros de cabeceras usados por el kernel. El compilador los incluirá de forma automática al procesar algún otro fichero de código fuente en cuyo interior se hacen llamamientos (pragmas) a éstas headers.
- init: código necesario para la inicialización del kernel y para crear todo el espacio de usuario durante el arranque. Uno de los ficheros más importantes es main.c, que es el core o núcleo «glue» del kernel que apuntará hacia el resto de partes hasta que el kernel esté disponible.
- ipc: muy importante, es el código IPC (Inter-Process Communication). Contiene el código de los manejadores de comunicación entre procesos, es decir, semáforos, código para la memoria compartida, etc.
- kernel: código que controla al propio kernel en sí, con todas las funcionalidades principales y no dependientes de las arquitecturas.
- lib: contiene el código de bibliotecas que el kernel necesita para sus rutinas.
- mm: código del Memory Management, es decir, del subsistema que gestiona la memoria virtual. No están todas aquí, solo las no dependientes de la arquitectura. Las dependientes las encontrarás dentro de arch/<arquitectura>/mm/. Gracias a este código se puede asignar memoria a los procesos, cache de página, intercambio de páginas entre la memoria de intercambio y la RAM, etc.
- net: dedicado al código fuente de los controladores de red a bajo nivel, como algunos protocolos especificos. Por ejemplo, en net/core se incluye el codigo de IPv4, IPv6, Appletalk, WiFi, Bluetooth, Ethernet, NFC, WIMAX,…
- samples: contiene ejemplos de programación y módulos que están iniciándose.
- scripts: no contiene código del kernel, solo scripts necesarios para construir el kernel.
- security: código fuente relacionado con la seguridad, es decir, de extensiones como AppArmor, NSA SELinux, etc.
- sound: código fuente de los controladores de sonido, es decir, el código de la pila de sonido.
- tools: código fuente de muchas de las herramientas para interactuar con el kernel Linux.
- usr: código fuente para crear ficheros CPIO como vmlinuz y similares tras compilar el kernel.
- virt: ficheros de código fuente para la virtualización.
Dentro de esos directorios vas a encontrar gran cantidad de ficheros con extensiones .c y .h que corresponden a los códigos en lenguaje C y a los headers o cabeceras. Pero también hay algunos ficheros sueltos dentro de las fuentes del kernel que son interesantes:
- COPYING: información sobre la licencia y derechos de autor.
- CREDITS: lista de contribuidores.
- Kbuild: script para configurar algunos parámetros para construir el kernel.
- Kconfig: script para configurar el kernel.
- MAINTAINERS: lista de los mantenedores del kernel.
- Makefile: script principal para compilar el kernel. Le pasará al compilador la lista de ficheros de fuente a compilar y otra información o parámetros necesrios según la configuración que le hayamos dado.
- README: fichero de texto con información que los desarrolladores quieren que conozcas para compilar el kernel. Es recomendable leerlo siempre, por si hay algún paso o peculiaridad que debemos hacer para compilar esa versión concreta del kernel.
- REPORTING-BUGS: documento de texto con información para el reporte de errores.
¿Eres un curioso como yo y te gusta husmear para aprender? Pues entonces te invito a indagar por los rincones de las profundidades del código del kernel Linux…
Recursos para analizar línea a línea el kernel Linux
Para poder analizar el kernel Linux línea a línea, puedes usar estos recursos que te ofrezco:
- Para usuarios principiantes: Zhao Jiong ha creado un PDF con el código fuente de Linux 0.12 que ha comentado casi línea a línea explicando para qué sirve todo ese código C. Puedes descargar A Heavily Commented Linux Kernel Source Code aquí. Al ser una versión muy primitiva de Linux, hay muchas menos líneas y controladores que en la actualidad, por lo que te resultará mucho más sencillo para comenzar a aprender. Hacerlo con una versión actual para los principiantes sería una locura.
- Para usuarios avanzados: en este sitio han publicado un fantástico tour por el código de Tamacom del kernel Linux 3.12, una versión mucho más actual para aprender sobre un kernel moderno. Además, si te gusta la historia de UNIX, también tienes el código de Unix v7 comentado y el de FreeBSD.
- Mapa interactivo del kernel Linux: si quieres navegar por un diagrama gráfico sobre el kernel Linux y así hacerte una mejor idea de todo el entramado, este es un buen recurso aportado por MAKELINUX.
- Fuentes oficiales: si quieres ver otras versiones del kernel, aunque no tan comentadas, puedes visitar kernel.org y allí encontrarás tanto el último kernel lanzado como versiones antiguas como la Linux 0.11, etc.
- Más: ya sabes que Minix se creó para ser estudiado, por tanto, si quieres puedes usar el código de Minix-1 para estudiarlo. Está muy bien comentado para estudiantes de programación. Para versiones más modernas, puedes acudir a la web oficial de Minix 3.
Más adelante me gustaría publicar otros artículos sobre cómo crear un módulo para Linux, de una forma sencilla. Este artículo y otros los puedes ir complementando con la serie de programación, ya que estos proyectos están escritos en C y ese es el lenguaje elegido para la serie de programación…