Red de conocimiento informático - Conocimiento informático - Cómo ver el código fuente de software o sistemas operativos (como Linux) cuyo código fuente es público (pasos detallados)

Cómo ver el código fuente de software o sistemas operativos (como Linux) cuyo código fuente es público (pasos detallados)

El sistema de configuración del kernel de Linux consta de tres partes: Makefile: Makefile distribuido en el código fuente del kernel de Linux, que define las reglas para compilar el archivo de configuración del kernel de Linux (config.in): proporciona a los usuarios la función de seleccionar la herramienta de configuración; : Incluye el intérprete de comandos de configuración (que interpreta 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, una interfaz basada en caracteres y una interfaz de usuario de configuración). (

Intérprete de comandos de configuración (interpreta los comandos de configuración utilizados en el script de configuración) e interfaz de usuario de configuración (que proporciona interfaces de configuración de usuario basadas en una interfaz de caracteres, una interfaz gráfica basada en Ncurses y una interfaz gráfica basada en Xwindows, respectivamente correspondientes to Make config, Make menuconfig y make xconfig).

Estas herramientas de configuración están escritas en lenguajes de scripting, como Tcl/TK, Perl (también incluyen algo de código escrito en C. Este artículo no analiza). sistema de configuración en sí, pero describe cómo usarlo. Entonces, a menos que sea el mantenedor del sistema de configuración, el desarrollador promedio del kernel no necesita saber cómo funcionan, solo cómo escribir Makefiles y archivos de configuración. , solo discutiremos los Makefiles y los archivos de configuración. Además, usaremos ARM como ejemplo para discutir cualquier cosa relacionada con una arquitectura de CPU específica, lo que no solo aclara la discusión, sino que no tiene impacto en el contenido en sí.

2 .Makefile

2.1 Descripción general de Makefile

La función de Makefile es crear una lista de archivos fuente que deben compilarse de acuerdo con la configuración y luego compilar estos archivos. por separado y vincular el código de destino para finalmente generar archivos binarios del kernel de Linux.

Dado que el código fuente del kernel de Linux está organizado en una estructura de árbol, los Makefiles también se distribuyen en forma de árboles de directorios. El kernel de Linux y los archivos directamente relacionados con Makefiles son: Makefile: Makefile de nivel superior, que 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. se utiliza para almacenar los resultados de la configuración del kernel (como make config): ubicados en arch/*/Makefile. Los Makefiles en diferentes directorios del sistema de la CPU, como arch/arm/Makefile, son Makefiles específicos de la plataforma en subdirectorios: como. drivers/Makefile, son responsables de administrar el código fuente en sus subdirectorios. Rules.make: archivos de reglas, utilizados por todos los Makefiles.

El usuario configura una configuración make, que genera un archivo .config. -level Makefile lee las opciones de configuración en .config. El Makefile de nivel superior tiene dos tareas principales: generar archivos vmlinux y módulos del Kernel. Para hacer esto, el Makefile de nivel superior recurre a cada subdirectorio del kernel y llama a los Makefiles. esos subdirectorios según la configuración del kernel. Hay una oración en el Makefile de nivel superior: incluya arch/$(ARCH)/Makefile, que contiene el Makefile para una arquitectura de CPU específica, que contiene información relacionada con la plataforma.

El Makefile ubicado en cada subdirectorio también crea la lista de archivos fuente necesarios para la configuración actual en función de la información de configuración proporcionada en .config e incluye $(TOPDIR)/Rules.make al final del archivo. . Makefile *** Se utilizan todas las reglas de compilación.

Por ejemplo, si necesita compilar todos los programas C en este directorio en código ensamblador, debe incluir las siguientes reglas de compilación en el Makefile:

%.s: %.c

$( CC) $(CFLAGS) -S $< -o $@

Hay muchos subdirectorios con los mismos requisitos, por lo que esta regla de compilación debe incluirse en sus respectivos Makefiles. Incluir esta regla de compilación en el Makefile respectivo puede resultar engorroso. El kernel de Linux colocará dichas reglas de compilación en Rules.make y las incluirá en el Makefile correspondiente (incluya Rules.make), para que pueda evitar repetir las mismas reglas 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 $< -o $@

2.2 Variables en Makefile

El Makefile de nivel superior define y genera muchas variables al entorno, y parte de la información se pasa a Makefiles en diferentes subdirectorios. Algunas variables, como SUBDIRS, 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 siguientes son variables de uso común:

1) Información de versión

La información de versión incluye VERSIÓN, PATCHLEVEL, SUBLEVEL, EXTRAVERSION y KERNELRELEASE. La información de versión define la versión actual del kernel, por ejemplo: VERSIÓN=2, PATCHLEVEL=4, PATCHLEVEL=3, PATCHLEVEL=4, PATCHLEVEL=5. PATCHLEVEL=4, SUBLEVEL=18, EXATAVERSION=-rmk7, ****, que juntos forman la versión de lanzamiento del kernel KERNELRELEASE: 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. Los archivos ARCH se utilizan en muchos subdirectorios. En muchos subdirectorios Makefiles, la lista de archivos fuente para compilar se selecciona según la definición de ARCH.

3) Información de ruta: TOPDIR, SUBDIRS

TOPDIR define el directorio raíz donde se encuentra el código fuente del kernel de Linux. Por ejemplo, Makefiles en cada subdirectorio puede encontrar la ubicación de Rules.make a través de $(TOPDIR)/Rules.make.

SUBDIRS define una lista de directorios, que el Makefile de nivel superior utiliza para decidir qué subdirectorios ingresar al compilar el kernel o módulo. El valor de SUBDIRS depende de la configuración del kernel, y SUBDIRS es; asignado al controlador del núcleo mm fs net ipc lib Dependiendo de la configuración del núcleo, SUBDIRS se asigna al controlador del núcleo mm fs net ipc lib; El valor de SUBDIRS depende de la configuración del kernel en el Makefile de nivel superior, el valor de SUBDIRS es los controladores del kernel mm fs net ipc lib en arch/*/Makefile, el valor de SUBDIRS se expandirá de acuerdo con la configuración del kernel; como se muestra en 4).

