国产精品天干天干,亚洲毛片在线,日韩gay小鲜肉啪啪18禁,女同Gay自慰喷水

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

一文講解內(nèi)核模塊依賴!

2023-04-18 15:53 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿

前言

不知大家有沒有想過,在一個(gè)內(nèi)核模塊代碼中,會(huì)用到printk函數(shù),而這個(gè)函數(shù)不是我們實(shí)現(xiàn)的,它是內(nèi)核代碼的一部分,但我們?yōu)槭裁茨軌蚓幾g通過呢?

我們的代碼之所以能夠編譯通過,是因?yàn)閷?duì)模塊的編譯僅僅是編譯,并沒有鏈接

編譯出來的.ko文件是一個(gè)普通的ELF文件,使用file命令和nm命令,我們可以看到相關(guān)的信息:

vser_initvser_exit分別是模塊的入口函數(shù)和出口函數(shù),使用nm命令查看模塊目標(biāo)文件的符號(hào)信息時(shí),可以看到vser_exitvser_init的符號(hào)類型是t,表示它們是函數(shù)。

printk的 符號(hào)類型是U,表示它是一個(gè)未決符號(hào)。意思是說在編譯階段不知道這個(gè)符號(hào)的地址,因?yàn)樗欢x在其他文件中,沒有放在模塊代碼一起編譯。

那printk函數(shù)的地址問題怎么解決呢?答案是用EXPORT_SYMBOL宏將printk導(dǎo)出即可。

EXPORT_SYMBOL導(dǎo)出符號(hào)

大致原理:利用EXPORT_SYMBOL宏生成一個(gè)特定的結(jié)構(gòu)并放在ELF文件的一個(gè)特定段中,在內(nèi)核的啟動(dòng)過程中,會(huì)將符號(hào)的確切地址填充到這個(gè)結(jié)構(gòu)的特定成員中。

模塊加載時(shí),加載程序?qū)⑷ヌ幚砦礇Q符號(hào),在特殊段中搜索符號(hào)的名字,如果找到,則將獲得的地址填充在被加載模塊的相應(yīng)段中,這樣符號(hào)的地址就可以確定。

使用這種方式處理未決符號(hào),其實(shí)相當(dāng)于把鏈接的過程推后,進(jìn)行了動(dòng)態(tài)鏈接,和普通的應(yīng)用程序使用共享庫函數(shù)的道理是類似的??梢园l(fā)現(xiàn),內(nèi)核將會(huì)有大量的符號(hào)導(dǎo)出,為模塊提供了豐富的基礎(chǔ)設(shè)施。


【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【749907784】整理了一些個(gè)人覺得比較好的學(xué)習(xí)書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。。ê曨l教程、電子書、實(shí)戰(zhàn)項(xiàng)目及代碼)??


內(nèi)核模塊依賴

通常情況下,一個(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

dep.c

Makefile關(guān)鍵處:

上述代碼中,dep.c定義了一個(gè)變量expval和一個(gè)函數(shù)expfun,并分別用EXPORT_SYMBOLEXPORT_SYMBOL_GPL導(dǎo)出。而vser.c里則調(diào)用了dep.c的變量和函數(shù),編譯安裝后:

從輸出信息中可以看到,vser.c正確引用到了dep.c的變量和函數(shù)。

這里有三點(diǎn)重要說明:

  • 如果使用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模塊所依賴的模塊。

兩個(gè)模塊存在依賴關(guān)系,如果分別編譯兩個(gè)模塊,會(huì)出現(xiàn)類似下面的警告信息,并且即便加載順序正確,加載也不會(huì)成功:

這是因?yàn)樵诰幾gvser模塊時(shí)在內(nèi)核的符號(hào)表中找不到expvalexpfun的項(xiàng),而vser模塊又完全不知道dep模塊的存在。

解決這個(gè)問題的方法是將兩個(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í),模塊才能被卸載.


原文作者:嵌入式Linux充電站




一文講解內(nèi)核模塊依賴!的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
扎鲁特旗| 新河县| 云南省| 普兰县| 石首市| 龙胜| 曲麻莱县| 丰台区| 罗定市| 论坛| 合肥市| 韶关市| 泾源县| 房产| 连城县| 马山县| 临海市| 什邡市| 运城市| 浪卡子县| 锡林浩特市| 汉阴县| 阿拉善左旗| 天台县| 新龙县| 西和县| 兴义市| 南郑县| 甘肃省| 吴忠市| 呼伦贝尔市| 信阳市| 仪征市| 沂源县| 舞钢市| 宜昌市| 丰城市| 绩溪县| 锡林郭勒盟| 古交市| 高邑县|