標籤:
原文網址:http://www.apkbus.com/android-98520-1-1.html
前面幾節都是將Linux驅動編譯成模組,然後動態裝載進行測試。動態裝載驅動模組不會隨著Android系統的啟動而自動裝載,因此Android系統每次啟動都必須使用insmod或modprobe命令裝載Linux驅動模組。
對於嵌入式系統(包括嵌入式Android、嵌入式Linux等)一般都採用將Linux驅動編譯進核心的方式。這樣做雖然沒有動態裝載靈活,但Linux驅動會隨著Android的啟動而自動裝載。一般在開發過程中為了測試和調試方便,會將Linux驅動以模組形式裝載到Linux核心中。當Linux驅動通過最終測試後,會將Linux驅動編譯進Linux核心再進行測試。
本節將介紹如何將word_count驅動編譯進Linux核心,並分別在Android模擬器和S3C6410開發板上測試word_count驅動。
Linux核心原始碼被設計成可裝卸式結構。也就是說只需要修改設定檔,就可以使某個Linux驅動編譯成模組(.ko檔案),或編譯進Linux核心,當然,也可以將該Linux驅動從Linux核心去除。核心的設定檔如下。
q .config:該檔案位於Linux核心原始碼的頂層目錄,為隱藏檔案。該檔案用於配置Linux核心中的模組。在.config檔案中可以對Linux驅動進行三方面的配置:編譯成驅動模組(.ko檔案)、編譯進核心和從Linux核心去除。可以手工修改.config檔案,也可以使用make menuconfig命令用菜單方式來設定.config檔案。
q Kconfig:每一個想要串連進Linux核心的模組目錄都有該檔案。該檔案主要用於定義make menuconfig命令顯示的菜單(包括功能表項目名稱、協助資訊、選項類型、模組依賴等資訊),除此之外,Kconfig檔案還可以匯入位於其他目錄的Kconfig檔案。make命令通過Kconfig檔案的遞迴引用,可以找到Linux核心中的所有Kconfig檔案,從而建立一個完整的配置菜單。
q Makefile:一般與Kconfig檔案同時出現。每有一個Kconfig檔案,就必要有一個Makefile檔案。該檔案用於指定如何編譯Makefile檔案所在目錄的原始碼。
現在還使用word_count驅動的例子來詳細說明如何將一個Linux驅動加入Linux核心原始碼樹中。由於word_count驅動屬於字元驅動,所以可以使用如下的步驟將word_count驅動加入Linux核心原始碼樹。
第1步:將word_count.c檔案放入Linux核心原始碼
將word_count.c檔案放到<Linux核心目錄>/drivers/char目錄中。
第2步:修改Kconfig檔案
開啟/root/kernel/goldfish/drivers/char/Kconfig檔案,找到endmenu,並在endmenu前面添加如下代碼。
config WORD_COUNT
bool "word_count driver"
help
This is a word count driver. It can get a word count from /dev/wordcount
其中,config後面的字串將作為Shell變數名的後半部分,前半部分是CONFIG_。也就是說,每一個具體的模組都會對應一個Shell變數來儲存該模組的3個編譯行為(產生.ko檔案、編譯進Linux核心或從Linux核心中去除)。word_count驅動模組的變數是CONFIG_WORD_COUNT。該變數的值會儲存在.config檔案中。
bool表示word_count驅動只能進行兩項設定(被編譯進核心與從Linux核心中去除),後面會介紹如何設定功能表項目的三項設定。bool後面的字串就是功能表項目的文本。help用於設定功能表項目的協助資訊。
第3步:修改Makefile檔案
開啟/root/kernel/goldfish/drivers/char/Makefile檔案。該檔案大多都是6-21所示的內容,隨便找個位置插入如下內容。
<ignore_js_op>
▲圖6-21 在Makefile檔案中添加word_count驅動模組
obj-$(CONFIG_WORD_COUNT) += word_count.o
通過第2步的設定產生了一個CONFIG_WORD_COUNT變數,而在第3步中obj-後使用了該變數,而不是使用固定的值(y或m)。make命令在編譯Linux核心時會將該變數替換成相應的值。
第4步:設定.config檔案
.config檔案可以通過手工配置,也可以通過make menuconfig命令在菜單中配置。在這裡我們採用菜單配置的方法。現在進入Linux核心頂層目錄(/root/kernel/goldfish)。然後執行make menuconfig命令顯示配置菜單,並進入“Device Drivers”>“Character devices”子功能表,找到“word_count_driver”功能表項目,按空格鍵將“word_count_driver”功能表項目前設定成星號(*),6-22所示。然後退出配置介面並儲存所做的修改。
按“h”鍵可以顯示word_count驅動的協助資訊,6-23所示。
<ignore_js_op>
▲圖6-22 配置word_count驅動模組
<ignore_js_op>
▲圖6-23 word_count驅動的協助資訊
在配置完.config檔案後,讀者可以開啟.config檔案,並找到CONFIG_WORD_COUNT,會發現該變數的值已被設成“y”。
第5步:編譯Linux核心
進入/root/kernel/goldfish目錄,執行下面的命令編譯Linux核心。
# make
如果讀者以前編譯過當前的Linux核心,並不需要擔心編譯的時間過長,因為make足夠智能,它只會編譯最新修改的模組及其依賴的模組。
當成功編譯Linux核心後,讀者可以到/root/kernel/goldfish/arch/arm/boot目錄找到zImage檔案,並使用Android模擬器運行這個核心。讀者會發現,在/dev目錄中有一個wordcount裝置檔案,而我們並沒有運行build.sh指令檔安裝word_count驅動。這是因為Android模擬器在裝載zImage核心檔案時已自動裝載了word_count驅動。不過在使用前面的例子測試word_count驅動時仍然需要執行下面的命令設定/dev/wordcount裝置檔案的存取權限。
# adb shell chmod 777 /dev/wordcount
如果讀者不想將word_count.c複製到/root/kernel/goldfish/drivers/char目錄,可以使用下面的命令在/root/kernel/goldfish/drivers/char目錄建立一個符號連結。
# ln -s /root/drivers/ch06/word_count /root/kernel/ goldfish/drivers/ char/word_ count
將word_count目錄加入Linux核心原始碼樹的步驟如下(在進行下面的步驟之前需要將上面步驟所做的設定注釋掉)。
第1步:建立新的Kconfig檔案
在word_count目錄中建立一個Kconfig檔案,並輸入如下內容:
config WORD_COUNT
tristate "word_count driver"
default y
help
This is a word count driver. It can get a word count from /dev/wordcount
其中tristate表示三態類型(編譯進核心、編譯成模組,從Linux核心移除)。如果使用tristate代替bool,功能表項目前面就變成角括弧。按“y”鍵,角括弧中顯示星號(*),表示編譯進核心。按“M”鍵,角括弧中顯示M,表示編譯成模組。按“N”鍵,角括弧在符號消失,表示word_count驅動被忽略。如果不斷按“空格”鍵,這3種狀態會迴圈切換。
default用來設定預設值。如果使用tristate,default可以設定y、m和n三個值,分別對應編譯進核心、編譯成模組和從Linux核心中移除。當模組第一次設定時會處於default設定的預設狀態。
注意如果使用tristate,必須按照6.4.2節的方法開啟“Enable loadable module support”選項,否則無法將驅動設為編譯成模組狀態(M狀態),功能表項目前面仍然是一對中括弧。
第2步:修改Makefile檔案
word_count目錄中的Makefile檔案目前的內容如下:
obj-m := word_count.o
在Makefile檔案中已經將編譯類型設為Linux驅動模組(obj-m表示編譯成.ko檔案)。但現在要將word_count驅動加入Linux核心原始碼樹中,因此需要使用CONFIG_WORD_COUNT變數來代替m,所以Makefile檔案的內容需要按如下內容修改。
obj-$(CONFIG_WORD_COUNT) := word_count.o
修改Makefile檔案後,如果還想使用前面幾節的指令檔測試word_count驅動,需要將.config檔案中CONFIG_WORD_COUNT變數值設為m,如果.config檔案中沒有該變數,就添加一個CONFIG_WORD_COUNT變數。當然,也可以使用make menuconfig命令設定。
為了可以單獨編譯word_count驅動,也可以和Linux核心一同編譯,我們可以採用如下形式重新編寫Makefile檔案。當CONFIG_WORD_COUNT變數未定義時,說明沒有與Linux核心一同編譯。
# 與Linux核心一同編譯
ifdef CONFIG_WORD_COUNT
obj-$(CONFIG_WORD_COUNT) := word_count.o
else
# 單獨編譯
obj-m := word_count.o
endif
第3步:修改上層目錄的Kconfig檔案
為了能找到word_count目錄中的Kconfig檔案,需要在drivers/char/Kconfig檔案中引用word_count目錄中的Kconfig檔案。現在開啟/root/kernel/goldfish/drivers/char/Kconfig檔案,在“endmenu”之前添加如下一行代碼。
source "drivers/char/word_count/Kconfig"
第4步:修改上層目錄的Makefile檔案
在drivers/char/Makefile檔案中添加如下一行,以便使make命令可以找到word_count目錄中的Makefile檔案。
obj-$(CONFIG_WORD_COUNT) += word_count/
接下來的工作就和前面介紹的五步中的第4步和第5步一樣了。在進入6-24所示的設定介面時,可以按“M”鍵將word_count驅動模組編譯成.ko檔案。
<ignore_js_op>
▲圖6-24 設定word_count驅動模組的編譯類型
注意當修改Linux核心設定後重新編譯核心,以前使用該Linux核心編譯的Linux驅動模組可能由于格式錯誤無法安裝,因此,在重新編譯Linux核心後,需要重新編譯Linux驅動模組。
如果想將word_count驅動模組編譯進其他核心也可採用與上面類似的做法。
【轉】6.4.6 將驅動編譯進Linux核心進行測試