4) Información de composición del kernel: HEAD, CORE_FILES, NETWORKS, DRIVERS, LIBS

El archivo del kernel de Linux vmlinux se genera mediante las siguientes reglas:

vmlinux: $ (CONFIGURACIÓN ) init/main.o init/version.o linuxsubdirs

$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o

-- grupo de inicio

$(CORE_FILES)

$(DRIVERS)

$(NETWORKS)

$(LIBS)

--end-group

-o vmlinux

Como puede ver, vmlinux consta de HEAD, main.o, version.o, CORE_FILES, DRIVERS, Composición de REDES y LIBS. Estas variables (como HEAD) se utilizan para definir la lista de archivos objeto y archivos de biblioteca a los que está conectado vmlinux. HEAD se define en arch/*/Makefile y se utiliza para determinar la lista de archivos que se vincularán primero a vmlinux. Por ejemplo, para las CPU de la serie ARM, HEAD se define de la siguiente manera:

HEAD := arch/arm/kernel/head-$(PROCESSOR).o

arch/arm/kernel /init_task .o

significa head-$(PROCESSOR).o e init_task ).o e init_task.o deben estar vinculados primero a vmlinux. Dependiendo de la CPU de destino, el PROCESADOR puede ser armv o armo. CORE_FILES, NETWORK, DRIVERS y LIBS se definen en el Makefile de nivel superior y se extienden mediante arch/*/Makefiles según sea necesario. CORE_FILES corresponde a los archivos principales del kernel, a saber, kernel/kernel.o, mm/mm.o, fs/fs.o e ipc/ipc.o. Además, arch/arm/Makefile extiende CORE_FILES:

# arch/arm/Makefile

# Si tenemos un directorio de máquina específico, inclúyalo al compilar.

MACHDIR := arco/brazo/mach-$(MACHINE)

ifeq ($(MACHDIR),$(comodín $(MACHDIR)))

SUBDIRS += $(MACHDIR)

CORE_FILES := $(MACHDIR)/$ (MACHDIR)/$(MACHINE).o $(CORE_FILES)

endif

HEAD := arch/arm/kernel/head-$(PROCESSOR).o

arch/arm/kernel/init_task.o

SUBDIRS += arco/brazo/kernel arco/brazo/mm arco/brazo/lib arco/brazo/nwfpe

CORE_FILES := arco/brazo/kernel/kernel.o arco/brazo/mm/mm. o $( CORE_FILES)

LIBS := arch/arm/lib/lib.a $(LIBS)

5) Información de compilación: ppp, cc, as, ld, ar, cflags, linkflags

se definen en Rules.make. CROSS_COMPILE es una regla general para la compilación. En situaciones específicas, el entorno de compilación debe especificarse claramente. El entorno de compilación se define en las variables anteriores. CROSS_COMPILE se define para requisitos de compilación cruzada, por ejemplo:

CROSS_COMPILE = arm-linux-

CC = $(CROSS_COMPILE)gcc

LD = $( CROSS_COMPILE)ld

......

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 tanto, se agregará $(CROSS_COMPILE) antes de cada herramienta de compilación cruzada para formar el nombre completo del archivo de la herramienta de compilación cruzada, como arm-linux-gcc.

CFLAGS define los parámetros pasados ​​al compilador de C.

LINKFLAGS es un parámetro utilizado por el vinculador cuando se vincula para compilar vmlinux. LINKFLAGS se define en arm/*/Makefile, por ejemplo:

# arch/arm/Makefile

LINKFLAGS :=-p -X -T arch/arm/ vmlinux.lds< / p>

6) Variables de configuración CONFIG_*

Hay muchas ecuaciones de variables de configuración en el archivo .config para ilustrar los resultados de la configuración del usuario. Por ejemplo, CONFIG_MODULES=y indica que el usuario ha seleccionado la funcionalidad del módulo del kernel de Linux.

Cuando .config se incluye en el Makefile de nivel superior, forma una serie de variables de configuración, cada una con un valor definido: y significa que el código del núcleo correspondiente a esta opción de compilación se compila estáticamente en En el Kernel de Linux; m significa que el código del kernel correspondiente a esta opción de compilación se compila en el módulo; n significa que esta opción de compilación no está seleccionada o, si esta opción no está seleccionada, el valor de la variable de configuración está vacío.

2.3 Variable Rules.make

Como se mencionó anteriormente, Rules.make es un archivo de reglas de compilación y todos los Makefiles contienen Rules.make. El archivo Rules.make define una serie de variables, las más importantes de las cuales son las variables de compilación y las variables de lista vinculada.

O_OBJS, L_OBJS, OX_OBJS, LX_OBJS: 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 utiliza el símbolo de salida EXPORT_SYMBOL.

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 significa que el archivo objeto utiliza el símbolo de salida EXPORT_SYMBOL.

O_TARGET, L_TARGET: Cada subdirectorio tiene un O_TARGET o L_TARGET. 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 usando $(LD) -r. O_TARGET es un módulo que se puede cargar en un módulo. O_TARGET termina en .o, mientras que L_TARGET termina en .a. .