(1)決定編譯哪些文件
(2)怎樣編譯這些文件
(3)怎樣連接這些文件,最重要的是它們的順序如何
2.Linux內核Makefile分類
*********************************************************************
頂層Makefile:它是所有Makefile文件的核心,從總體上控制着內核的編譯、
連接
.config :配置文件,在配置內核時生成,所有Makefile文件(包括頂層
目錄及各級子目錄)都是根據.config來決定使用哪些文件
arch/$(ARCH)/Makefile:對應於體系結構的Makefile,它用來決定哪些體系結
構相關的文件參與內核的生成,並提供一些規則來生成
特定格式的內核映像
scripts/Makefile.* : Makefile共用的通用規則、腳本等
kbuild Makefile :各級子目錄下的Makefile,被上一層Makefile調用來編譯
當前目錄下的文件
*********************************************************************
3.根據Makefile的作用分析這5類文件
(1)決定編譯哪些文件
Linux內核的編譯過程從頂層Makefile開始,然后遞歸地進入各級子目錄調用它們的Makefile,分為3個步驟:
(1)頂層Makefile決定內核根目錄下哪些子目錄將被編譯進內核
在頂層Makefile中有如下內容:
init-y := init/
drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
......................
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
頂層Makefile將這13個子目錄分為5類,除去include目錄和后面不包
含內核源碼的目錄外,還有一個arch目錄在arch/$(ARCH)/Makefile中被包
含進內核,在頂層Makefile中直接包含了這個Makefile,如下所示:
452 include $(srctree)/arch/$(SRCARCH)/Makefile
(2)arch/$(ARCH)/Makefile決定arch/$(ARCH)目錄下哪些文件、哪些目錄將
被編譯進內核
在arch/arm/Makefile中有如下內容:
100 head-y := arch/arm/kernel/head$(MMUEXT).o
arch/arm/kernel/init_task.o
...............................................
196 core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
197 core-y += $(machdirs) $(platdirs)
198 core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
199 core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
200 core-$(CONFIG_VFP) += arch/arm/vfp/
...............................................
204 libs-y := arch/arm/lib/ $(libs-y)
第100行中MMUEXT在arch/arm/Makefile前面定義,對於沒有MMU的處
理器,使用文件head-nommu.S;對於有MMU的處理器,使用head.S文件
CONFIG_XXXX在配置內核時定義,它的值有3種:y、m或空
編譯內核時將依次進入init-y、core-y、libs-y、drivers-y和net-y
所列出的目錄中執行它們的Makefile,每個子目錄都會生成一個
built-in.o(libs-y所列的目錄下,有可能生成lib.a文件)。最后,head-y
所表示的文件將和這些built-in.o、lib.a一起被連接成內核映像文件
vmlinux
(3)各級子目錄下的Makefile決定所在目錄下哪些文件將被編譯進內核,哪
些文件將被編譯成模塊(驅動程序),進入哪些子目錄繼續調用它們的
Makefile
在配置內核時,生成配置文件“.config”,根據.config中定義的各
個變量決定編譯哪些文件,Makefile使用如下語句間接包含.config文
件(因為包含的是"include/config/auto.conf"文件):
486 -include include/config/auto.conf
在"include/config/auto.conf"文件中,變量的值為y或m
1)obj-y用來定義哪些文件被編進(built-in)內核
obj-y中定義的.o文件由當前目錄下的.c或.S文件編譯生成,
它們連同下級子目錄的built-in.o文件一起被組合成(使用
“$(LD)-R”命令)當前目錄下的built-in.o文件,這個built-in.o
文件被它的上一層Makefile使用
2)obj-m用來定義哪些文件被編譯成可加載模塊(Loadable module)
obj-m中定義的.o文件由當前目錄下的.c或.S文件編譯生成,
它們被編譯成模塊,一個模塊可以由一個或幾個.o文件組成,對於
有多個源文件的模塊,除在obj-m中增加一個.o文件外,還要定義
一個<module_name>-objs變量來告訴Makefile這個.o文件由哪些
文件組成
例如:
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
3)lib-y用來定義哪些文件被編成庫文件
liy-y中定義的.o文件由當前目錄下的.c或.S文件編譯生成,
它們被打包成當前目錄下的一個庫文件:lib.a ;同時出現在
obj-y和lib-y中的.o文件,不會被包含進lib.a中,要把這個
lib.a編譯進內核中,需要在頂層Makefile中libs-y變量中列出
當前目錄
4)obj-y、obj-m還可以指定要進入的下一層子目錄
obj-$(CONFIG_JFFS2_FS) += jffs2/
(2)怎樣編譯這些文件----編譯選項、連接選項是什么
這些選項可分為3類:
1)全局的
適用於整個內核代碼,在頂層Makefile和arch/$(ARCH)/Makefile中
定義,這些選項的名稱為CFLAGS(編譯C文件的 選項)、AFLAGS(編譯匯編
文件的選項)、LDFLAGS(連接文件的選項)、 ARFLAGS(制作庫文件的選項)
2)局部的
在各個子目錄中定義,針對當前Makefile中的所有文件,名稱分別
為:EXTRA_CFLAGS、EXTRA_AFLAGS、EXTRA_LDFLAGS、EXTRA_ARFLAGS
3)個體的
僅適用於某個文件,如果想針對某個文件定義它的編譯選項,可以使
用CFLAGS_$@, AFLAGS_$@,前者用於編譯某個C文件,后者用於編譯某
個匯編文件。$@表示某個目錄文件
(3)怎樣連接這些文件,它們的順序如何
在頂層Makefile中,目錄名的后面直接加上built-in.o或lib.a,表示
要連接進內核的文件,如下所示:
init-y := $(patsubst %/, %/built-in.o, $(init-y))
core-y := $(patsubst %/, %/built-in.o, $(core-y))
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
net-y := $(patsubst %/, %/built-in.o, $(net-y))
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
patsubst是個字符串處理函數,它的用法如下:
$( patsubst pattern, replacement, text)
表示尋找“text”中符合格式“pattern”的字,用“replacement”代替
它們,比如init-y的初值為“init/”,經過變換后變為“init/built-in.o”
再如下所示:
vmlinux-init := $(head-y) $(init-y)
vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)
vmlinux-all := $(vmlinux-init) $(vmlinux-main)
vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds
vmlinux-all表示所有構成映象文件vmlinux的目標文件,可知這些目標文件的順序為head-y、init-y、core-y、libs-y、drivers-y、net-y
4.總結
(1)配置文件.config中定義了一系列的變量,Makefile將結合它們來決定哪些
文件被編譯進內核、哪些文件被編譯成模塊、涉及哪些子目錄
(2)頂層Makefile和arch/$(ARCH)/Makefile決定根目錄下哪些子目錄、
arch/$(ARCH)目錄下哪些文件和目錄將被編譯進內核
(3)各級子目錄下的Makefile決定所在目錄下的哪些文件將被編譯進內核,哪些
文件被編譯成模塊(即驅動程序),進入哪些子目錄繼續調用它們的Makefile
(4)頂層Makefile和arch/$(ARCH)/Makefile設置了可以影響所有文件的編譯、
連接選項,即全局選項
(5)各級子目錄下的Makefile中可以設置影響當前目錄下所有文件的編譯、連接
選項,即局部選項
(6)頂層Makefile按照一定的順序組織文件,根據連接腳本arch/$(ARCH)
kernel/vmlinux.lds生成內核映象文件vmlinux