Linux核心中的Kconfig、Makefile、.config
毛毛同學今天學習了驅動程式模組的安裝與解除安裝,在這個過程中毛毛髮現,核心的目錄中有許多的Kconfig、Makefile檔案,但是毛毛不知道為什麼需要這些檔案,這些檔案又是用來做什麼的。下面我們就和陶毛毛同學一起來學習下這些檔案的作用是什麼。
首先我們來學習什麼Makefile,什麼是Kconfig ,什麼是.config
Makefile:一個文字形式的檔案,其中包含一些規則告訴make編譯哪些檔案以及怎樣編譯這些檔案。
Kconfig:一個文字形式的檔案,其中主要作用是在核心配置時候,作為配置選項。
.config:檔案是在進行核心配置的時候,經過配置後生成的核心編譯參考檔案。
Kconfig
1.先了解一下Kconfig的語法:
一個典型的核心配置選單如下:
menu "Network device support"
config NETDEVICES
bool "Enable Net Devices"
depends on NET
default y
help
This is help desciption。
...
endmenu
包含在menu/endmenu中的內容會成為Network device support的子選單。每一個子選單項都是由config來定義的。congfig下方的那些bool、depends on、default、help等為config的屬性,用於定義該選單項的型別、依賴項、預設值、幫助資訊等。
2. 補充說明一下型別定義部分:
每個config選單項都要有型別定義: bool布林型別、 tristate三態(內建、模組、移除)、string字串、 hex十六進位制、 integer整型。
例如:
config HELLO_MODULE
bool "hello test module"
bool 型別的只能選中或不選中,顯示為[ ]; tristate型別的選單項多了編譯成核心模組的選項,顯示為< > , 假如選擇編譯成核心模組,則會在.config中生成一個 CONFIG_HELLO_MODULE=m的配置,假如選擇內建,就是直接編譯成核心影響,就會在.config中生成一個 CONFIG_HELLO_MODULE=y的配置. hex十六進位制型別顯示為( )。
3. 目錄層次迭代
在Kconfig中有類似語句:source "drivers/usb/Kconfig"
用來包含(或巢狀)新的Kconfig檔案,這樣便可以使各個目錄管理各自的配置內容,使不必把那些配置都寫在同一個檔案裡,方便修改和管理。
----------------------------------------------------------------------------------------------
Makefile
2.6核心的Makefile分為5個組成部分:
1. 最頂層的Makefile
2. 核心的.config配置檔案
3. 在arch/$(ARCH) 目錄下的體系結構相關的Makefile
4. 在s目錄下的 Makefile.* 檔案,是一些Makefile的通用規則
5. 各級目錄下的大概約500個kbuild Makefile檔案
頂層的Makefile檔案讀取 .config檔案的內容,並總體上負責build核心和模組。Arch Makefile則提供補充體系結構相關的資訊。 s目錄下的Makefile檔案包含了所有用來根據kbuild Makefile 構建核心所需的定義和規則。
Kbuild Makefile
對於Makefiles的不同組成部分,有一些不同的語法規則。針對的物件也不同,對於大部分核心模組或裝置驅動的開發者和使用者來說,最常接觸到的就是各層目錄下基於kbuild架構的kbuild Makefile檔案。Kbuild Makefile核心內容主要包括:
1.目標定義
目標定義就是用來定義哪些內容要做為模組編譯,哪些要編譯連結進核心。如:
obj-y += foo.o
表示要由foo.c或者foo.s檔案編譯得到foo.o並連結進核心,而obj-m則表示該檔案要作為模組編譯。 除了y,m以外的obj-x形式的目標都不會被編譯。而更常見的做法是根據.config檔案的CONFIG_ 變數來決定檔案的編譯方式(該變數如何起作用見文末另一篇文章的連結),如:
obj-$(CONFIG_EXT2) += ext2.o
除了obj-形式的目標以外,還有lib-y library庫,hostprogs-y 主機程式等目標,但是基本都應用在特定的目錄和場合下。
例子說明:
下面我們以例項來說明這幾個檔案的作用
Step1:編輯配置檔案Kconfig,加入驅動選項,使之在make menuconfig 的時候出現
開啟 linux-2.6.32.2/drivers/char/Kconfig 檔案,新增如圖所示:
儲存退出,這時在linux-2.6.32.2 目錄位置執行一下make menuconfig 就可以在Device
Drivers Character devices 選單中看到剛才所新增的選項了,按下空格鍵將會選擇為<M>,
此意為要把該選項編譯為模組方式;再按下空格會變為<*>,意為要把該選項編譯到核心中,
在此我們選擇<M>,如圖:
Step2:通過上一步,我們雖然可以在配置核心的時候進行選擇,但實際上此時執行編譯核心還是不能把mini2440_hello_module.c 編譯進去的,還需要在Makefile 中把核心配置選項和真正的原始碼聯絡起來,開啟linux-2.6.32.2/drivers/char/Makefile,如圖新增並儲存退出:
Step3:這時回到linux-2.6.32.2 原始碼根目錄位置,執行make modules,就可以生成我們所需要的核心模組檔案 mini2440_hello_module.ko 了,如圖:至此,我們已經完成了模組驅動的編譯。