Linux system porting: Kernel top-level Makefile

Posted by jason97673 on Thu, 03 Mar 2022 14:59:28 +0100

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

Topics: Linux Makefile kernel