Linux驅動開發之模組化載入方法
目錄:
一、編寫一個最簡單的hello.c的驅動程式。
二、把此程式直接放到核心目錄下的 ......./char目錄中。應該怎樣修改Makefile以及Kconfig來實現動態的模組化載入
三、在核心目錄下的 ......./char 目錄中新建立一個hello_new/的目錄(因為在這個字元驅動可能會有較多的原始檔以及其他的輔助檔案時需要建立一個單獨的目錄讓檔案結構更加清楚)
一:編寫一個簡單的hello_module.c檔案
程式碼如下:
/*
* Helloc, World! 我們的第一個模組
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
/*
* Hello_init 初始化函式
*/
static int hello_init(void)
{
printk(KERN_ALERT "I bear a charmed life.\n");
return 0;
}
/*
* Hello_exit 退出函式
*/
static void hello_exit(void)
{
printk(KERN_ALERT "Out Out, brief candle!\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen");
hello_init()函式是模組的入口,模組的所有初始化函式必須符合下面的形式
int my_init(void),因為init函式一般不會在外部呼叫,所以標記為static。
對於退出函式也必須符合void my_exit(void)的形式。如果檔案被靜態的編譯到核心中,那麼退出函式將不包含退出函式,而且永遠也不會呼叫退出函式。
二、把此程式直接放到核心目錄下的 ......./char目錄中。應該怎樣修改Makefile以及Kconfig來實現動態的模組化載入
1)........./char/Makefile檔案中的修改:
增加如下語句: obj-$(CONFIG_HELLO_MODULE) += hello_module.o ($(CONFIG_HELLO_MODULE) 主要是與Kconfig中建立核心原始碼樹對應使用)
2)....../char/Kconfig檔案中的修改:
增加如下語句:
config HELLO_MODULE
tristate "Mini2440 module sample new"
depends on MACH_MINI2440
default m if MACH_MINI2440
help
Mini2440 module sample new.
這裡的HELLO_MODULE與Makefile檔案中的CONFIG_HELLO_MODULE後半部分對應。而不是hello_module.c這個檔名字去對應。
其中tristate表示3態的意思,即這個模組有Y、M、N三種狀態,在make menuconfig的選項中可以進行選擇。Y是表示靜態的編譯到核心中去。N表示核心不包含此模組。M表示核心把此模組以模組的形式編譯到模組中去。
depends on MACH_MINI2440,表示次模組對MACH_MINI2440模組有依賴關係。只有具備了依賴的模組才回出現此模組。如果依賴模組是Y,則此模組可以是Y、M、N,如果依賴模組是M,則此模組可以是M、N,
default m if MACH_MINI2440表示如果具備這個模組了,預設是模組化編譯。
help後面的都屬於提示性的化,在make menuconfig的時候,點選help出現的,並且在make menuconfig的時候這個模組的名字為Mini2440 module sample new。
3)在做了上面步驟後,進入到.../linux-2.6.32.2這個原始碼資料夾,執行make menuconfig,根據需要進行一些選擇。再執行make zImage。最後把zImage下載到開發板。
4)在.../linux-2.6.32.2這個原始碼資料夾執行make modules,生成hello_module.ko,在把此檔案上傳到開發板,並且放到/lib/modules/2.6.32.2-FriendlyARM資料夾中,執行modprobe hello_module就可以看到在終端打印出
I bear a charmed life.
再執行modprobe -r hello_module或則rmmod hello_module就可以看到Out Out, brief candle!
insmod以及rmmod都僅僅載入指定的模組,不會執行任何依賴性或進一步錯誤檢測。而modprobe不但會載入指定的模組,而且會自動載入任何它所依賴的有關模組。modprobe是最佳的模組載入方式。
三、在核心目錄下的 ......./char 目錄中新建立一個hello_new/的目錄(因為在這個字元驅動可能會有較多的原始檔以及其他的輔助檔案時需要建立一個單獨的目錄讓檔案結構更加清楚)
1)在....../char目錄下建立hello/這個資料夾。把原來的hello_module.c檔案移動到這個檔案中去,並且刪除其他的hello_module*的檔案。
2)在hello/資料夾下建立Makefile以及Kconfig兩個檔案。
3)在Makefile檔案寫入如下內容:
obj-$(CONFIG_HELLO_MODULE) += hello_module.o
如果以後不是一個原始檔時。則這樣寫
obj-$(CONFIG_HELLO_MODULE) += hello_module.o
hello_module-objs := hello_module-first.o hello_module-second.o
這樣,hello_module-first.c與hello_module-second.c原始檔就會自動被編譯進去。(其實在Makefile的編寫的時候用到了Makefile的潛規則,自動可以生成原始檔對應的.o檔案)
4)
在Kconfig檔案中寫入如下內容:
config HELLO_MODULE
tristate "Mini2440 module sample new second"
depends on MACH_MINI2440
default m if MACH_MINI2440
help
Mini2440 module sample new second.
這裡多了一個second主要目的是和第一次編譯的區別,讓自己看到,是這次編譯成功了,而不是上一次。
5)進入到...../char目錄下,修改此目錄中的Makefile以及Kconfig
Makefile檔案:
先刪除在第一次編譯過程中新增的東西(當然如果直接使用這種方法進行編譯,則不用刪除了)
在檔案中加入如下語句
obj-$(CONFIG_HELLO_MODULE) += hello/
Kconfig檔案:
先刪除在第一次編譯過程中新增的東西(當然如果直接使用這種方法進行編譯,則不用刪除了)
在檔案中加入如下語句
source "drivers/char/hello/Kconfig"
6)後面步驟和 二中的 3) 4)步驟一致。
為了確認自己是否,成功,可以修改hello_module.c的輸出資訊,重新進行模組生成,再放入開發板,進行模組載入,看列印輸出資訊是否改變了。