作者:華清遠見講師
Linux驅動開發主要的工作就是編寫模塊,一個典型的Linux內核模塊文件.ko 主要由以下幾個部分組成。
模塊加載函數(必須)
當通過insmod或modprobe命令加載內核模塊時,模塊的加載函數會自動被內核執行,完成本模塊的相關初始化工作。
Linux內核模塊加載函數一般用static 關鍵字聲明為內部鏈接,並以__init 標識。之所以標識為__init
,用途是如果編譯內核時模塊是以靜態方式包含在vmlinux中,則在鏈接的時候標識為__init 的函數會放在.init.text
這個區,同時還會在.initcall.init
區中保存一份函數指針,在內核初始化階段會通過這些函數指針調用這些初始化函數,在初始化階段完成後,這些init區段會被釋放以節省內存。
模塊加載函數必須以module_init(函數名)
的形式被指定。它返回整型值,若初始化成功,返回0。初始化失敗時,應該返回錯誤編碼。內核的錯誤碼是一個負數,在中定義,形如ENODEV等。
示例代碼如下:
1. static int __init foo_init(void)
2. {
3. //...
4. }
5. module_init(foo_init)
模塊卸載函數(必須)
當通過rmmod命令卸載某模塊時,模塊的卸載函數會自動被內核執行,完成與模塊加載函數相反的功能。
Linux內核模塊卸載函數一般用static 關鍵字聲明為內部鏈接,並以__exit 標識。和__init 一樣, __exit
也可以使對應函數在運行完成後自動回收內存。具體可以查看內核代碼中__init 和__exit 這兩個宏的定義。
模塊卸載函數必須以module_exit(函數名) 的形式指定,不返回任何值。
示例代碼如下:
1. static void __exit foo_exit(void)
2. {
3. //...
4. }
5. module_exit(foo_exit)
模塊許可證聲明(必須)
模塊許可證(LICENSE)聲明描述內核模塊的許可權限,如果不聲明 LICENSE,模塊被加載時,將收到內核被污染(kernel
tainted)的警告。在Linux2.6內核中,可接受的 LICENSE包括“GPL”,“GPL v2”,“GPL and additonal
rights”,“Dual BSD/GPL”,“Dual MPL/GPL”和“Proprietary”。
大多數情況下,內核模塊應遵循GPL兼容許可權。Linux2.6內核模塊最常見的是聲明模塊采用BSD/GPL雙LICENSE,如下:
1. MODULE_LICENSE("Dual BSD/GPL")
模塊參數(可選)
模塊參數是模塊被加載的時候可以被傳遞給它的值,它本身對應模塊內部的全局變量。
在裝載內核模塊時,用戶可以向模塊傳遞參數,形式為“insmode(或modprobe) 模塊名
參數名=參數值”,如果不傳遞,參數將使用模塊內定義的默認值。 模塊內部可以用module_param(參數名,參數類型,參數讀/寫權限)
定義一個參數,例如:
1. static char *str = "hello,world"
2. static int num = 4000
3. module_param(num, int, S_IRUGO)
4. module_param(str, charp, S_IRUGO)
模塊導出符號(可選)
內核模塊可以導出符號(symbol,對應於函數或變量),這樣其它模塊可以使用本模塊中的變量或函數。
Linux2.6的/proc/kallsyms 文件對應著內核符號表,它記錄了符號以及符號所在的內存地址。
模塊可以使用如下宏導出符號到內核符號表:
1. EXPORT_SYMBOL(符號名)
2. EXPORT_SYMBOL_GPL(符號名)
導出的符號將可以被其他模塊使用,使用前聲明一下即可。EXPORT_SYMBOL_GPL() 適用於包含GPL許可證的模塊。例如:
1. #include
2. #include
3. MODULE_LICENSE("Dual BSD/GPL")
4.
5. init add(int a,int b)
6. {
7. return a + b
8. }
9. EXPORT_SYMBOL(add)
模塊作者等信息聲明(可選)
我們可以使用MODULE_AUTHOR , MODULE_DESCRIPTION , MODULE_VERSION ,
MODULE_DEVICE_TABLE , MODULE_ALLAS 分別聲明模塊的作者,描述,版本,設備表和別名。
其中注意MODULE_DEVICE_TABLE 常用於PCI或者USB驅動中表明該驅動模塊所支持的設備。
>>>更多優秀技術博文來自華清遠見嵌入式學院
本文出自 “嵌入式學習天地” 博客,請務必保留此出處http://farsight.blog.51cto.com/1821374/1792641