linux內核學習-編譯架構-1.編譯過程簡單說說和kconfig文件介紹

隨着學習的深入,有必要了解下編譯的過程。尋找到一個出路。

前言
這篇文章知道C語言的“宏語句”的含義。

一、編譯過程簡單說說

從內核的編譯過程,我們知道:
1.首先要有一個.config文件(這個文件通過Make menuconfig產生)。
2.make命令根據.config和Makefile文件,最終生成vmlilnux這個內核文件。
3.vmlinux壓縮成zImage。

二、.config文件來龍去脈

在源碼的編寫時候,程序員需要寫一個叫Kconfig的文件。在整個kernel源碼中有很多的Kconfig文件並且他們是以“樹狀”的形式,層層聯繫起來(是聯繫,不是依賴)。
kbuild工具(源碼中的一個程序)會從某些指定的目錄(源碼的頂級目錄結構是規範好的)開始,搜索源碼中的所有Kconfig文件,然後配合Make menuconfig將內核可以配置的東西都呈現出來,用戶根據自己的需求,配置好內核。最終保存爲.config文件。

當然這裏提一點:整個內核很大,所有選項一項一項的配置完,然後再生成.config文件是非常難的事情。所以供應商一般都會給一個樣板.config文件,make menuconfig會自動加載相關配置。我們只需要做小修改就行。

三、.config文件

打開.config文件,會發現,裏面都是一些類似的“宏定義”內容。沒錯,它就類似一種開關的作用。告訴make我要什麼功能。記得編譯進去。
所以在看Makefile文件的時候,發現一些變量找不到的定義的,可以到.config文件裏面找找。

四、Kconfig文件

Kconfig位於kernel源碼內大部分的文件夾中,是一種特殊格式的文件,負責提供kernel各個功能的配置選項。
文件的組織方式如下所示,編譯的時候傳入arch參數,找到對應的kconfig。文件通過source的方式引入新的kconfig文件。通過解析後,就可以形成menuconfig的組織形式
在這裏插入圖片描述

比如進行驅動移植等工作時,有時需要自己添加Kconfig中的一個配置項,從而將某個設備驅動添加到內核的配置項目中。
需要注意的是,Kconfig僅僅負責提供配置選項本身,而不提供各選項的值,

下面我們將以Block devices爲例,剖開這層面紗。
在這裏插入圖片描述
在Device Drivers–》Block devices裏面。在這裏插入圖片描述
同時代碼對應drivers–》block目錄下的Kconfig
在這裏插入圖片描述
1.看Kconfig的第5行,對應是menuconfig,也就是說這個Kconfig是以一個單獨的頁面單獨展開。而config則代表的是一個配置選項。
2.而被 if BLK_DEV和 endif # BLK_DEV括起來的這些配置選項,就是Block devices菜單內的子選項
3.3.souce有點include的意思,每一個Kconfig都會source引入其所有子目錄下的Kconfig,從而保證了所有的Kconfig項目都被包含進menuconfig中。這個也告訴我們:如果自己在linux內核中添加了一個文件夾,一定要在這個文件夾下創建一個Kconfig文件,然後在這個文件夾的上一層目錄的Kconfig中source引入這個文件夾下的Kconfig文件
4.menuconfig或者config後面空格隔開的類似於DM9000和NETDEVICES 的就是這個配置項的配置項名字。配置項名字會被很多文件所引用(有點像宏定義),比如前面添加CONFIG_後就構成了.config中的配置項名字
5.bool或tristate後面跟着的字符串就是這些配置項在menuconfig的顯示內容
6.bool表示該配置項只能配置Y和N,對應menuconfig中的[ ];而tristate表示該配置項可以被配置爲Y,N,M,對應menuconfig中的<>;如圖所示
7.depends 的含義是依賴的意思,就比如上面的配置項DM9000_16BIT,它依賴於配置項DM9000,如果配置項DM9000是N,那麼DM9000_16BIT無論配置爲任何值,都無效了;另外,依賴是層層遞進的,如果依賴的依賴無效,也會導致配置項無效。同時依賴無效的話還會導致make menuconfig中配置項的消失
8.depends並不要求依賴的配置項一定是一個,可以是多個,而且還可以有邏輯運算(比如上面的!UML)。這種時候只要依賴項目運算式子的裸機結果爲真則依賴就成立

五、實例1:

需要編譯這個ttyprink的功能,在drivers/char目錄中包含了TTY_PRINTK設備驅動的源代碼drivers/char/ttyprintk.c。而在該目錄的Kconfig文件中包含關於
TTY_PRINTK的配置項:
在這裏插入圖片描述
可以看到TTY_PRINTK依賴EXPERT和TTY兩個配置項,也就是說這兩個配置項沒有打開,TTY_PRINTK是看不到的。通過查找,還真的在Device Drivers->Character devices中找不到TTY_PRINTK這個項。通過查找源碼,找到EXPERT這個項對應的Kconfig文件在/init/Kconfig。默認是no的,看這個文件的頭部,知道其對應根目錄的General setup菜單。打開後找到
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
選擇上,然後再去看TTY_PRINTK就可以找到有了。
在這裏插入圖片描述

六、實例2:

假設想把自己寫的一個flash的驅動程序加載到工程中,而且能夠通過menuconfig配置內核時選擇該驅動該怎麼辦呢?

可以分三步:

第一:將你寫的hello.c 文件添加到/drivers/char/ hello目錄下。

第二:修改/drivers/char/ hello目錄下的kconfig文件:

config HELLO_MODULE
tristate "hello-tristate"
default y
help
        this is help test

第三:修改該目錄下makefile文件。
添加如下內容:

obj-$(CONFIG_HELLO_MODULE) += hello.o

第四:修改上層目錄/drivers/char中Kconfig文件

在這裏插入圖片描述

這樣,當你運行make menucofnig時,你將發現 hello-tristate選項,如果你選擇了此項。

該選擇就會保存在.config文件中。體現爲
在這裏插入圖片描述
這將是在hello/Makefile中

obj-$(CONFIG_HELLO_MODULE) += hello.o
等價爲
obj-y += hello.o

系統在調用hello下的makefile 時,將會把 hello.o 加入到內核中。即可達到你的目的。

七、實例3

爲演示Kconfig不同的數據類型的效果,編寫如下例程:
Kconfig文件:

config HELLO_MODULE
tristate "hello-tristate"
default y
help
        this is help test
 
 
config HELLO_MODULE2
bool "hello-bool"
default y
help
        this is help test
 
 
config HELLO_MODULE3
string "helllo-string"
default "str-test"
 
 
config HELLO_MODULE4
hex "hello-hex"
 
 
config HELLO_MODULE5
int "hello-int"

在這裏插入圖片描述
最終生成的.config文件如下
在這裏插入圖片描述

可以看到,會自動在名字的前面加上CONFIG_這樣的關鍵字。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章