This article will continue to explain the generation process of arm linux kernel zImage, kernel version number 4.10. In the arch/arm/Makefile file, you can see that zImage depends on vmlinux, where vmlinux refers to the vmlinux in the root directory. arch/arm/Makefile: boot := arch/arm/boot BOOT_TARGETS = zImage Image xipImage bootpImage uImage … … $(BOOT_TARGETS):vmlinux $(Q)$(MAKE) $(build)=$(boot)MACHINE=$(MACHINE) $(boot)/$ @ -- (1 ) @$(kecho) ' Kernel: $(boot)/$@ is ready' Here vmlinux is the elf file of the compiled linux kernel: #file vmlinux vmlinux: ELF 32-bitLSB executable, ARM, version 1 (SYSV), statically linked, not stripped Among them, (build)=$(boot) is expanded to scripts/Makefile.build obj=arch/arm/boot. build is a variable defined in scripts/Kbuild.include: build := -f$(srctree)/scripts/Makefile.build obj boot := arch/arm/boot directly specifies the boot file generation path of the architecture, while MACHINE is determined by user configuration, after all, an ARM CPU can form different machine architectures with various peripherals. ifneq ($(machine-y),) MACHINE := arch/arm/mach-$(word 1,$(machine-y))/ else MACHINE := endif For example: machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 You can find CONFIG_ARCH_S3C64XX=y in the kernel configuration file .config. In this way, statement (1) can be parsed into: make -fscripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/mach-s3c6400/arch/arm/boot/zImage Next, look at scripts/Makefile.build. The way it includes the arch/arm/boot/Makefile file is somewhat special. It gets obj from the above command line, then finds the Makefile in the corresponding folder and executes it. At the beginning of scripts/Makefile.build, the value of src is assigned to arch/arm/boot: src := $(obj)… … # The filename Kbuild has precedence over Makefile kbuild-dir := $(if $(filter /%, $(src)), $(src), $(srctree)/$(src)) kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)include$(kbuild-file)kbuild-file is the Makefile file in the path specified by src, which is arch/arm/boot/Makefile, which contains the rules for building arch/arm/boot/zImage. PHONY := __build… …__build: $(if$(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \ KBUILD_BUILTIN is initialized to 1 in the top-level Makefile, so this rule's dependency requires a builtin-target variable. This variable is defined in scripts/Makefile.build. ifneq ($(strip$(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),) builtin-target := $(obj)/built-in.o endif The variable obj is the directory specified by the vmlinux-dirs variable. So the $(vmlinux-dirs)/built-in.o target will be built here. The rules and commands for this target are defined in the scripts/Makefile.build file: # If the list of objects to link is empty, just create an empty built-in.o cmd_link_o_target =$(if $(strip $(obj-y)),\$(cmd_make_builtin) $@$(filter $(obj-y), $^) \$(cmd_secanalysis),\$(cmd_make_empty_builtin)$@)$(builtin-target):$(obj-y) FORCE $(call if_changed,link_o_target) vmlinux-dirs will be explained later, it contains all the folders represented by the variable$(xx) that need to be compiled. All target file generation rules are defined in scripts/Makefile.build as follows: # Built-in and composite module parts $(obj)/%.o:$(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE $(call cmd,force_checksrc) $(call if_changed_rule,cc_o_c) After vmlinux is generated, make -fscripts/Makefile.build will be executed next. The following rules are defined in arch/arm/boot/Makefile: $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) The value of the variable obj is arch/arm/boot. Obviously, zImage depends on $(obj)/compressed/vmlinux at this time. $(obj)/compressed/vmlinux:$(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed$@ The expanded command is as follows: make -f scripts/Makefile.buildobj=arch/arm/boot/compressedarch/arm/boot/compressed/vmlinux Continue to return to the compressedvmlinux generation command,make -f scripts/Makefile.build obj=arch/arm/boot/compressed arch/arm/boot/compressed/vmlinux. At this timeobj=arch/arm/boot/compressed, soscripts/Makefile.build will automatically includearch/arm/boot/compressed/Makefile, which specifies the generation rules ofarch/arm/boot/compressed/vmlinux. arch/arm/boot/compressed/Makefile: $(obj)/vmlinux:$(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o \ $(addprefix $(obj)/, $(OBJS))$(lib1funcs) $(ashldi3) \ $(bswapsdi2) $(efi-obj-y) FORCE @$(check_for_multiple_zreladdr) $(call if_changed,ld) @$(check_for_bad_syms) The first of these two rules is to compress the Image generated by vmlinux objcopy to generate piggy.gz, and then generate piggy.o. The cmd_ld command is defined in the scripts/Makefile.lib file: quiet_cmd_ld = LD $@ cmd_ld = $(LD)$(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \ $(filter-out FORCE,$^) -o $@ Here the arch/arm/boot/compressed/vmlinux file is generated according to the link script arch/arm/boot/compressed/vmlinux.lds. Then in the arch/arm/boot/Makefile rule: $(obj)/zImage:$(obj)/compressed/vmlinux FORCE$(callif_changed,objcopy) In this way, the final zImage is generated after objcopy processing.lib file definition: quiet_cmd_ld =LD $@ cmd_ld = $(LD)$(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \ $(filter-out FORCE,$^) -o $@ Here the arch/arm/boot/compressed/vmlinux file is generated according to the link script arch/arm/boot/compressed/vmlinux.lds. Then in the arch/arm/boot/Makefile rule: $(obj)/zImage:$(obj)/compressed/vmlinux FORCE$(callif_changed,objcopy) In this way, the final zImage is generated after objcopy processing.lib file definition: quiet_cmd_ld =LD $@ cmd_ld = $(LD)$(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \ $(filter-out FORCE,$^) -o $@ Here the arch/arm/boot/compressed/vmlinux file is generated according to the link script arch/arm/boot/compressed/vmlinux.lds. Then in the arch/arm/boot/Makefile rule: $(obj)/zImage:$(obj)/compressed/vmlinux FORCE$(callif_changed,objcopy) In this way, the final zImage is generated after objcopy processing.
|