“HelloWorld”驅動:在核心空間載入和卸載驅動
當一個裝置驅動模組被載入進核心,一些諸如複位裝置、預留RAM(reserving RAM)、中斷和輸入輸出連接埠等預備工作經常會被執行。
我們需要展示兩個函數:module_init和module_exit,這兩個函數在核心完成了上述的任務。他們和使用者空間的insmod和rmmod相對應,前面我們提到過,這兩個命令式用來安裝和卸載模組的。總的來說,使用者命令insmod和rmmod使用的是核心的函數module_init 和 module_exit。
讓我們來看一個實現傳統程式Hello world的程式:
<hello.c> =
#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
MODULE_LICENSE("DualBSD/GPL");
static inthello_init(void) {
printk("<1>Hello world!\n");
return 0;
}
static voidhello_exit(void) {
printk("<1>Bye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
實際上函數hello_init和hello_exit可以取任何你想取的名字。但是,為了將他們和對應的載入和卸載函數相對應,他們必須作為參數傳遞給相應的module_init和module_exit函數。
這裡使用了printk函數,除了它只工作在核心空間外它和我們熟知的printf函數非常相似。符號“<1>”表明了這個訊息具有高優先順序(小數字)。這樣,除了能夠在核心系統記錄檔當中得到這個訊息外,你還可以在系統的控制台接收到這個訊息。
在添加了它的名字到“Makefile”中後,這個模組也可以用之前的命令進行編譯。
<Makefile2> =
obj-m :=nothing.o hello.o
在本片文章之後,我將編寫Makefiles檔案作為了一個練習留給了讀者。一個可以編譯本指南中所有模組的Makefile在本文的附錄A中可以找到。
當一個模組被載入或者卸載的時候,在系統的控制台都將列印寫在printk函數中的訊息。如果這些訊息沒有在控制台出現,你可以使用dmesg命令查看他們或者使用命令“cat /var/log/syslog”查看系統日誌。
下表顯示了這兩個新的函數
Event |
User functions |
Kernel functions |
Load module |
Insmod |
module_init() |
Open device |
|
|
Read device |
|
|
Write device |
|
|
Close device |
|
|
Remove module |
rmmod |
module_exit() |
表 裝置驅動事件和與對應的在使用者空間和核心空間的互動函數