A brief analysis of the linux kernel vmlinux generation process

I haven't been very busy at work recently, so I studied the compilation process of the Linux kernel, and I will briefly record it here.

$(obj)/zImage:  $(obj)/compressed/vmlinux FORCE
    $(call if_changed,objcopy)

The generation of linux kernel zImage depends on vmlinux.

The underlying makefile of the analysis kernel is as follows:

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

It is found that the generation of vmlinux mainly depends on vmlinux-deps.

export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y2) $(drivers-y) $(net-y) $(virt-y)
export KBUILD_VMLINUX_LIBS := $(libs-y1)
export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds

vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_LIBS)

KBUILD_LDS: is a link file
KBUILD_VMLINUX_MAIN: some libraries and drivers

Here we focus on analyzing KBUILD_VMLINUX_INIT

init-y		:= $(patsubst %/, %/built-in.o, $(init-y))
...
KBUILD_VMLINUX_INIT := $(head-y) $(init-y)

It can be seen that KBUILD_VMLINUX_INIT is the built-in.o file in each subdirectory.

So how did built-in.o come about?
View /scripts/Makefile.build file

ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),)
builtin-target := $(obj)/built-in.o
endif
...
$(builtin-target): $(obj-y) FORCE
	$(call if_changed,link_o_target)

The built-in.o in each directory depends on (obj-y), so far it is clear that $(obj-y) is the *.o file compiled from the source files in each directory.

Expansion:
When we add our own source code to the kernel and want it to be compiled into the kernel, we usually modify the makefile in the subdirectory like this

...
obj-y += myself_file.o
...

In the makefile, the order of $(obj-y) is also very important, which is the order in which the source code is compiled and linked into built-in.o . Therefore, some initialization functions (module_init() / _initcall) will be called according to the sequence at startup. Once the link sequence is changed, the initialization sequence of the device may also be changed, which will cause problems with system startup.

Guess you like

Origin blog.csdn.net/weixin_44698673/article/details/128845871