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.