通常情況下,一個(gè)模塊只使用內(nèi)核導(dǎo)出的符號(hào),自己不導(dǎo)出符號(hào)。但是如果一個(gè)模塊需要提供全局變量或函數(shù)給另外的模塊使用,那么就需要將這些符號(hào)導(dǎo)出。
這在一個(gè)驅(qū)動(dòng)調(diào)用另一個(gè)驅(qū)動(dòng)代碼時(shí)比較常見,這樣模塊和模塊之間就形成了依賴關(guān)系,使用導(dǎo)出符號(hào)的模塊將會(huì)依賴于導(dǎo)出符號(hào)的模塊。
舉個(gè)具體的例子,下面是兩個(gè)C文件,vser.c
調(diào)用了dep.c
中的變量和函數(shù):
vser.c
#include < linux/init.h >
#include < linux/kernel.h >
#include < linux/module.h >
extern int expval;
extern void expfun(void);
static int __init vser_init(void)
{
printk("vser_init");
printk("expval:%dn", expval);
expfun();
return 0;
}
static void __exit vser_exit(void)
{
printk("vser_exitn");
}
module_init(vser_init);
module_exit(vser_exit);
dep.c
#include < linux/kernel.h >
#include < linux/module.h >
static int expval = 5;
EXPORT_SYMBOL(expval);
static void expfun(void)
{
printk("expfun");
}EXPORT_SYMBOL_GPL(expfun);
Makefile關(guān)鍵處:
obj-m := vser.o
obj-m += dep.o
上述代碼中,dep.c定義了一個(gè)變量expval
和一個(gè)函數(shù)expfun
,并分別用EXPORT_SYMBOL
和EXPORT_SYMBOL_GPL
導(dǎo)出。而vser.c
里則調(diào)用了dep.c
的變量和函數(shù),編譯安裝后:
# modprobe vser
# dmesg
[58278.204677] vser_init
[58278.204683] expval:5
[58287.206464] expfun
從輸出信息中可以看到,vser.c
正確引用到了dep.c
的變量和函數(shù)。
這里有三點(diǎn)重要說(shuō)明:
- 如果使用
insmod
命令加載模塊,則必須先加載dep模塊,再加載vser模塊 。
因?yàn)関ser模塊用到了dep模塊的東西。從這里可以看出,modprobe
命令優(yōu)于insmod
命令的地方在于其可以自動(dòng)加載被依賴的模塊。而這又要?dú)w功于depmod
命令,depmod
命令會(huì)生成模塊的依賴信息,保存在/lib/modules/5.10.111-64-generic/modules.dep
文件中。其中,5.10.111-64-generic是內(nèi)核源碼版本。查看該文件可以發(fā)現(xiàn)vser模塊所依賴的模塊。
# cat /lib/modules/5.10.111-64-generic/modules.dep
......
extra/vser.ko: extra/dep.ko
extra/dep.ko:
- 兩個(gè)模塊存在依賴關(guān)系,如果分別編譯兩個(gè)模塊,會(huì)出現(xiàn)類似下面的警告信息,并且即便加載順序正確,加載也不會(huì)成功 :
WARNING: "expfun" [/home/ubuntu/driver/module/vser.ko] undefined!
WARNING: "expval" [/home/ubuntu/driver/module/vser.ko] undefined!
# sudo insmod dep.ko
# sudo insmod vser.ko
insmod:error inserting 'vser.ko': -1 Invalid parameters
這是因?yàn)樵诰幾gvser
模塊時(shí)在內(nèi)核的符號(hào)表中找不到expval
和expfun
的項(xiàng),而vser
模塊又完全不知道dep
模塊的存在。
解決這個(gè)問(wèn)題的方法是將兩個(gè)模塊放在一起編譯,或者將dep模塊放在內(nèi)核源碼中,先在內(nèi)核源碼下編譯完所有的模塊,再編譯vser模塊。
- 卸載模塊時(shí)要先卸載vser模塊,再卸載dep模塊,否則會(huì)因?yàn)閐ep模塊被vser模塊使用而不能卸載 。
內(nèi)核將會(huì)創(chuàng)建模塊依賴關(guān)系的鏈接,只有當(dāng)依賴于這個(gè)模塊的鏈表為空時(shí),模塊才能被卸載.
-
模塊
+關(guān)注
關(guān)注
7文章
2735瀏覽量
47753 -
內(nèi)核
+關(guān)注
關(guān)注
3文章
1382瀏覽量
40427 -
Linux
+關(guān)注
關(guān)注
87文章
11345瀏覽量
210403
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
linux 了解內(nèi)核模塊的原理 《Rice linux 學(xué)習(xí)開發(fā)》
![linux 了解<b class='flag-5'>內(nèi)核模塊</b>的原理 《Rice linux 學(xué)習(xí)開發(fā)》](https://file.elecfans.com/web1/M00/9C/BA/o4YBAF0tMVeATu_xAAA0I2O0aJ8666.png)
Linux 內(nèi)核模塊工作原理及內(nèi)核模塊編譯案例
![Linux <b class='flag-5'>內(nèi)核模塊</b>工作原理及<b class='flag-5'>內(nèi)核模塊</b>編譯案例](https://file.elecfans.com/web1/M00/C7/3B/o4YBAF9qpsyACZgaAABwEWXfsvI775.png)
Linux內(nèi)核模塊間通訊方法
![Linux<b class='flag-5'>內(nèi)核模塊</b>間通訊方法](https://file1.elecfans.com/web2/M00/89/4E/wKgaomSAQsyAOh-6AADd7_xq52A238.png)
Linux內(nèi)核模塊程序結(jié)構(gòu)
Linux內(nèi)核模塊簡(jiǎn)介
內(nèi)核模塊的原理以及其模塊編寫
![<b class='flag-5'>內(nèi)核模塊</b>的原理以及其<b class='flag-5'>模塊</b>編寫](https://file1.elecfans.com//web2/M00/A7/20/wKgZomUMQoaARtrKAABMAQ5es0A389.png)
什么是內(nèi)核模塊?如何編寫一個(gè)簡(jiǎn)單的模塊?
什么是 Linux 內(nèi)核模塊?
嵌入式LINUX系統(tǒng)內(nèi)核和內(nèi)核模塊調(diào)試教程
![嵌入式LINUX系統(tǒng)<b class='flag-5'>內(nèi)核</b>和<b class='flag-5'>內(nèi)核模塊</b>調(diào)試教程](https://file.elecfans.com/web1/M00/CE/DC/pIYBAF-lGRiAGlMhAAIcOnWxy7I142.png)
如何在Petalinux創(chuàng)建Linux內(nèi)核模塊?
嵌入式LINUX系統(tǒng)內(nèi)核和內(nèi)核模塊調(diào)試
![嵌入式LINUX系統(tǒng)<b class='flag-5'>內(nèi)核</b>和<b class='flag-5'>內(nèi)核模塊</b>調(diào)試](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評(píng)論