linux核心makefile分析

2021-09-11 07:42:41 字數 4628 閱讀 7659

核心makefile.txt中將makefile分為 5部分,kernel makefile、arch makefile、kbuild makefile、.config檔案以及scripts/makefile.*

kernel makefile 

kernel makefile 位於linux 核心源**的頂層目錄,也叫 top makefile 。它主要用於指定編譯linux kernel 目標檔案(vmlinux )和模組(module )路徑。它根據.config檔案決定了核心根目錄下那些檔案、子目錄被編譯進核心。對於核心或驅動開發人員來說,這個檔案幾乎不用任何修改。

arch makefile

arch makefile 位於arch/$(arch)/makefile ,是系統對應平台的makefile 。kernel top makefile 會包含這個檔案來指定平台相關資訊。arch makefile同樣根據.config檔案,決定了arch/$(arch) 目錄下 那些檔案、子目錄被編譯進核心 只有平台開發人員會關心這個檔案。

kbuild makefile

從linux 核心2.6 開始,linux 核心的編譯採用kbuild 系統 ,這同過去的編譯系統有很大的不同,kbuild 系統使用kbuild makefile 來編譯核心或模組。當kernel makefile 被解析完成後,kbuild 會讀取相關的kbuild makefile 進行核心或模組的編譯。kbuild makefile 有特定的語法指定哪些編譯進核心中、哪些編譯為模組、及對應的原始檔是什麼等。核心及驅動開發人員需要編寫這個kbuild

makefile 檔案。 

scripts/makefile.* 通用規則

makefile.build 

被頂層makefile所呼叫,與各級子目錄的makefile合起來構成乙個完整的makefile檔案,定義built-in.o、.lib以及目標檔案.o的生成規則。這個makefile檔案生成了子目錄的.lib、built-in.o以及目標檔案.omakefile.clean 

被頂層makefile所呼叫,用來刪除目標檔案等makefile.lib 

被makefile.build所呼叫,主要是對一些變數的處理,比如說在obj-y前邊加上obj目錄kbuild.include 

被makefile.build所呼叫,定義了一些函式,如if_changed、if_changed_rule、echo-cmd 

詳細分析請參考:深度探索linux作業系統:系統構建和原理解析

.config

來自配置過程,生成 auto.conf 以及 autoconf.h,被頂層makefile所包含,參考

核心雖然有自己的構建系統kbuild,但是kbuild 並不是什麼新的東西,我們可以把kbuild 看作利用gnu make組織的一套複雜的構建系統,雖然kbuild 也在make 基礎上做了適當的擴充套件,但是因為核心的複雜性,所以kbuild 要比一般的專案的makefile 的組織要複雜的多。為了方便linux開發者能夠編寫makefile,kbuild考慮得不可謂不周到,比如,kbuild將所有與編譯過程相關的共用規則和變數都提取到scripts

目錄下的makefile.build中,而具體的子目錄下的 makefile 檔案則可以編寫的非常簡單與直接。

大多的kbuild 檔案的名字都是makefile 。為了與其他makefile 檔案相區別,你也可以指定kbuild makefile 的名字為 kbuild 。而且如果「makefile 」和「kbuild 」檔案同時存在,則kbuild 系統會使用「kbuild 」檔案。在這裡,我們的 kbuild makefile 就是各個子目錄的makefile ,它的作用就是 指定當前目錄下的檔案,哪些被編譯進當前目錄的built-in.o、那些被編譯成模組、那些不編譯。

kbuild makefile 的乙個最主要功能就是指定編譯什麼,這個功能是通過下面兩個物件指定的obj-? 和***-objs  

例如: 

obj-y += foo.o 

obj-m += abc.o 

大多數情況下是這樣: 

obj-$(config_dm9000) += dm9000.o 

具體的 config_dm9000 是y 還是m取決於配置過程,配置過程產生.config檔案,.config又產生auto.conf以及autoconf.**件,包含在makefile檔案裡。

參考:如果核心模組是通過幾個原始檔編譯而成的,您可以使用和上面同樣的方法指定您想要編譯的模組.然而此時kbuild需要知道編譯模組時是基於那些目標檔案的,因此您需要設定乙個$(-objs)變數來告訴編譯器.

例如:#drivers/isdn/i4l/makefile

obj-$(config_isdn) += isdn.o

isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o

用 obj-* 連線的objects 在指明的資料夾中被用作模組或者綜合進built-in.o 。也又可能被列出的objects 將會被包含進乙個庫,lib.a 。所有用lib-y 列出的objects 在那個資料夾中被綜合進單獨的乙個庫。列在obj-y 且 附加列在lib-y 中的objects 將不會被包含在庫中,因為他們將會被任意的訪問。對於被連線在lib-m 中,連續的objects 將會被包含在lib.a 中。值得注意的是kbuild makefile 可能列出檔案用作built-in

,並且作為庫的一部分。因此,同乙個資料夾可能包含乙個built-in.o 和lib.a 檔案  

例如:  

lib-y    := checksum.o delay.o 

這裡講會建立乙個基於checksum.o 和delay.o 的庫檔案。對於kbuild ,識別乙個lib.a 正在被構建,這個資料夾應該被列在 libs-y 中。 lib-y 的使用方法通常被限制在lib/ 和arc/*/lib 中。

kernel makefile

/* 指定 平台、編譯器 */ 

arch        ?= arm 

cross_compile    ?= arm-linux- 

/* 設定 6 類檔案編譯路徑 */ 

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/

/* 包含 arch makefile 在通用編譯路徑基礎上增加 架構相關的路徑 */ 

include $(srctree)/arch/$(srcarch)/makefile

head-y        := arch/arm/kernel/head$(mmuext).o arch/arm/kernel/init_task.o

core-y                += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/

core-y                += $(machdirs) $(platdirs) 

core-$(config_fpe_nwfpe)    += arch/arm/nwfpe/ 

core-$(config_fpe_fastfpe)    += $(fastfpe_obj) 

core-$(config_vfp)        += arch/arm/vfp/ 

drivers-$(config_oprofile)      += arch/arm/oprofile/ 

libs-y                := arch/arm/lib/ $(libs-y)

/* 指定路徑下的built-in.o 檔案 */ 

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 a, ab, c) 會將ab中的a替換為c 

例如: 

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

$(net-y) == net/ 

將 %/built-in.o中的%/替換為net/ 

結果為:net/built-in.o

Linux核心配置 Makefile目標

在頂層linux原始碼目錄中輸入命令make help,它會顯示一長串從原始碼樹中生成的目標列表。最常見的使用make的方式是不指定目標,在這種情況下,它會生成核心elf檔案vmlinux和針對所選架構的預設二進位制映象 例如,x86架構的bzimage 使用make時,如果不指定目標,它也會編譯所...

linux核心模組編譯makefile

1 編譯進核心的模組 如果需要將乙個模組配置進核心,需要在makefile中進行配置 obj y foo.o 2 編譯可載入的模組 所有在配置檔案中標記為 m的模組將被編譯成可載入模組.ko檔案。如果需要將乙個模組配置為可載入模組,需要在makefile中進行配置 obj m foo.o 3 模組編...

linux核心Makefile的簡單分析

makefile 總結 1 配置檔案.config中定義了一系列的變數,makefile將結合它們來決定哪些檔案被編譯進核心。哪些檔案被編譯成模組。涉及哪些子目錄。2 頂層makefile和arch arch makefile決定更目錄下哪些子目錄,arch arch 目錄下哪些檔案和目錄被編譯進核...