分析Linux內(nèi)核源碼組織結(jié)構(超詳細~)
本文主要參考韋東山老師的《嵌入式Linux應用開發(fā)完全手冊》,基于Linux-2.6.32.2源碼。 概要:本文內(nèi)容包含Linux源碼樹結(jié)構分析、Linux Makefile分析、Kconfig文件分析、Linux內(nèi)核配置選項分析。這些知識是為了理解內(nèi)核文件的組織形式,為具體移植內(nèi)核做知識準備。
1. Linux源碼樹結(jié)構分析
對Linux源碼樹下個子目錄內(nèi)包含的內(nèi)容進行列表羅列:

?
2.Linux Makefile分析
主要從三個方面講解:編譯哪些文件、如何編譯文件、如何連接文件
Linux Makefile的分類

編譯哪些文件
【文章福利】小編推薦自己的Linux內(nèi)核技術交流群:【891587639】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ?


頂層Makefile決定哪些目錄中的文件將編譯進內(nèi)核
頂層Makefile將13個子目錄分成5個部分:init-y、drivers-y、net-y、libs-y、core-y
頂層通過下列語句包含和體系架構有關的Makefile。仔細觀察可以看到/arch子目錄的根目錄下是沒有Makefile文件的,而其它各子目錄都是有Makefile。
所以在編譯內(nèi)核之前先要確定ARCH
默認的ARCH不是我們需要的,所以要進行修改
$$(srctree)/arch/$(SRCARCH)/Makefile對內(nèi)核的內(nèi)容進行了擴充
可以看到一個新元素head-y,它還有一個特殊的地方,它是直接對應著兩個文件,而不是目錄。之所以分成兩個是為了同時支持有無MMU的CPU,它們對應著兩個不同的head$(MMUEXT).o 文件,由變量MMUEXT控制,可以在配置時設定。
至此我們知道了編譯時將進入哪些文件進行編譯。編譯時依次進入init-y、core-y、libs-y、drivers-y、net-y中列的目錄調(diào)用其中的Makefile進行編譯,每一個子目錄都會生成build-in.o(libs-y所列的目錄下有可能生成lib.a)。最后head-y列出的文件和build-in.o、lib.a一起連接成vmlinux.
在配置內(nèi)核時,將會產(chǎn)生.config文件,Makefile將會在.config文件中添加下面兩行。
有可能是版本原因,在2.6.32.2版本中并沒有上面兩個語句,有下面兩句。
觀察.config文件會發(fā)現(xiàn)變量的值主要有兩種y、m,各級的Makefile將會根據(jù)這些變量的值來決定編譯哪些文件,同時是編譯進內(nèi)核,還是作為內(nèi)核模塊存在。
obj-y中定義的.o文件將由當前目錄下的.c、.S文件及子目錄下的build-in.o文件編譯連接得到的。
注意:obj-y中定義的.o文件的順序是由意義的。
下面是一段取自子目錄中的Makefile文件內(nèi)容,在該目錄下有ioat和ipu子目錄
obj-m中定義的.o文件是由的當前目錄下的.c、.S文件編譯生成,它們不會與build-in.o一起編譯進入內(nèi)核。而是被編譯成.ko文件,作為模塊存在。
當.o文件由單文件編譯而成時,用下面的語句:
當.o文件由多文件編譯而成時,用下面的語句:
編寫驅(qū)動程序時,也是以這種方式編寫Makefile。
lib-y中定義的.o文件是由的當前目錄下的.c、.S文件編譯生成,他們被打包成當前目錄下的lib.a文件。同時出現(xiàn)在lib-y和obj-y中的文件,不會被包含進lib.a文件。
obj-y和obj-m可以用來指定進入下一級目錄。
怎么編譯這些文件
怎么編譯文件就是意味著編譯選項和連接選項是什么。 這些選項分成3類:全局的(適用整個代碼樹)、局部的(適用單個Makefile)、個體的(適用單個文件)。 全局選項是在頂層Makefile和arch/$(ARCH)/Makefile中定義的,這些選項是CFLAGS、AFLAGS、LDFLAGS、ARFLAGS,它們分別是編譯C文件的選項,編譯匯編文件的選項,連接文件的選項,制作庫文件的選項。 局部選項在各自子目錄中定義,名稱為:EXTRA_CFLAGS、EXTRA_AFALGS、EXTRA_LDFALGS、EXTRA_ARFLAGS. 對單文件設定編譯選項,可以用CLFAGS_$@、AFLAGS_$@,前者對C文件,后者對匯編文件。 注意:3類選項是一起使用的,在scripts/Makefile.lib中可以看到:
如何連接文件
在頂層Makefile文件中有如下語句:
可以看出以后的連接是相當于著五種built-in.o文件和head-o文件的連接。
之后對這些文件再次進行合并
可以看出初始化代碼由兩部分組成head-y和init-y兩部分組成,而且head-y是在init-y的前面。所以總的代碼順序是arch/arm/kernel/head.o(假設有MMU,沒有的話是head_nommu.o)、arch/arm/kernel/init_task.o、init/build-in.o。
連接腳本是arch/$(SRCARCH)/kernel/vmlinux.lds,它由arch/$(SRCARCH)/kernel/vmlinux.lds.S生成。
具體連接細節(jié)可以查看上面的文件內(nèi)容。
3.內(nèi)核的Kconfig分析
內(nèi)核配置工具讀取各個Kconfig文件,生成配置界面共開放人員配置內(nèi)核,最后生成配置文件.config。
關于Kconfig的最權威資料在/Documentations/Kbuild/kconfig-language.txt
Kconfig語法分析:
Kconfig的基本要素:config
config經(jīng)常被其它條目包含,用來生成菜單和多項選擇。
上述代碼是config的常用方式:
在配置界面中配置了該選項后,會在.config中出現(xiàn) CONFIG_JFFS2_FS_WBUF_VERIFY = y或者m.
在配置界面中將會顯示Verify JFFS2 write-buffer reads選項,bool是變量的類型,一共有5種變量類型:bool、tristate、 string 、hex 、int,bool變量有兩種取值y,m;tristate變量有三種取值y,m,n;string可以取字符串;hex取十六進制數(shù);int取十進制數(shù)。
代表只有在JFFS2_FS_WRITEBUFFER被配置時,才會進行該選項的配置。
代表默認的情況下是選擇n
代表在該選項被選種時,會將FS_POSIX_ACL也選種。
當在配置時按H時會顯示該信息。
menu條目
配置界面的主界面是由根目錄下Makefile中ARCH配置決定的,當選擇arm時,/arch/arm中的Kconfig文件將會用來生成主目錄。
設定主目錄的名稱
將會創(chuàng)建System Type子目錄
choice條目
choice將多個類似的配置選項組合在一起,供用戶多選和單選
上述代碼給出提示信息,選中之后就可以進行選擇配置
choice條目中定義的變量類型只能是bool和tristate,當配置的代碼編譯入內(nèi)核時為bool,只能有一個條目選擇為y;當編譯成模塊時為tristate或bool,為bool時,也只能是一個為y,當為tristate時,可以有多個m。
comment條目
comment條目用于提供幫助信息,出現(xiàn)在配置界面的第一行。
source條目
用于包含其他Kconfig文件
菜單形式的配置界面的操作方法配置界面中[*]、< M >、[ ]分別表示相應的文件被編譯進內(nèi)核、編譯成模塊、沒有被編譯。
當執(zhí)行第一條語句時,將.config外的config文件加載,當執(zhí)行第二條時,表示存儲成處.config 外的config文件。
4.Linux內(nèi)核配置選項
與移植密切相關的內(nèi)容是System Type、Device Driver。
內(nèi)核配置主界面內(nèi)容

在配置內(nèi)核的時候按照順序進行,因為前面的配置會影響后面的。
