5、Linux内核模块开发
Linux的模塊驅動
?
這是個最簡單的驅動程序。就是打印hello的信息。驅動程序和我們的程序語言結果有點不大一樣。驅動模塊的入口是倒數第二行的module_init()的函數。驅動模塊的出口是module_exit()的函數。
3.接著是makfile文件:
這也是一個很簡單的Makefile文件了。Obj-m后面跟的是我們的最終目標依賴的文件hello.o。第三行的KDIR是我們編譯進的內核的路徑。All是執行make得到的目標,$(KDIR)指定內核的路徑,就是第三行的路徑。M=$(PWD)是模塊存放的路徑。接著就是清除生成的文件的命令。
4.make的執行過程:
從上面的執行的過程,我們可以看到makefile的執行的過程。
?
?
?
如果在一個工程里,當有兩個.c文件的時候的編寫:
Hello.c:
Function.c:
Makefile修改為:
最后編譯的結果如下圖:
?
?
?
?
?
內核模塊的安裝和卸載:
insmod hello.ko
卸載內核模塊:
rmmod hello(卸載的時候不用加.ko)
查看模塊:
lsmod
?
執行的結果:
注意:內核模塊只有當沒有用戶用時才可以卸載,如上圖:我們的test是沒有被使用,而fuse有兩個用戶在使用。我們試著卸載這兩個內核模塊的截圖:
?
?
?
內核模塊的可選的信息:模塊申明、模塊參數、符號信息。
模塊的申明:
????MODULE_LICENSE("遵守的協議")
申明該模塊遵守的許可證協議,如:"GPL"、"GPL v2"等。
????MODULE_AUTHOR("作者")
????申明模塊的作者
????MODULE_DESCRIPTION("該模塊的功能描述")
????MODULE_VERSION("v1.0")
申明模塊的版本
?
模塊申明可以讓讀者知道該模塊所遵守的協議,增加模塊代碼的可讀性。
?
?
只是一個提示,增加可讀性的作用。
?
模塊參數的傳遞:
在我們的應用程序中:int main(int argc,char** argv):argc表示命令行輸入的參數個數,argv中保存輸入端的參數。
那么我們的內核模塊中是怎么傳入參數的呢?:
?
模塊參數跟我們程序語言的參數有點不大一樣,除了用一般的數據類型來申明變量參數,我們還得用module_param()這個宏來指定它是模塊參數:
Module_param(name,type,perm):
Name:變量的名稱
Type:變量的類型,bool,int,charp。
Perm:訪問權限。S_IRUGO:讀權限。S_IWUSR:寫權限。
例如:
Int a=33;
Char *st;
Module_param(a,int ,S_IRUGO);
Module_param(st,charp,S_IRUGO);
?
下面是執行的實例:
我們定義了一個a=99;然后在14行打印出來。運行的結果:
上面是執行的過程,我們也可以在執行的時候給它加參數:
字符串也是一樣:
運行的結果:
?
?
最后是符號導出:
符號導出的實例:
修改Makefile:
?
修改function.c為:
?
執行的過程:
?
同時產生了兩個.ko模塊。
當我們去安裝hello.ko的時候,出現了這個錯誤:未定義的符號:
這是因為我們程序中的extern int function();現在的系統中不存在這個函數。那是不是得先insmod function.ko呢!?
雖然系統已經出現了function函數,可是系統還是找不到。可以看出錯誤依然存在。
?
這就是模塊導出的問題:當我們要去使用一個模塊里面的變量,函數的時候,必須使用符號導出。也就是把變量和函數輸出到我們的系統當中,使整個系統都可以使用。
修改function.c為:
用EXPORT_SYMBOL()來申明,我的function是可以被系統的其他模塊使用的。不過,我們應該先編譯function.ko,在編譯hello.ko。結果:
這就是符號輸出的使用。
總結與應用程序的區別:
內核的打印:
Printf和printk都是打印信息的。但是printk還有級別打印:
Hello.c:
?
輸出結果:
結果只有KERN_EMERG級別的才在屏幕打印出來。這樣的打印級別,我們可以控制在那些地方可以打印什么。當然,我們也可以用輸入來代替級別。例如上面的"<0>",就是KERN_EMER。
?
?
轉載于:https://www.cnblogs.com/FORFISH/p/5188421.html
總結
以上是生活随笔為你收集整理的5、Linux内核模块开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 7个你可能不认识的CSS单位
- 下一篇: hdu 5616 Jam's balan