一個Linux內核模塊主要由如下幾個部分組成。
1)模塊加載函數(必須)
當經過insmod或modprobe命令加載內核模塊時,模塊的加載函數會自動被內核執行,完成本模塊的相關初始 化工做。
Linux內核模塊加載函數通常以__init標識聲明,示例代碼以下:
static int __init FuntionA(void)
{
}
module_init( FuntionA);
模塊加載函數必須以 「module_init(函數名)」的形式被指定。它返回整型值,若初始化成功,返回0。而在 初始化失敗時,應該返回錯誤編碼。
2)模塊卸載函數(必須)
當經過rmmod命令卸載某模塊時,模塊的卸載函數會自動被內核執行,完成與模塊加載函數相反的功能。
模塊卸載函數通常以__exit標識聲明,示例代碼以下:
static void __exit FuntionB(void)
{
}
module_exit( FuntionB );
模塊卸載函數在模塊卸載的時候執行,不返回任何值,必須以「module_exit(函數名)」的形式指定。
一般來講,模塊卸載函數要完成與模塊加載函數相反的功能,以下所示。
a)若模塊加載函數註冊了XXX,則模塊卸載函數應該註銷XXX。
b)若模塊加載函數動態申請了內存,則模塊卸載函數應釋放該內存。
c)若模塊加載函數申請了硬件資源(中斷,DMA通道,I/O端口和I/O內存等)的佔用,則模塊卸載函數應釋 放這些硬件資源。
d)若模塊加載函數開啓了硬件,則卸載函數中通常要關閉硬件。
3)模塊許可證聲明(必須)
模塊許可證(LICENSE)聲明描述內核模塊的許可權限,若是不聲明 LICENSE,模塊被加載時,將收到內核被 污染的警告。
在Linux2.6內核中,可接受的 LICENSE包括「GPL」,「GPL v2」,「GPL and additonal rights」,「Dual BSD/GPL」,「Dual MPL/GPL」和「Proprietary」。
大多數狀況下,內核模塊應遵循GPL兼允許可權。Linux2.6內核模塊最多見的是以MODULE_LICENSE("Dual BSD/GPL")語句聲明模塊採用BSD/GPL雙 LICENSE 。
4)模塊參數(可選)
模塊參數是模塊被加載的時候能夠被傳遞給它的值,它自己對應模塊內部的全局變量。
咱們能夠用「module_param(參數名,參數類型,參數讀/寫權限)」爲模塊定義一個參數,例如:
static char *str = "hello,world";
static int num = 4000;
module_param(num,int,S_IRUGO);
module_param(str,charp,S_IRUGO);
在裝載內核模塊時,用戶能夠向模塊傳遞參數,形式爲「insmode(或modprobe) 模塊名參數名=參數值」, 若是不傳遞,參數將使用模塊內定義的默認值。
5)模塊導出符號(可選)
內核模塊能夠導出符號(symbol,對應於函數或變量),這樣其它模塊能夠使用本模塊中的變量或函數。
Linux2.6的「/proc/kallsyms」文件對應着內核符號表,它記錄了符號以及符號所在的內存地址。
模塊能夠使用以下宏導出符號到內核符號表:
EXPORT_SYMBOL(符號名);
EXPORT_SYMBOL_GPL(符號名);
導出的符號將能夠被其餘模塊使用,使用前聲明一下便可。EXPORT_SYMBOL_GPL()值適用於包含GPL許可證的 模塊。
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
init add(int a,int b)
{return a+b;}
EXPORT_SYMBOL( add );
6)模塊做者等信息聲明(可選)。
咱們能夠使用MODULE_AUTHOR,MODULE_DESCRIPTION,MODULE_VERSION,MODULE_DEVICE_TABLE,MODULE_ALLAS分 別聲明模塊的做者,描述,版本,設備表和別名。
模塊的編譯
使用make -C (Linux內核源代碼目錄) M=(要編譯的源文件和Makefile目錄) modules,若是當前就處在模塊所 在的目錄,則能夠使用 make -C (Linux內核源代碼目錄) M=$(pwd) moduleshtml
文章來源:http://blog.sina.com.cn/s/blog_413240a601013k2p.htmllinux