Linux 3.6內核編譯vmlinux,bzImage

Tips1:在根目錄中的Makfile中include了2次目標體系結構下的Makefile文件

第一次:

481 include $(srctree)/arch/$(SRCARCH)/Makefile
482 export KBUILD_DEFCONFIG KBUILD_KCONFIG

由註釋可知,此處讀取具體體系結構下的Makefile是爲了設置KBUILD_DEFCONFIG.用於如果make時使用參數defconfig。

556 all: vmlinux

如果在make時沒有給定參數,這個all就是默認final goal。但是它會被具體體系結構下的目標覆蓋。也就是說它並不是我們的終極目標。


第二次include具體體系結構下的Makefile文件

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

在該文件中:

150 all: bzImage
155 bzImage: vmlinux

這裏關係到GNU Make的知識,如果出現了相同的target,那麼後面的target將會把前面的覆蓋,並且執行後面一個的依賴和命令。所以這裏發生兩次覆蓋,首先,556行的vmlinux覆蓋了在482行include中帶入的bzImage,而在564include後,bzImage又作爲final goal覆蓋了vmlinux。回到第一次註釋,那裏include具體體系結構下的Makefile就是爲了設置參數而已。

最終確定final goal是第二次include。它一定要在all: vmlinux之後。


ps:再看一眼155行,其實bzImage是依賴於vmlinux的。於是,接下來,tips。看看vmlinux


Tips2:vmlinux的依賴(逆着退,只看看vmlinux的直接依賴)

751 vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE

依賴:

743 vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)

依賴:

738 export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
 739 export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)
 740 export KBUILD_LDS          := arch/$(SRCARCH)/kernel/vmlinux.lds

這裏使用export是爲了讓這些變量外部可見,給scripts/link-vmlinux.sh用的

依賴:

 729 init-y          := $(patsubst %/, %/built-in.o, $(init-y))
 730 core-y          := $(patsubst %/, %/built-in.o, $(core-y))
 731 drivers-y       := $(patsubst %/, %/built-in.o, $(drivers-y))
 732 net-y           := $(patsubst %/, %/built-in.o, $(net-y))
 733 libs-y1         := $(patsubst %/, %/lib.a, $(libs-y))
 734 libs-y2         := $(patsubst %/, %/built-in.o, $(libs-y))
 735 libs-y          := $(libs-y1) $(libs-y2)

由patsubst函數後,將init-y等內容中本來由/結尾的文件都變成了/built-in.o的文件了。

其中head-y是定義在體系結構相關的Makefile中的。在其中也對core-y,drivers-y進行了修改。

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

對於init-y,core-y,drivers-y,libs-y依賴於:

 506 init-y          := init/
 507 drivers-y       := drivers/ sound/ firmware/
 508 net-y           := net/
 509 libs-y          := lib/
 510 core-y          := usr/

在x86/Makefile中的修改:

161 libs-y  += arch/x86/lib/
162 
163 # See arch/x86/Kbuild for content of core part of the kernel
164 core-y += arch/x86/
165 
166 # drivers-y are linked after core-y
167 drivers-$(CONFIG_MATH_EMULATION) += arch/x86/math-emu/
168 drivers-$(CONFIG_PCI)            += arch/x86/pci/
169 
170 # must be linked after kernel/
171 drivers-$(CONFIG_OPROFILE) += arch/x86/oprofile/
172 
173 # suspend and hibernation support
174 drivers-$(CONFIG_PM) += arch/x86/power/
175 
176 drivers-$(CONFIG_FB) += arch/x86/video/

小結:

vmlinux直接依賴於

(1)arch/x86/kernel/vmlinux.lds

(2)arch/x86/kernel/head32.o,arch/x86/kernel/head_32.o,arch/x86/kernel/head.o以及

init,usr,kernel,mm,fs,ipc,security,crypto,block,arch/x86,drivers,sound,firmware,net,lib,arch/x86/lib,arch/x86/oprofile,arch/x86/power,arch/x86/video目錄下的/build-in.o文件,/lib.a文件

(3)以及一個shell腳本scripts/link-vmlinux.sh在kernel 2.26版本中沒有該腳本,它所要完成的任務就鏈接起上述文件形成vmlinux)


Tips3:確定目標代碼的運行平臺(ARCH)。即設置SRCARCH的過程。逆向尋找

在根目錄的Makefile中

200 SRCARCH         := $(ARCH)

195 ARCH            ?= $(SUBARCH)

//arch可以來自make的參數行(包括環境變量的設置),如果沒有,就來自SUBARCH

 168 SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
 169                                   -e s/arm.*/arm/ -e s/sa110/arm/ \
 170                                   -e s/s390x/s390/ -e s/parisc64/parisc/ \
 171                                   -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
 172                                   -e s/sh[234].*/sh/ )

這條命令的作用,開啓一個shell進程,執行uname -m命令。輸出主機的硬件架構名稱。再用後面的sed命令進行篩選,比如

sed -e s/i.86/i386表示,只要硬件架構是某86,都給它叫做i386.

所以SRCARCH在200行之前就確定了。看下tip1中,include具體體系結構下的Makefile,發生在400+行,此時這個SRCARCH變量已經被正確賦值了。



發佈了38 篇原創文章 · 獲贊 9 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章