配置與編譯核心用到的工具很多,在這裡只對幾個關鍵工具進行介紹,更多的內容請參考相關手冊。
make
make
是一種幫助大型軟體工程的編譯工作實現自動化的程式語言。正確地使用make可以大大減少因編譯程式而花費的時間,因為它可以消除不必要的再編譯。make的基本設計思想是如果目標檔案是在最近一次對原始檔的修改之後編譯的,它就是「新的」,不需要重新編譯;如果最近一次對源
檔案的修改之後沒有及時更新目標檔案,那麼該目標檔案就是「舊的」,需要重新編譯。為了理解make如何執行乙個任務,需要了解一些術語:
◆目標 需要執行的乙個任務。多數情況下它就是使用者要生成的檔案的名字,但是它也可以僅是個任務的名字。
◆依賴關係 兩個目標之間相互依存的關係。如果修改目標b會造成目標a的修改,那麼就說目標a依賴於目標b,b是a的先決條件。
◆變數 一種儲存臨時資訊的載體。make中使用的變數應該加上括號,例如$(temp)。
◆命令 執行任務時使用的指令,可以是一條、多條,甚至沒有。
◆規則 一條完整的規則具有以下格式:
目標(target) : 先決條件
(prerequisites)
規則(***mand)
......
其中只有目標必須要有,其它成分可以沒有。一條完整的規則描述了編譯乙個目標的方法和依賴關係,是makefile中最重要的部分。
◆makefile
檔案 描述如何生成乙個或多個目標的檔案。它列出目標依賴的各個檔案,並提供正確編譯這些目標所需要的規則。
接下來以
2.4.23的kbuild為例,簡要介紹一下核心的構建過程。首先,完整的核心構建過程由以下五種makefile封裝。
1.根目錄
makefile
它是最重要的makefile,定義所有與體系結構無關的變數和目標。它讀取.config檔案,並根據其資訊最終生成vmlinux和modules。make通過向下遞迴呼叫子目錄中的makefile來編譯這兩個目標。
2.配置檔案
.config
執行「make 」會在根目錄下生成該配置檔案,其內容記錄了具體的配置選擇,也可以將舊核心的配置檔案放在這裡。
3.arch/*/makefile
這是與特定體系結構相關的makefile。它包含在根目錄下的makefile中,為kbuild提供體系結構的特定資訊。
4.子目錄
makefiles
它們存在於每個子目錄下,大約有幾百個。它們接受來自上層make傳遞下來的資訊,並根據這些資訊來構造乙個需要編譯的檔案列表,並交由rules.make處理。
5.rules.make
幾乎每個子目錄makefile都包含該makefile。根據子目錄makefiles構建的檔案列表,make使用rules.make定義的通用規則來編譯所有來自列表的原始檔。
kbuild的執行過程是:make從根目錄makefile開始執行,從中獲得與體系結構無關的變數和依賴關係,並同時從arch/*/makefile中獲得體系特定的變數等資訊,這些資訊擴充套件了根目錄makefile提供的變數。此時kbuild已經擁有構建核心需要的所有變數和目標。然後,make進入子目錄,把部分變數傳遞給子目錄makefile。子目錄makefile根據配置資訊決定編譯哪些原始檔,從而構建出乙個需要編譯的檔案列表。最後,rules.make根據其定義的編譯規則決定這些檔案的編譯方式。
需要注意的是,由於make的向下遞迴特性和無序性,其執行過程並不完全遵守順序逐行執行的規則,但無論make的執行有多複雜,也只分為兩個階段。第乙個階段make會讀取所有變數和分析所有目標的依賴關係,並最終建立一棵依賴關係樹。同時,所有的立即型變數(通過「:=」賦值)在這個過程中被擴充套件,就像c變數一樣。而在這個階段的最後,所有的延遲型變數才被擴充套件(通過「=」賦值)。這點需要格外注意。第二個階段make會根據依賴關係樹執行命令。
因此,乙個目標和其先決條件的規則定義的順序是無所謂的,很可能乙個目標的先決條件的規則定義在百行以後才出現。make會耐心讀完所有的makefile後分析得出依賴關係樹。
gcc
gcc是gnu的免費編譯程式,也是核心惟一指定使用的編譯器。gcc在執行乙個完整的編譯任務時會經過以下步驟:
◆預處理gcc會呼叫cpp程式來分析各種巨集指令,如#define、#if、#include等。
◆編譯 這一階段根據輸入檔案產生組合語言指令。由於通常情況下是立即呼叫匯程式設計序as,所以輸出一般不儲存在檔案中,可以使用-s選項強制輸出源程式的彙編版本。
◆彙編 這一階段將組合語言源程式作為輸入,生成.o目標檔案。
◆鏈結 這是最後乙個階段。該階段中,各個.o模組被鏈結在一起構成可執行檔案。
as 使用者可以明確地要求使用as來直接處理彙編檔案。as產生的目標檔案可以分為文字段(.text)、資料段(.data)和未初始化資料段(.bss)。
ld 與as相似,使用者可以明確地要求使用ld鏈結程式將幾個模組組合成乙個單獨的可執行檔案。其鏈結過程通常由乙個叫ld鏈結指令碼的檔案來描述。該指令碼使用linker ***mand language編寫。使用「ld --verose」命令可以看到這個預設使用的ld鏈結指令碼。
ar ar是gnu的二進位制檔案處理程式,用於建立、修改及從歸檔檔案中抽取檔案。由它生成的.a歸檔檔案實際上是乙個包含許多可執行二進位制**子程式集合的庫檔案。
rpmbuild
使用「make rpm」可以把核心源**製作成rpm包。在此之前,kbuild會執行「make spec」生成rpmbuild程式用到的spec檔案,詳見「man rpmbuild」。
中介軟體
根目錄scripts下的各種指令碼和c原始檔都可以稱作中介軟體。它們並不是核心元件的一部分,只是在kbuild執行過程中的輔助程式。以split-include為例,講述配置檔案的運作機理。
.config由關鍵字/值對組成,其內容類似於:
config_mpentiumiii=y
# config_mpentium4 is not set
config_reiserfs_fs=m
這些資訊在執行「make 」時自動生成。同時include/linux/autoconf.h依照.config的內容生成。它的格式類似於
: #define config_mpentiumiii 1
#undef config_mpentium4
#undefconfig_reiserfs_fs
#define config_reiserfs_fs_module 1
對比一下不難發現,include/linux/autoconf.h明確地洞悉了.config的意圖:哪些元件不編譯,哪些需要編譯進核心,而哪些又要作為模組來編譯?split-include根據include/linux/autoconf.h在include/config/下建立相關的目錄和.h檔案。每個.h檔案只包括include/linux/autoconf.h中的某一行,比如在配置核心選項時支援ntfs檔案系統,並把它編譯進核心,在.config中就會生成「config_ntfs_fs=y」,相應地在include/linux/autoconf.h中會生成「#define config_ntfs_fs
1」一項。這樣,所有與ntfs檔案系統相關的c原始檔都會包含include/config/ntfs/fs.h標頭檔案。
如果以前編譯過核心,並且沒有使用過「make mrproper」,.config、include/linux/autoconf.h和include/linux/config/就不會被刪除。這裡涉及到新舊核心的配置問題。乙個全新的核心**是未經配置的。如果只在原核心的功能基礎上增加對ntfs的支援,那麼從頭開始配置無疑是浪費時間。可以繼續使用原核心的.config檔案,而所有的配置資訊不會有任何更改,並且可以直接在原配置的基礎上增加新功能。
在複雜的情況下,保留的舊核心配置資訊還要與新的配置資訊進行比較:哪些舊資訊需要覆蓋,哪些需要保留?下面來看一下幾種可能的情況
:
舊值儲存在include/config/下的.h檔案中,新值儲存在新生成的include/linux/autoconf.h檔案中。split-include的**不僅描述了如何處理這五種情況,還描述了include/config/下檔案和子目錄的生成過程。
linux配置 編譯核心實用工具
配置與編譯核心用到的工具很多,在這裡只對幾個關鍵工具進行介紹,更多的內容請參考相關手冊。make make 是一種幫助大型軟體工程的編譯工作實現自動化的程式語言。正確地使用make可以大大減少因編譯程式而花費的時間,因為它可以消除不必要的再編譯。make的基本設計思想是如果目標檔案是在最近一次對原始...
linux實用工具
基本實用工具 ls 顯示檔名 list cat 顯示文字檔案內容 rm i 刪除檔案 remove i開啟選項 less more 分屏顯示檔案 hostname 顯示系統名 檔案操作 cp sourcefile destinationfile 複製檔案copy mv oldname newname...
Linux實用工具
特殊字元 轉義字元可以用 括起來,也可以在前面加上 基礎的一些命令 列出檔名 ls 顯示檔案文字內容 cat 刪除檔案 rm 顯示系統名 hostname 複製檔案 cp 更改檔名 mv 列印檔案 lpr 查詢字串 grep 顯示頭,尾檔案 head,tail 按順序顯示檔案內容 sort 刪除檔案...