最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(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)遵守國家法律
荣成市| 浏阳市| 平罗县| 桐柏县| 偃师市| 禹城市| 阜阳市| 临清市| 义乌市| 河北区| 上饶市| 苍南县| 崇文区| 茌平县| 沧源| 云浮市| 万载县| 涞源县| 沈阳市| 连云港市| 砚山县| 长岛县| 循化| 满城县| 寿阳县| 巴里| 灌阳县| 盘山县| 历史| 梁河县| 吴江市| 新津县| 迁西县| 商洛市| 如东县| 许昌县| 萨嘎县| 普兰店市| 陇西县| 宁城县| 姚安县|