linux核心學習(8)如何產生vmlinux?簡單走走

來源:互聯網
上載者:User

 我們應該瞭解,核心編譯出vmlinux還不算數,最後這個ELF格式的檔案會被壓縮成bzImage。不過那無關緊要。這次我要說說vmlinux的產生流程,當然只是簡單走走,裡面kbuild複雜文法,連Makefile內建的很多規則都是比較複雜的,恐怕要全部搞懂,得費很大勁,畢竟這對於我研究的方向沒有多大協助。我們知道要產生可執行檔要經過這樣幾個步驟:xx.c->xx.o、xx.o->xx,即先編譯在連結,最終xx就是我們要的檔案,那麼核心原始碼怎麼有序的形成這樣的模式呢,靠的就是kbuild這個了不起的架構模型。

當然第一步找到vmlinux目標。

vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE
ifdef CONFIG_HEADERS_CHECK
    $(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
ifdef CONFIG_SAMPLES
    $(Q)$(MAKE) $(build)=samples
endif
ifdef CONFIG_BUILD_DOCSRC
    $(Q)$(MAKE) $(build)=Documentation
endif
    $(call vmlinux-modpost)
    $(call if_changed_rule,vmlinux__)
    $(Q)rm -f .old_version

這個目標依賴的還挺多的,不過這裡我只關注2個:vmlinux-init、vmlinux-main。可以看出前面兩個是變數。只分析一個即可。
找到vmlinux-init。

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

這裡又有兩個變數:head-y、init-y。有些熟悉,有點類似obj-y、obj-m等吧。通過尋找,我沒找到啊,當然這個Makefile是沒有了,這個是和機器有關的變數,在這行上面不遠處,有包含:

include $(srctree)/arch/$(SRCARCH)/Makefile

現在應該很熟悉了吧,無非就是將關於機器的那個Makefile給包含進來,這裡以x86為例。找到head-y的蹤影。

head-y := arch/x86/kernel/head_$(BITS).o
head-y += arch/x86/kernel/head$(BITS).o
head-y += arch/x86/kernel/head.o
head-y += arch/x86/kernel/init_task.o

好了,怎麼找,應該知道了。不過這裡還來看看init-y會發現和head-y有些不同。至於像.o這些檔案怎麼產生的,後面會看到。

init-y        := init/

這是第一次定義,但是別太慌,下面還有。

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

這句話翻譯一下就是 init-y := init/built-in.o。這個build-in.o這個中間檔案可能聽說過,其實這個檔案就是有這個目錄下所有obj-y來合成的。當然會用到遞迴調用的方式,不過怎麼個遞迴法不是我要探討的問題,我只需要找到在哪裡開始的就ok。好了,vmlinux-init基本就可以確定了,下面的vmlinux-main類似方式可以確定。我在來說說比較關鍵的一個問題,build-in.o是在哪條命令中產生,因為我們知道肯定得涉及kbuild規則遞迴調用才能做到。其實要知道這個在哪裡產生的確得看些東西才能找到,不過這裡我只是簡單說說就可以了。知道這句話就可以了。

$(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
如果不瞭解一些常識,誰會注意到sort那句話就是幹這事情的。所以在執行vmlinux時候,$(vmlinux-dirs)目標肯定會先得到執行,現在該有的都有了,vmlinux-init、vmlinux-main,關鍵的內容都來,最後執行連結即可得到vmlinux,在哪裡連結的,看看endif後面那3條。

endif
    $(call vmlinux-modpost)
    $(call if_changed_rule,vmlinux__)
    $(Q)rm -f .old_version

第一條就是調用一下vmlinux-modpost,這個其實也是個命令,只不過是自訂的。尋找一下,在上面。

quiet_cmd_vmlinux-modpost = LD      $@
      cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@                          /
     $(vmlinux-init) --start-group $(vmlinux-main) --end-group             /
     $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^)
define rule_vmlinux-modpost
    :
    +$(call cmd,vmlinux-modpost)
    $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
    $(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd
endef

發現沒有,既定義了命令還定義了規則,$(LD)就是連結了。呵呵,說得夠簡單的,說到這裡發現,整個過程竟然如此簡單,但是要分析到這些得看很多內容的,發現我搞2天呢。呵呵,不還是蠻值得的。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.