內核Makefile的框架
<linux2.6.xx>
---------------------->
|
|- Makefile
|
|- .config
|
|- arch
| |- $(ARCH)
| |- Makefile
|
|- scripts
| |- Makefile.*
|
|- <almost each directory>
| |- kbuild Makefile
# 頂層Makefile
根據內核配置文件,通過(guò)向下訪(fǎng)問(wèn)makefile的方式,制作內核文件vmlinux與模塊文件。
# .config
有內核配置程序所生成。
# arch/$(ARCH)/Makefile
向頂層Makefile提供硬件架構的特別信息,與對象機器硬件架構對應的Makefile會(huì )被頂
層Makefile所包含。
# scripts/Makefile.*
包含用于編譯內核的kbuild Makefile規則。
# kbuild Makefile
執行上層Makefile傳遞下來(lái)的命令,從.config中提取信息,生成Kbuild,完成內核編
譯所需的文件列表。
----------------------------------------------------------------------------------
.config
.config文件可以被理解為一個(gè)Makefile的變量表,該文件記錄了內核Makefile中與特定文件
編譯是否被編譯相關(guān)變量的值。內核配置程序根據每個(gè)目錄下的KCONFIG文件生成內核配置程序
選項界面,用戶(hù)通過(guò)該界面設定了需要編譯的功能,內核配置程序再根據KCONFIG中的內容生成
了不同的變量,并把該變量導入到.config,供內核編譯時(shí)參照調用。
---------------------------------------------------------------------------------
架構Makfile
頂層Makefile為各子目錄下Makefile包含的公共部分,而頂層Makefile又首先包含了arch/
$(ARCH)/Makefile。該架構Makefile包含了針對特定架構的配置信息,相關(guān)變量及目標等。
一具體架構Makefile的具體目的就是,將生成并壓縮 vmlinux 文件,寫(xiě)入啟動(dòng)代碼,并將其拷
貝到正確的位置。這就包含了多種不同的安裝命令。該具體目的也無(wú)法在各個(gè)平臺間進(jìn)行標
準化。一般,附加的處理命令入在arch/$(ARCH)/下的boot目錄。
----------------------------------------------------------------------------------
Kbuild文件
內核使用Kbuild組織Kbuild Makefile。如果同一目錄中同時(shí)出現Makefile與Kbuild,
Kbuild將會(huì )被使用。
編譯內核文件的主要目標有兩個(gè):分別是obj-y和obj-m。
Kbuild Makefile規定所有編譯進(jìn)內核的目標文件存在$(obj-y)列表中,編譯成模塊的
目標文件存在$(obj-m)列表中。而這些列表依賴(lài)內核的配置文件。
修改目標內容采用以下方式:
obj-$(CONFIG_<obj_dir_name>) = filename.o
此語(yǔ)句告訴內核,當前目錄下有一名為filename.o的目標。此目標將由filename.c或
filename.s文件編譯得到。
CONFIG_<obj_dir_name>
Makefile只對當前目錄對象負責,Kbuild通過(guò)辨別Kconfig中CONFIG_<obj_dir_name>
的值來(lái)判斷是否應該遞歸操作,但是它指代的值只能夠是y(編譯進(jìn)內核)或m(編譯成模塊),其
余值一律不會(huì )被編譯鏈接, 如:
#fs/Makefile
obj-$(CONFIG_EXT2_FS) = ext2/
如果,CONFIG_EXT2_FS的值有效,Kbuild就會(huì )遞歸訪(fǎng)問(wèn)ext2目錄,遞歸的原因是ext2/是一個(gè)目錄,
再調用該目錄下的Makefile進(jìn)行編譯操作。
----------------------------------------------------------------------------------
Kbuild執行的步驟
1) 根據內核配置生成文件 .config
2) 將內核的版本號存儲在 include/linux/version.h
3) 生成指向 include/asm-$(ARCH) 的符號鏈接
4) 更新所有編譯所需的文件:
-附加的文件由 arch/$(ARCH)/Makefile 指定。
5) 遞歸向下訪(fǎng)問(wèn)所有在下列變量中列出的目錄:
init-* core* drivers-* net-* libs-*
并編譯生成目標文件。
-這些變量的值可以在 arch/$(ARCH)/Makefile 中擴充。
6) 鏈接所有的目標文件,在源代碼樹(shù)頂層目錄中生成 vmlinux。
最先聯(lián)接是在 head-y中列出的文件,該變量由
arch/$(ARCH)/Makefile 賦值。
7) 最后完成具體架構的特殊要求,并生成最終的啟動(dòng)鏡像。
-包含生成啟動(dòng)指令
-準備 initrd 鏡像或類(lèi)似文件
----------------------------------------------------------------------------------
目標 obj-y
1). Kbuild編譯所有的$(obj-y)文件,然后,然后將它們鏈接為build-in.o文件,最后
鏈接到vmlinux中。
2). 相同的目標可以在obj-y列表中重復出現,已成功鏈接到built-in.o的目標會(huì )被忽略。
3). 目標鏈接時(shí)是按順序的。如果鏈接順序出錯,有可能造成硬盤(pán)數據出錯。
----------------------------------------------------------------------------------
目標 obj-m
1). 一個(gè)文件編譯一個(gè)模塊
obj-$(CONFIG_<obj_dir_name>) = <module_name>.o
2). 多個(gè)文件編譯一個(gè)模塊
obj-$(CONFIG_<obj_dir_name>) = <module_name>.o
<module_name>-objs := obj_file_1.o ... obj_file_n.o
Kbuild能夠識別目標文件的后綴為-objs和-y。kbuild通過(guò)CONFIG_符號來(lái)判斷對象是
否用于組合。
----------------------------------------------------------------------------------
編輯標志
下面標志僅在它們所被指定的Kbuild makefile有效。
ccflags-y
用于編譯C源代碼的編譯選項。源代碼樹(shù)擁有。
asflags-y
用于編譯匯編源代碼的編譯選項。當前目錄擁有。
ldflags-y
用于鏈接目標文件的選項。當前目錄擁有。
CFLAGS_$(filename), AFLAGS_$(filenam)
編譯源代碼選項,單個(gè)文件擁有的。
----------------------------------------------------------------------------------
依賴(lài)跟蹤
改變下面任意項內容,所有受影響文件將會(huì )重新被編譯。
1). 所有參與編譯的文件(*.o和*.h)
2). 所有參與使用的CONFIG_項
3). 用于編譯的命令行
----------------------------------------------------------------------------------
相關(guān)變量列表
----------------------------------------------------------------------------------
KERNELRELEASE
$(KERNELRELEASE) 是一個(gè)字符串,類(lèi)似"2.4.0-pre4",用于安裝目錄的命名或顯示當前的版本號。
一部分架構Makefile使用該變量。內容通過(guò)cat include/config/kernel.release所得。
ARCH
該變量定義了目標架構,比如"i386","arm" 或"sparc"。有些Kbuild Makefile
根據 $(ARCH) 決定編譯哪些文件。
默認情況下,頂層Makefile將其設置為本機架構。如果是跨平臺編譯,用戶(hù)可以
用下面的命令覆蓋該值:
make ARCH=m68k ...
INSTALL_PATH
該變量為架構Makefile定義了安裝內核鏡像與 System.map 文件的目錄。
主要用來(lái)指明架構特殊的安裝路徑。
INSTALL_MOD_PATH,MODLIB
$(INSTALL_MOD_PATH) 為了安裝模塊,給 $(MODLIB) 聲明了前綴。該變量不能
在Makefile中定義,但可以由用戶(hù)傳給Makefile。
$(MODLIB) 具體的模塊安裝的路徑。頂層Makefile將$(MODLIB)定義為
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)。用戶(hù)可以通過(guò)命令行
參數的形式將其覆蓋。
INSTALL_MOD_STRIP
如果該變量有定義,模塊在安裝之前,會(huì )被剝出符號表。如果
INSTALL_MOD_STRIP 為 "1",就使用默認選項 --strip-debug。否則,
INSTALL_MOD_STRIP 將作為命令 strip 的選項使用。
---------------------------------------------------------------------------------------------
與設備驅動(dòng)相關(guān)的瑣碎
. 編譯額外模塊
make M=dir modules 頂層Makefile會(huì )調用dir目錄下的Makefile去構造額外模塊
聯(lián)系客服