Linux system transplantation: Kernel top-level Makefile (Part 2)
Continue to analyze the top-level Makefile execution process of Linux kernel source code
1, make defconfig procedure
Like the top-level makefile of uboot, make XXX should be used before compiling the source code_ Defconfig configures the Linux kernel, and the code configures it first
- config-targets
- mixed-targets
- dot-config
These three parameters
After this code is executed, the value changes as follows:
config-targets= 1 mixed-targets= 0 dot-config= 1
The following code is executed according to these three values. The execution code of config targets = 1 is as follows:
This code mainly refers to the file arch/arm/Makefile (zImage, uImage and other files are generated by arch/arm/Makefile), and then exports KBUILD_DEFCONFIG,KBUILD_KCONFIGļ¼
Then, because "% config" matches the previous one, execute the following code and "% config" depends on scripts_basic, outputmakefile and FORCE
scripts_ The basic code is as follows:
Build is defined in the file scripts / kbuild In include, the value is build: = - f $(srctree) / scripts / makefile build obj
Expansion is:
scripts_basic: make -f ./scripts/Makefile.build obj=scripts/basic rm -f . tmp_quiet_recordmcount
Therefore, the following command to expand% config is:
make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
Compile xxx_defconfig
2, Makefile Build script analysis
Therefore, two scripts will eventually be executed in one
#scripts_basic depends on the execution of make -f ./scripts/Makefile.build obj=scripts/basic #%config executed make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
They all executed makefile Build this script, the two makefiles Build execution has different effects:
scripts_ The purpose of basic is to compile scripts/basic/fixdep and scripts/basic/bin2c
The second line of code matches the expanded code below
%_defconfig: scripts/kconfig/conf scripts/kconfig/conf --defconfig=arch/arm/configs/%_defconfig Kconfig
The code depends on scripts/kconfig/conf, which will compile scripts/kconfig/conf.c to generate conf software, which will%_ The configuration in defconfig is output to config file, and finally generate the file under the root directory of Linux kernel config file
3, make process
Enter make to compile all by default. The code is as follows:
Then all depends on vmlinux
Vmlinux relies on scripts / link vmlinux SH $(vmlinux DEPs) force, vmlinux DEPs is defined as follows:
vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)
The parameters are defined in the front
KBUILD_VMLINUX_INIT= $(head-y) $(init-y) KBUILD_VMLINUX_MAIN = $(core-y) $(libs-y) $(drivers-y) $(net-y) KBUILD_LDS= arch/$(SRCARCH)/kernel/vmlinux.lds
Where SRCARCH=arm, so the actual dependency of vmlinux is:
scripts/link-vmlinux.sh,$(head-y) ,$(init-y),$(core-y) ,$(libs-y) ,$(drivers-y) ,$(net-y),arch/arm/kernel/vmlinux.lds and FORCE
- head-y
It is defined in the file arch/arm/Makefile
head-y := arch/arm/kernel/head$(MMUEXT).o
If MMU is not enabled, MMUEXT=-nommu. If MMU is enabled, it is empty and enabled here
- init-y,drivers-y,net-y
These three parameters are defined as follows:
The three parameters are brought in as follows:
init-y = init/built-in.o drivers-y = drivers/built-in.o sound/built-in.o firmware/built-in.o net-y = net/built-in.o
- libs-y
Relevant codes are as follows:
libs-y := lib/ ...... libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y)) libs-y := $(libs-y1) $(libs-y2)
Under the arch/arm/Makefile file:
libs-y := arch/arm/lib/ $(libs-y)
So the final value of libs-y is as follows:
libs-y = arch/arm/lib/lib.a lib/lib.a arch/arm/lib/built-in.o lib/built-in.o
- core-y
The top-level Makefile has the following code
core-y := usr/ ... core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
Append core-y in arch/arm/Makefile
The code adds different values to core-y according to different configurations. If VFP is enabled, it will be displayed in Config in CONFIG_VFP=y, then arch/arm/vfp will be added to core-y/
Then the code behind the makefile is appended
core-y := $(patsubst %/, %/built-in.o, $(core-y))
If config is enabled_ VFP, the final parameters are as follows:
core-y = usr/built-in.o arch/arm/vfp/built-in.o \ arch/arm/vdso/built-in.o arch/arm/kernel/built-in.o \ arch/arm/mm/built-in.o arch/arm/common/built-in.o \ arch/arm/probes/built-in.o arch/arm/net/built-in.o \ arch/arm/crypto/built-in.o arch/arm/firmware/built-in.o \ arch/arm/mach-imx/built-in.o kernel/built-in.o\ mm/built-in.o fs/built-in.o \ ipc/built-in.o security/built-in.o \ crypto/built-in.o block/built-in.o
These variables are built in O or a and other files, compile the source code files in the corresponding directory, and generate build in O files, some generated a library files, and finally these built-in O and a file can be linked to form an executable file in ELF format, that is, vmlinux. The link file is arch / arm / kernel / vmlinux LDS, the linking process is controlled by the shell script scripts / link vmlinux SH to complete
4, Build in O file compilation and generation process
In the previous section, we know build in O and The a library file is provided by link vmlinux After the SH file is linked, vmlinux is generated. Let's take a look at build in O how to compile the generated
Because vmliux relies on vmlinux DEPs,
vmlinux-deps= $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)
KBUILD_LDS is a link script, KBUILD_VMLINUX_INIT and KBUILD_VMLINUX_MAIN is built-in. Under each subdirectory o,. A document, the final value is as follows:
makefile has a function to sort the string list of vmlinux DEPs and remove duplicate words. The function depends on vmlinux dirs
(sort $(vmlinux-deps)): $(vmlinux-dirs)
Vmlinux dirs is a key parameter
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \ $(core-y) $(core-m) $(drivers-y) $(drivers-m) \ $(net-y) $(net-m) $(libs-y) $(libs-m)))
Save parameters as follows:
At the same time, the top-level Makefile has the following code:
Vmlinux dirs relies on prepare and scripts, and then executes
make -f ./scripts/Makefile.build obj=$@
It is this function that brings all these directories in vmlinux dirs into the command and compiles them o documents
5, make zImage procedure
In addition to vmlinux mentioned above, there are several important files. Please briefly explain them:
-
vmlinux:
Vmlinux is the most original kernel file compiled, which has not been compressed. For example, the Linux source code provided by punctual atom, the compiled vmlinux is almost 16MB
-
Image:
Image is a Linux kernel image file that contains only executable binary data. It is obtained by canceling some other information in vmlinux using objcopy
-
zImage:
zImage is the gzip compressed Image
-
uImage:
uImage is a download image file used by the old version of uboot. uImag adds a header with a length of 64 bytes in front of zImage. This header describes the type, loading location, generation time, size and other information of the image file. At present, the new uboot supports zImage startup, so uImage is no longer needed
The following code is available in arch/arm/Makefile
Variable BOOT_TARGETS outputs zImage, Image, xipImage and other Image files, which depend on vmlinux. The specific compilation instructions are expanded as follows:
make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/zImage
With the help of scripts / makefile The build file completes the conversion from vmlinux to zImage