Linux內(nèi)核模塊初始化的過程是怎樣的,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
一、代碼
模塊1導(dǎo)出了函數(shù)void output(void),模塊2調(diào)用了模塊1中的函數(shù)。(先加載模塊1,再加載模塊2)
模塊1:
#include <linux/module.h> #include <linux/kernel.h> // static int int_var = 0; module_param(int_var, int, 0644); MODULE_PARM_DESC(int_var, "A integer variable"); static char* str_var = "default"; module_param_named(str_var_alias, str_var, charp, 0644); MODULE_PARM_DESC(str_var_alias, "A string variable"); static char str_var2[10]; module_param_string(str_var2_alias, str_var2, 10, 0644); MODULE_PARM_DESC(str_var2_alias, "A string variable"); static int int_arr[10]; int narr; module_param_array(int_arr, int, &narr, 0644); MODULE_PARM_DESC(int_arr, "A integer array"); static int int_arr2[10]; int narr2; module_param_array_named(int_arr2_alias, int_arr2, int, &narr2, 0644); MODULE_PARM_DESC(int_arr2_alias, "A integer array"); // static void output(void) { printk("hello world!\n"); } EXPORT_SYMBOL_GPL(output); static int __init init_marker(void) { int i; printk("init marker.\n"); // printk("int_var:%d\n", int_var); printk("str_var:%s\n", str_var); printk("str_var2:%s\n", str_var2); for (i=0; i<narr; ++i) { printk("int_arr[%d]=%d\n", i, int_arr[i]); } for (i=0; i<narr2; ++i) { printk("int_arr2[%d]=%d\n", i, int_arr2[i]); } // output(); return 0; } static void __exit exit_marker(void) { printk("exit marker.\n"); } module_init(init_marker); module_exit(exit_marker); MODULE_VERSION("1.0.0_0"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("gwy"); MODULE_ALIAS("the alias of module name"); MODULE_DESCRIPTION("the description about the use of the module"); //MODULE_DEVICE_TABLE();
模塊2:
#include <linux/module.h> #include <linux/kernel.h> static void my(void) { extern void output(void); output(); printk("my\n"); } static int __init init_marker(void) { printk("init marker.\n"); my(); return 0; } static void __exit exit_marker(void) { printk("exit marker.\n"); } module_init(init_marker); module_exit(exit_marker); MODULE_VERSION("1.0.0_0"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("gwy"); MODULE_ALIAS("the alias of module name"); MODULE_DESCRIPTION("the description about the use of the module"); //MODULE_DEVICE_TABLE();
二、初始化
2.1 函數(shù)原型
static int __init init_marker(void)
{
}
static void __exit exit_marker(void)
{
}
初始化函數(shù),在定義文件之外沒有任何意義,所以應(yīng)聲明為static。
__init(__exit)表名該函數(shù)只在初始化期間使用。在模塊裝載之后,模塊裝載器會(huì)將初始化函數(shù)丟掉,這樣可以將函數(shù)占用的內(nèi)存釋放出來。
2.2 關(guān)于模塊的描述
MODULE_VERSION("1.0.0_0");
模塊版本號(hào)
MODULE_LICENSE("GPL");
模塊開源協(xié)議
MODULE_AUTHOR("gwy");
模塊作者
MODULE_ALIAS("the alias of module name");
模塊別名
MODULE_DESCRIPTION("the description about the use of the module");
模塊描述
MODULE_PARM_DESC(int_var, "A integer variable");
參數(shù)描述
查看模塊信息:
三、加載/卸載
insmod
rmmod
modprobe ( modprobe -r )
lsmod(通過讀取/proc/modules虛擬文件來獲取模塊信息)
四、模塊參數(shù)
4.1 參數(shù)
module_param(int_var, int, 0644);
定義模塊參數(shù)。
module_param_named(str_var_alias, str_var, charp, 0644);
外部參數(shù)名稱與內(nèi)部變量名稱不同。
module_param_string(str_var2_alias, str_var2, 10, 0644);
拷貝字符串到分配好的內(nèi)存。(不同于charp,先分配內(nèi)存,再拷貝)
module_param_array(int_arr, int, &narr, 0644);
定義模塊數(shù)組類型參數(shù)。
module_param_array_named(int_arr2_alias, int_arr2, int, &narr2, 0644);
數(shù)組類型 外部參數(shù)名稱與內(nèi)部變量名稱不同。
MODULE_PARM_DESC(int_var, "A integer variable");
參數(shù)描述。
4.2 支持的類型
bool
invbool
布爾值(true或false),關(guān)聯(lián)的變量是int型。
charp
字符指針值。內(nèi)核會(huì)為用戶提供的字符串分配內(nèi)存,并設(shè)置相應(yīng)的指針。
int、short、long、uint、ushort、ulong
4.3 訪問權(quán)限
module_param(int_var, int, 0644);
0644是訪問權(quán)限,用數(shù)字表示,或者用S_IRUGO|S_IWUSR表示。
查看訪問權(quán)限:/sys/module/test/parameters
4.4 查看模塊的參數(shù)
modinfo查看,見2.2中圖片。
五、導(dǎo)出符號(hào)表
模塊層疊技術(shù)
5.1 導(dǎo)出函數(shù)
EXPORT_SYMBOL(func)
EXPORT_SYMBOL_GPL(func)
EXPORT_SYMBOL_GPL導(dǎo)出的模塊只能被GPL許可的模塊使用。
5.2 查看導(dǎo)出的符號(hào)
/proc/kallsyms
5.3 調(diào)用模塊導(dǎo)出符號(hào)
需要在模塊2的Makefile中添加:KBUILD_EXTRA_SYMBOLS = /opt/test-kernel/Module.symvers(模塊1的路徑,必須是絕對(duì)路徑), 否則會(huì)報(bào)錯(cuò)。
參考資料:http://blog.csdn.net/hshl1214/article/details/8769112
六、錯(cuò)誤處理
如果可以繼續(xù),通過降低功能繼續(xù)運(yùn)轉(zhuǎn)。
如果不能繼續(xù),必須撤銷所有已經(jīng)注冊(cè)的設(shè)備。
goto、cleanup/flag。
撤銷順序與加載順序相反。
七、模塊裝載競(jìng)爭(zhēng)
模塊還沒初始化完的時(shí)候,內(nèi)核就有可能來調(diào)用我們的模塊了。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,的支持。
當(dāng)前題目:Linux內(nèi)核模塊初始化的過程是怎樣的-創(chuàng)新互聯(lián)
轉(zhuǎn)載來于:http://aaarwkj.com/article2/cdhioc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計(jì)、品牌網(wǎng)站制作、外貿(mào)建站、微信公眾號(hào)、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容