Linux Makefile分析-vmlinux產生

來源:互聯網
上載者:User
1, 頂層Makefile跟蹤:

找到vmlinux目標 

# vmlinux image - including updated kernel symbols

vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE

ifdef CONFIG_HEADERS_CHECK

         $(Q)$(MAKE) -f $(srctree)/Makefile headers_check

endif

         $(call if_changed_rule,vmlinux__)

         $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@

         $(Q)rm -f .old_version

         @echo "========================vmlinux============================"

         @echo $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o)

         @cp vmlinux vmlinux.full

找到vmlinux-init:

vmlinux-init := $(head-y) $(init-y)

head-y是和機器有關的變數,定義在arch內的Makefile裡:

head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o

這個是通過include $(srctree)/arch/$(SRCARCH)/Makefile 包含這個Makefile的。

init-y定義在本Makefile:

init-y        := init/

...

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

最終結果就是:

init-y := init/built-in.o。這個build-in.o這個中間檔案可能聽說過,其實這個檔案就是有這個目錄下所有obj-y來合成的。

此外,下面兩變數自己找一下:

vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)

vmlinux-lds  := arch/$(ARCH)/kernel/vmlinux.lds

vmlinux-dirs

還要注意一下,下面這句:

$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;

這句在執行vmlinux目標前由依賴關係產生,我們來看看最關鍵的vmlinux-dirs。

vmlinux-dirs    := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \

              $(core-y) $(core-m) $(drivers-y) $(drivers-m) \

              $(net-y) $(net-m) $(libs-y) $(libs-m)))

其實$(vmlinux-dirs)還是一個目標。

PHONY += $(vmlinux-dirs)

 $(vmlinux-dirs): prepare scripts

     $(Q)$(MAKE) $(build)=$@

用到了Makefile.kbuild規則。將vmlinux-dirs裡面的目錄進行了遞迴處理產生出那些.o的檔案,特別是build-in.o, 在執行vmlinux時候,$(vmlinux-dirs)目標肯定會先得到執行。


連結得到vmlinux

在哪裡連結的,看看 endif後面:

         $(call if_changed_rule,vmlinux__)

         $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@

$(call if_changed_rule,vmlinux__)會調用rule_vmlinux_,即下面內容:

# Link of vmlinux

# If CONFIG_KALLSYMS is set .version is already updated

# Generate System.map and verify that the content is consistent

# Use + in front of the vmlinux_version rule to silent warning with make -j2

# First command is ':' to allow us to use + in front of the rule

define rule_vmlinux__

         :

         $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version))

         $(call cmd,vmlinux__)

         $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd

         $(Q)$(if $($(quiet)cmd_sysmap),                                      \

           echo '  $($(quiet)cmd_sysmap)  System.map' &&)                     \

         $(cmd_sysmap) $@ System.map;                                         \

         if [ $$? -ne 0 ]; then                                               \

                   rm -f $@;                                                    \

                   /bin/false;                                                  \

         fi;

         $(verify_kallsyms)

endef

在這上面有命令vmlinux__, _vmlinux_version和sysmap定義, 其中vmlinux_命令中有LD的連結產生vmlinux.

# Rule to link vmlinux - also used during CONFIG_KALLSYMS

# May be overridden by arch/$(ARCH)/Makefile

quiet_cmd_vmlinux__ ?= LD      $@

      cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \

      -T $(vmlinux-lds) $(vmlinux-init)                          \

      --start-group $(vmlinux-main) --end-group                  \

      $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^)

# Generate new vmlinux version

quiet_cmd_vmlinux_version = GEN     .version

      cmd_vmlinux_version = set -e;                     \

         if [ ! -r .version ]; then                         \

           rm -f .version;                                   \

           echo 1 >.version;                             \

         else                                                \

           mv .version .old_version;                       \

           expr 0$$(cat .old_version) + 1 >.version;    \

         fi;                                                    \

         $(MAKE) $(build)=init

# Generate System.map

quiet_cmd_sysmap = SYSMAP

      cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap

2. Makefile.kbuild規則:

       $(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build  \

        obj =$(vmlinux-dirs)

找到目標__build:

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

        $(if $(KBUILD_MODULES),$(obj-m)) \

        $(subdir-ym) $(always)

       @:

因為KBUILD_BUILTIN在頂層Makefile中被初始化為1,所以這個規則的依賴有一個builtin-target變數:

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

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

endif

變數obj就是vmlinux-dirs變數指定的目錄。所以這裡會構建$(vmlinux-dirs)/built-in.o目標:

ifdef builtin-target

quiet_cmd_link_o_target = LD      $@

# 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 $@ $(filter $(obj-y), $^),\

                    rm -f $@; $(AR) rcs $@)

上面由obj-y指定的.o,產生$(vmlinux-dirs)/built-in.o.

$(builtin-target): $(obj-y) FORCE

       $(call if_changed,link_o_target)

下麵包含了vmlinux-dirs變數指定目錄中的Makefile檔案,在這些makefile檔案中會指定obj-y變數,它指定的都是一些*.o目標檔案,

kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))

include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)

這些*.o檔案的產生方法由scripts/Makefile.build檔案的模式規則指定

%.o: %.c FORCE

       $(call cmd,force_checksrc)

       $(call if_changed_rule,cc_o_c)

上面會產生obj-y指定的.o

通過上面這一系列的步驟,就編譯連結出由變數vmlinux-init指定的目標,vmlinux-main變數指定的目標的構建與此類似.

天行健,君子當自強不息

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.