天天看點

uboot建構架構8-built-in.o的編譯過程追蹤

找入口

追蹤的第一件事情,還是找入口,就跟看C代碼我們需要先找到main函數一樣。

我在《u-boot.bin生成過程追蹤》一文中提到了"u-boot-dirs"變量,這個變量展開之後,是一系列的目錄。然後這些目錄作為目标,有如下的生成規則:

PHONY += $(u-boot-dirs)
$(u-boot-dirs): prepare scripts
        $(Q)$(MAKE) $(build)[email protected]
           

u-boot-dirs展開是一系列目錄,如下:

arch/arm/cpu arch/arm/cpu/armv7 arch/arm/imx-common ......
           

我們以目錄"arch/arm/cpu"為例,将這個規則的指令行展開,得到:

$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj=arch/arm/cpu
           

這裡使用u-boot-dirs裡面的目錄作為obj的值,引入Makefile.build進行make建構。那麼建構built-in.o的規則應該就在這個Makefile裡面了。打開Makefile.build,第108行,有關于built-in.o的變量指派:

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

這裡,builtin-target指派為"arch/arm/cpu/built-in.o",這個builtin-target在第358行有一個對應規則:

#
# Rule to compile a set of .o files into one .o file
#
ifdef builtin-target
quiet_cmd_link_o_target = LD      [email protected]  
# If the list of objects to link is empty, just create an empty built-in.o
cmd_link_o_target = $(if $(strip $(obj-y)),\
                      $(LD) $(ld_flags) -r -o [email protected] $(filter $(obj-y), $^) \
                      $(cmd_secanalysis),\
                      rm -f [email protected]; $(AR) rcs$(KBUILD_ARFLAGS) [email protected])

$(builtin-target): $(obj-y) FORCE
        $(call if_changed,link_o_target)

targets += $(builtin-target)
endif # builtin-target
           

這裡的builtin-target規則,應該就是built-in.o的入口了。

展開規則

上面我們找到了built-in.o的入口,就是builtin-target對應的規則。這個規則依賴$(obj-y),obj-y變量實際上是Makefile.build裡面根據obj參數包含另外的Makefile帶進來的。見Makefile.build第59行:

include $(kbuild-file)
           

我們以上面"obj=arch/arm/cpu"為例,這裡的include就變成:

include ./arch/arm/cpu/Makefile
           

在這個被引入的Makefile裡面,根據配置定義了obj-y變量的值。

builtin-target規則的指令調用了if_changed函數,這個函數展開之後是cmd_link_o_target的值,見規則以上該變量的定義。我們将該變量做适當展開,如下:

$(LD) $(ld_flags) -r -o [email protected] $(filter $(obj-y), $^) $(cmd_secanalysis),rm -f [email protected]; $(AR) rcs$(KBUILD_ARFLAGS) [email protected]
           

其中cmd_secanalysis變量定義在135行,這個變量根據配置來定義,如果相應配置沒有選擇,則該變量為空。這裡我們以實際的例子看下這個指令是怎樣的:

arm-poky-linux-gnueabi-ld.bfd -r -o arch/arm/cpu/armv7/mx6/built-in.o arch/arm/cpu/armv7/mx6/soc.o arch/arm/cpu/armv7/mx6/clock.o
           

如上,調用了連結器ld,使用了-r選項,該選項使ld輸出可重定位檔案。連結器輸入為各個源代碼檔案編譯的目标檔案。

以上就是built-in.o檔案的建構過程,是不是感覺特别簡單?