Summary of the make process of the top-level Makefile of the Linux kernel

1. Make compilation of Linux kernel source code

This article summarizes what the top-level Makefile does when making the Linux kernel source code. That is to summarize the make process of the Linux kernel source code.

This article is a continuation of the previous article at the following address:

Instructions on the make process of the top-level Makefile of the Linux kernel 2_Ling Xiaozhan's Blog-CSDN Blog

2. Summary of Linux make process

1. vmlinux

When executing the "make" command to compile the Linux kernel source code, the top-level Makefile will compile target _all . After the analysis of the previous article, target _all ultimately depends on vmlinux , and vmlinux in the top-level Makefile depends on the following:

vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE
...
+$(call if_changed,link-vmlinux)

The focus here is to analyze "scripts/link-vmlinux.sh $(vmlinux-deps) FORCE".

Among them, link-vmlinux.sh is just a script file, and the rest is to analyze the dependency vmlinux-deps.

The dependency vmlinux-deps depends on $(head-y) , $(init-y) , $(core-y) , $(libs-y) , $(drivers-y) and $(net-y). six variables.

These six variables have been analyzed in the previous article.

These variables are all built-in.o or .a files. This is the same as oubot. They compile the source code files in the corresponding directories and then generate built-in.o files in the respective directories. Some of them generate . a library file. Finally, these built-in.o and .a files are linked to form an executable file in ELF format, which is vmlinux !

But linking requires a link script. The dependency of vmlinux , arch/arm/kernel/vmlinux.lds, is the link script for the entire Linux .

2. Commands that vmlinux depends on

The commands that vmlinux depends on are as follows:
+$(call if_changed,link-vmlinux)

Indicates that the result of $(call if_changed,link-vmlinux) will be used as the final command to generate vmlinux . The " + " in front indicates that the result of the command cannot be ignored. $(call if_changed,link-vmlinux) is to call the function if_changed , link-vmlinux is the parameter of the function if_changed .

The function if_changed is defined in the file scripts/Kbuild.include as follows:

247 if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
248 @set -e; \
249 $(echo-cmd) $(cmd_$(1)); \
250 printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)

Line 247: any-prereq is used to check whether the dependent file has changed. If the dependent file has changed, then any-prereq is not empty, otherwise it is empty. arg-check is used to check whether the parameters have changed. If there are no changes, arg-check will be empty.
Line 248 , " @set -e " tells bash to exit directly if the execution result of any statement is not true ( that is, an execution error ) .
Line 249 , $(echo-cmd) is used to print the command execution process, for example, it will be output when linking to  vmlinux
" LINK vmlinux ". $ (1) in $(cmd_$(1)) represents the parameter, which is link-vmlinux , so $(cmd_$(1)) represents
Execute the contents of cmd_link-vmlinux .

cmd_link-vmlinux is defined as follows in the top-level Makefile :
914 # Final link of vmlinux
915 cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS)
$(LDFLAGS_vmlinux)
916 quiet_cmd_link-vmlinux = LINK $@
Line 915 is the value of cmd_link-vmlinux , where CONFIG_SHELL=/bin/bash , $< represents the first dependent file of the target vmlinux, so this file is scripts/link-vmlinux.sh .
LD= arm-linux-gnueabihf-ld -EL , LDFLAGS is empty. The value of LDFLAGS_vmlinux is determined by the top-level Makefile and
The two files arch/arm/Makefile are decided together, and finally LDFLAGS_vmlinux=-p --no-undefined -X --pic
veneer --build-id . Therefore, the final value of cmd_link-vmlinux is:

cmd_link-vmlinux = /bin/bash scripts/link-vmlinux.sh arm-linux-gnueabihf-ld -EL -p --noundefined -X --pic-veneer --build-id

3. vmliux_link function

cmd_link-vmlinux will call the scripts/link-vmlinux.sh script to link out vmlinux ! There is the following code in link-vmlinux.sh :
51 vmlinux_link()
52 {
53 local lds="${objtree}/${KBUILD_LDS}"
54
55 if [ "${SRCARCH}" != "um" ]; then
56 ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
57 -T ${lds} ${KBUILD_VMLINUX_INIT} \
58 --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1}
59 else
60 ${CC} ${CFLAGS_vmlinux} -o ${2} \
61 -Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \
62 -Wl,--start-group \
63 ${KBUILD_VMLINUX_MAIN} \
64 -Wl,--end-group \
65 -lutil ${1}
66 rm -f linux
67 fi
68 }
......
216 info LD vmlinux
217 vmlinux_link "${kallsymso}" vmlinux

vmliux_link is the function that ultimately links out vmlinux .
Line 55 determines whether SRCARCH is equal to " um ". If not, execute the code on lines 56~58 . Because SRCARCH=arm , the condition is established and the code in lines 56~58 is executed.
Lines 56 ~58: It is a normal link operation. The connection script is lds= ./arch/arm/kernel/vmlinux.lds . The files to be linked are determined by the variables KBUILD_VMLINUX_INIT and KBUILD_VMLINUX_MAIN .
Line 217 calls the vmlinux_link function to link out vmlinux .

When using the command " make V=1" to compile the Linux kernel source code, the following compilation information will appear :

This is the process of make . The focus is to link the built-in.o , .a and other files in each subdirectory together, and finally generate
vmlinux is an executable file in ELF format. The link script is arch/arm/kernel/vmlinux.lds , and the link process is
This is done by the shell script scripts/link-vmlinux.s .

おすすめ

転載: blog.csdn.net/wojiaxiaohuang2014/article/details/133152056