Cómo construir el árbol de código fuente del kernel
Makefile: el Makefile distribuido en el código fuente del kernel de Linux define las reglas de compilación del kernel de Linux;
Archivo de configuración (config . en): Proporciona a los usuarios la función de selección de configuración;
Herramientas de configuración: incluido el intérprete de comandos de configuración (explicación de los comandos de configuración utilizados en los scripts de configuración) y la interfaz de usuario de configuración (que proporciona una interfaz basada en caracteres, gráfica Ncurses). interface y La interfaz de configuración de usuario de la interfaz gráfica de Xwindows corresponde a Make config, Make menuconfig y make xconfig respectivamente).
Estas herramientas de configuración están escritas en lenguajes de scripting, como Tcl/TK y Perl (incluidos algunos códigos escritos en C). Este artículo no analiza el sistema de configuración en sí, pero presenta cómo utilizar el sistema de configuración. Entonces, a menos que usted sea el mantenedor del sistema de configuración, el desarrollador promedio del kernel no necesita conocer sus principios, solo necesita saber cómo escribir Makefiles y archivos de configuración. Por lo tanto, en este artículo solo analizamos Makefile y los archivos de configuración. Además, siempre que se trate de contenido específico relacionado con la arquitectura de la CPU, usaremos ARM como ejemplo, que no solo puede aclarar los problemas discutidos, sino que tampoco tiene ningún impacto en el contenido en sí.
2. Generar archivos
2.1 Descripción general de Makefile
La función de Makefile es construir una lista de archivos fuente que deben compilarse de acuerdo con la configuración. Y luego compílelos por separado para convertir el código de destino. Vinculados entre sí, la forma final es un binario del kernel de Linux.
Debido a que el código fuente del kernel de Linux está organizado en una estructura de árbol, los Makefiles también se distribuyen en el árbol de directorios. Los Makefiles en el kernel de Linux y los archivos directamente relacionados con Makefiles son:
Makefile: el Makefile de nivel superior es el archivo de control general para toda la configuración y compilación del kernel.
. config: archivo de configuración del kernel, que contiene opciones de configuración seleccionadas por el usuario y se utiliza para almacenar los resultados de la configuración del kernel (como make config).
Arch/*/Makefile: Makefile se encuentra en varios directorios del sistema de la CPU, como arch/arm/Makefile, y es un Makefile específico de la plataforma.
Makefile en cada subdirectorio: como drivers/Makefile, es responsable de la gestión del código fuente en el subdirectorio.
Rules.make: Archivo de reglas, utilizado por todos los Makefiles.
Después de que el usuario lo configura a través de make config. Se ha generado la configuración. Se lee el Makefile superior. configuración. El Makefile de nivel superior tiene dos tareas principales: generar archivos vmlinux y módulos del kernel. Para lograr este objetivo, el Makefile de nivel superior ingresa recursivamente a cada subdirectorio del kernel y llama a los Makefiles ubicados en estos subdirectorios respectivamente. En cuanto a qué subdirectorios ingresar, depende de la configuración del kernel. En el Makefile de nivel superior, hay una oración: incluya arch/$(ARCH)/Makefile, que contiene el Makefile bajo una arquitectura de CPU específica. Este Makefile contiene información relacionada con la plataforma.
El Makefile ubicado en cada subdirectorio también se basa en. Al final del archivo se incluye $(TOPDIR)/Rules.make.
El archivo Rules.make juega un papel muy importante, define todas las reglas de compilación utilizadas por Makefile ***. Por ejemplo, si necesita compilar todos los programas C en este directorio en código ensamblador, debe tener las siguientes reglas de compilación en el Makefile:
%.s: %. c
$(CC)$(CFLAGS)-S $<-o $@
Hay muchos subdirectorios con los mismos requisitos y deben incluirse en su Makefile. Esta compilación La regla será más problemática.
En el kernel de Linux, dichas reglas de compilación se colocan de manera uniforme en Rules.make, y Rules.make (incluido Rules.make) se incluye en cada Makefile, lo que evita que las mismas reglas aparezcan repetidamente en múltiples Makefiles. Para el ejemplo anterior, la regla correspondiente en Rules.make es:
%.s: %. c
$(CC)$(CFLAGS)$(EXTRA _ CFLAGS)$(CFLAGS _ $(* F))$(CFLAGS _ $ @)-S $ & lt;-o $@
2.2 Variables en archivos Makefile
El Makefile de nivel superior define y genera muchas variables al entorno, pasando cierta información a los Makefiles en cada subdirectorio. Algunas variables, como los subdirectorios, no solo se definen y se les asignan valores iniciales en el Makefile de nivel superior, sino que también se expanden en arch/*/Makefiles.
Las variables más utilizadas son las siguientes:
1) Información de versión
La información de versión incluye: versión, nivel de parche, subnivel, versión adicional y kernel. versión. La información de la versión define la versión actual del kernel, como VERSION=2, PATCHLEVEL=4, SUBLEVEL=18, EXATAVERSION=-rmk7, que son * * * iguales que la versión de lanzamiento del kernel: 2.4.18-rmk7.
2) Arquitectura de CPU: ARCH
Al comienzo del Makefile de nivel superior, use ARCH para definir la arquitectura de la CPU de destino, como ARCH:=arm, etc. En Makefiles en muchos subdirectorios, la lista de archivos fuente compilados debe seleccionarse según la definición de ARCH.
3) Información de ruta: directorio superior, subdirectorio
TOPDIR define el directorio raíz donde se encuentra el código fuente del kernel de Linux. Por ejemplo, el Makefile en cada subdirectorio puede encontrar la ubicación de Rules.make a través de $ (topdir)/rules.make.
SUBDIRS define una lista de directorios. Al compilar un kernel o módulo, el Makefile de nivel superior determina qué subdirectorios ingresar en función de los subdirectorios. El valor del subdirectorio depende de la configuración del kernel. En el Makefile de nivel superior, SUBDIRS se especifica como controlador del kernel mm fs net ipc lib. Según la configuración del kernel, expanda el valor SUBDIRS en arch/*/Makefile, consulte el ejemplo en 4).
4) Información de composición del kernel: head, core_files, redes, controladores, libs.
El archivo del kernel de Linux vmlinux se genera mediante las siguientes reglas:
VM Linux:$(CONFIGURATION)init/main . o init/version o Linux subdirs
<. p>$ (LD)$(banderas de enlace)$(HEAD)init/main . o init/version o-Start-Group
$(Core File)
$(controlador)
$(red)
USD (LIBS)
-base final
-o vmlinux
p>Se puede ver que vmlinux consta de HEAD, main.o, version.o, CORE_FILES, controlador, red y LIBS. Estas variables (como HEAD) se utilizan para definir la lista de archivos objeto y archivos de biblioteca que están conectados para generar vmlinux. HEAD se define en arch/*/Makefile y se utiliza para determinar la lista de archivos vinculados por primera vez a vmlinux. Por ejemplo, para las CPU de la serie ARM, HEAD se define como:
HEAD := arch/arm/kernel/head-$(procesador).
o
arch/arm/kernel/init_task.o
Muestra head-$(procesador). o e init_task.o deben estar vinculados primero a vmlinux. Si el procesador es armv o armo depende de la CPU de destino. CORE_FILES, NETWORK, DRIVERS y LIBS se definen en el Makefile de nivel superior y se expanden mediante arch/*/Makefile según sea necesario. CORE_FILES corresponde a los archivos del kernel, incluidos kernel/kernel.o, mm/mm.o, fs/fs.o, ipc/ipc.o. Se puede ver que estos son los archivos más importantes que componen el kernel. Además, arch/arm/Makefile extiende CORE_FILES:
# arch/arm/Makefile
# Si tenemos un directorio específico de la máquina, inclúyalo en la compilación.
MACHDIR :=arch/arm/mach-$(máquina)
ifeq ($(dirección de la máquina), $(comodín$(dirección de la máquina)))
Rama += $(MACHDIR)
CORE _ FILES:= $(mach dir)/$(MACHINE). o $(archivo principal)
endif
HEAD := arch/arm/kernel/head-$(procesador). o
arch/arm/kernel/init_task.o
SUBDIRS+= arch/arm/kernel arch/arm/mm arch/arm/lib arch/arm/nwf PE
Archivo principal:= arch/arm/kernel/kernel . o arch/arm/mm/mm . o $(archivo principal)
LIBS := arch/arm/lib/lib.a. $(LIBS)
5) Información de compilación: CPP, CC, AS, LD, AR, CFLAGS, LINKFLAGS.
Rules.make define reglas generales para la compilación. Para ocasiones específicas, el entorno de compilación debe especificarse claramente. El entorno de compilación se define en las variables anteriores. De acuerdo con los requisitos de compilación cruzada, se define CROSS_COMPILE. Por ejemplo:
CROSS_COMPILE = arm-linux-
CC = $(compilación cruzada)gcc
LD = $(compilación cruzada)LD p>
......
CROSS_COMPILE define el prefijo del compilador cruzado arm-linux-, lo que significa que todas las herramientas del compilador cruzado comienzan con arm-linux-, por lo que en cada compilador cruzado compilación Agregue $(CROSS_COMPILE) delante de la herramienta del compilador para formar un nombre de archivo completo de la herramienta del compilador cruzado, como arm-linux-gcc.
CFLAGS define los parámetros pasados al compilador de c.
LINKFLAGS son parámetros utilizados por el vinculador cuando se vincula para compilar vmlinux. LINKFLAGS se define en arm/*/Makefile, como por ejemplo:
# arch/arm/Makefile
link flags:=-p-X-T arch/arm/VM Linux p>
6) Hay muchas ecuaciones de variables de configuración en la variable de configuración CONFIG_*
. Archivo de configuración para describir los resultados de la configuración del usuario. Por ejemplo, CONFIG_MODULES=y indica que el usuario ha seleccionado la función del módulo del kernel de Linux.
Después de eso.
config se incluye en el Makefile de nivel superior, formando muchas variables de configuración. Cada variable de configuración tiene un valor determinado: y indica que el código del kernel correspondiente a esta opción de compilación se compila estáticamente en el kernel de Linux. La opción de compilación se compila en un módulo; n indica que esta opción de compilación no está seleccionada; si no se selecciona en absoluto, el valor de la variable de configuración está vacío.
2.3 Reglas. Generar variables
Como se mencionó anteriormente, Rules.make es un archivo de reglas de compilación y todos los Makefiles contendrán reglas.make. Los archivos Rules.make definen muchas variables. las más importantes son las variables de lista compiladas y vinculadas.
O_OBJS, L_OBJS, OX_OBJS, LX_OBJS: una lista de archivos de destino en este directorio que deben compilarse en el kernel de Linux vmlinux. La "x" en OX_OBJS y LX_OBJS indica que el archivo de destino usa EXPORT_SYMBOL. símbolo de salida.
M_OBJS, MX_OBJS: una lista de archivos de destino en este directorio que deben compilarse en módulos cargables. Asimismo, la "x" en MX_OBJS indica que el símbolo de salida EXPORT_SYMBOL se utiliza en el archivo de destino.
O_TARGET, L_TARGET: Hay un O_TARGET o L_TARGET en cada subdirectorio. Rules.make primero compila todos los archivos objeto en O_OBJS y OX_OBJS desde el código fuente, y luego los vincula a O_TARGET o L_TARGET con $(LD)-R, O_TARGET termina con . o, mientras que L_TARGET termina en . a.