Arm linux 內核構建(2)

本文將繼續講解arm linux內核zImage的生成過程,內核版本號4.10。linux

 

在arch/arm/Makefile文件中,能夠看到zImage 依賴於vmlinux,這裏的vmlinux指的是根目錄下的vmlinux。架構

 

arch/arm/Makefile:ui

boot := arch/arm/boot命令行

BOOT_TARGETS    = zImage Image xipImage bootpImage uImageip

… …get

$(BOOT_TARGETS):vmlinuxcmd

    $(Q)$(MAKE) $(build)=$(boot)MACHINE=$(MACHINE) $(boot)/$@  --(1)it

 @$(kecho) ' Kernel: $(boot)/$@ is ready'io

 

這裏的vmlinux是編譯生成的linux內核的elf文件:編譯

#file vmlinux

vmlinux: ELF 32-bitLSB executable, ARM, version 1 (SYSV), statically linked, not stripped

 

其中,(build)=$(boot)被擴展爲了scripts/Makefile.build obj=arch/arm/boot。

build是scripts/Kbuild.include中定義的變量:

build := -f$(srctree)/scripts/Makefile.build obj

 

boot := arch/arm/boot 直接指明該架構的boot文件生成路徑,而MACHINE則是由用戶配置來決定,嵌入式物聯網更多資料企鵝意義氣嗚嗚吧久零就易,畢竟一個ARM CPU能夠和各種外設組成不一樣的機器架構。

ifneq ($(machine-y),)

MACHINE  := arch/arm/mach-$(word 1,$(machine-y))/

else

MACHINE  :=

endif

 

好比:

machine-$(CONFIG_ARCH_S3C64XX)    := s3c6400 s3c6410

在內核配置文件.config能夠找到CONFIG_ARCH_S3C64XX=y。

這樣,語句(1)就能夠解析成:

make -fscripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/mach-s3c6400/arch/arm/boot/zImage

 

接着看scripts/Makefile.build,它包含arch/arm/boot/Makefile文件的方式有些特殊,它是從上面的命令行獲得obj,而後找到對應文件夾下的Makefile並執行。

在scripts/Makefile.build的開頭,src的值被賦值爲arch/arm/boot:

src := $(obj)

… …

# The filename Kbuildhas 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就是src指定路徑下的Makefile文件,此時就是arch/arm/boot/Makefile,它包含了構建arch/arm/boot/zImage的規則。

PHONY := __build

… …

__build: $(if$(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \

 

KBUILD_BUILTIN 在頂層Makefile 中被初始化爲1,因此這個規則的依賴須要一個builtin-target 變量。

這個變量在scripts/Makefile.build中定義。

ifneq ($(strip$(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),)

builtin-target := $(obj)/built-in.o

endif

 

變量obj 就是vmlinux-dirs 變量指定的目錄。因此這裏會構建$(vmlinux-dirs)/built-in.o 目標,在scripts/Makefile.build文件中有這個目標的規則及命令的定義:

# If the list ofobjects 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將在後面解釋,它包含了全部由變量$(xx)表明的須要編譯處理的文件夾。全部的目標文件生成規則在scripts/Makefile.build中定義以下:

# Built-in andcomposite module parts

$(obj)/%.o:$(src)/%.c $(recordmcount_source) $(objtool_obj) FORCE

        $(call cmd,force_checksrc)

        $(call if_changed_rule,cc_o_c)

 

vmlinux在生成完畢後,接着會執行make -fscripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/mach-s3c6400/arch/arm/boot/zImage。arch/arm/boot/Makefile中定義了以下規則:

 $(obj)/zImage:  $(obj)/compressed/vmlinux FORCE

        $(call if_changed,objcopy)

 

變量obj的值便是arch/arm/boot。顯然zImage此時又依賴於$(obj)/compressed/vmlinux。

$(obj)/compressed/vmlinux:$(obj)/Image FORCE

        $(Q)$(MAKE) $(build)=$(obj)/compressed$@

 

擴展開的命令以下:

make -f scripts/Makefile.buildobj=arch/arm/boot/compressed

arch/arm/boot/compressed/vmlinux

 

繼續回到壓縮vmlinux生成命令,make -f scripts/Makefile.build obj=arch/arm/boot/compressed arch/arm/boot/compressed/vmlinux。

此時obj=arch/arm/boot/compressed,因此scripts/Makefile.build會自動包含arch/arm/boot/compressed/Makefile,該文件指明瞭arch/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)

 

這兩個規則的第一個就是把由vmlinux 進行objcopy生成的Image進行壓縮生成piggy.gz,而後生成piggy.o。cmd_ld 命令在scripts/Makefile.lib 文件定義:

quiet_cmd_ld =LD      $@

cmd_ld = $(LD)$(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \

              $(filter-out FORCE,$^) -o $@


這裏根據連接腳本arch/arm/boot/compressed/vmlinux.lds 連接生成了arch/arm/boot/compressed/vmlinux文件。而後在arch/arm/boot/Makefile規則中:

$(obj)/zImage:$(obj)/compressed/vmlinux FORCE

$(callif_changed,objcopy)

這樣,通過objcopy處理後便生成了最終的zImage。

相關文章
相關標籤/搜索