LDD3中Makefile淺析

新手,剛開始學linux下的驅動開發。前期看了本robert love《linux kernel development》,很多問題都沒有深究。

在學習ldd3時,遇到的第一個問題是編譯自己的內核,這個花費了一些工夫後終於搞定。

遇到的第二個問題就是這本書的第二章《構造和運行模塊》中的Makefile的問題。

現在初步有了自己的理解,記錄下來,供以後溫故知新,也方便有我相同疑問的朋友參考。

如有錯誤之處,請大家指出,共同進步,謝謝。

 

我的開發環境是fedora 13OS,自己下了2.6.35的Kernel源代碼樹,從新編譯,安裝了系統。

具體GNU工具的版本就不說了,都是fedora 13自帶的。看懂本文,可能需要有一點點makefile基礎,我也不是很精通:)

 

首先,將Makefile粘帖出來:

 

 

首先解釋下makefile中的幾點:

$(MAKE)--是指make。在內核樹的主makefile中,可以找到這個變量。

$(KERNELRELEASE)--KERNELRELEASE也是一個變量,可以在內核樹的主makefile中找到。

$(MAKE) -C $(KERNELDIR)  --KERNELDIR在前面定義了,是指內核樹的根目錄。-C選項的作用是將當前的工作目錄轉移到你所指定的目錄,我們這裏指定爲內核樹的根目錄,/lib/modules/$(shell uname -r)/build指向的就是內核樹的根目錄,build是個軟鏈接。 uname -r是shell命令,顯示當前的內核版本號,我的是2.6.35.

M=$(PWD)--M=選項讓該makefile在構造modules目標之前,返回到當前目錄。一般這個makefile和驅動模塊的代碼在一起,就是返回到驅動模塊代碼所在的目錄。“M=” 選項的作用是,當用戶需要以某個內核爲基礎編譯一個外部模塊的話,需要在make modules 命令中加入“M=dir” ,程序會自動到你所指定的dir 目錄中查找模塊源碼,將其編譯,生成KO 文件。

modules--目標指向obj-m變量中設定的模塊。如果有多個源文件,obj-m := hello.o需要改一下,改如下:

 

 

 

接下來重點描述下我對makefile流程的理解,其實這個纔是我最花工夫的地方。

 

首先要搞明白一點,我的驅動代碼和這個makefile並不一定在內核樹根目錄下,實際上,我是在/home/xxx/src/下的。在shell裏,也是在這個目錄下執行的make命令。

 

執行make

首先檢查KERNERRELEASE變量,發現沒有定義,所以,走else,接下來定義了兩個變量KERNELDIR和PWD。

然後會走進default.

 

注意: 此時會因爲 -C $(KERNELDIR)進入內核樹根目錄,執行內核樹根目錄下的主makefile,這個makefile中有我們前面提到的兩個變量的聲明,KERNELRELEASE和MAKE。內核樹裏的主makefile會根據M=選項,執行M=選項指向的目錄處的驅動代碼的makefile。其實這是第二次讀這個makefile了。

然後根據M=選項指向的模塊目錄,再執行驅動代碼位置的makefile,也就是前面粘帖下來的makefile。你可能會有疑問,那這個makefile不是被讀了兩遍了嗎?是的。就是讀了兩遍,但是兩遍結果並不相同。因爲第二遍的時候,KERNELRELEASE 和MAKE變量有了定義。於是走了ifndef分支,obj-m有了定義,此時才真正的編譯內核模塊。編譯完模塊,會離開內核樹的目錄,回到M=選項指向的目錄。

 

一個標準的模塊編譯過程,makefile是要被讀兩次的。

 

採用這種makefile的好處是,既可以將驅動模塊放在內核樹裏面編譯(/usr/src/linux/driver/),也可以將驅動模塊放在內核樹外面,都可以編譯通過.

 

使用命令: make -n可以查看詳細的執行過程.

 

參考:

1.LDD3

2.http://www.embedu.org/Column/Column310.htm

 

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