本系列參考陳學(xué)松的《深入Linux設(shè)備驅(qū)動(dòng)程序內(nèi)核機(jī)制》
Linux內(nèi)核模塊形式上以.ko文件存在,概念上類似于Windows的動(dòng)態(tài)鏈接庫(kù)dll,內(nèi)核模塊可以在系統(tǒng)運(yùn)行期間動(dòng)態(tài)擴(kuò)展系統(tǒng)功能而無(wú)須重新編譯一個(gè)新的內(nèi)核鏡像并重啟系統(tǒng),這一特性為內(nèi)核開(kāi)發(fā)者提供了極大的便利。
1. 內(nèi)核模塊的動(dòng)態(tài)編譯和靜態(tài)編譯 首先得了解兩者的區(qū)別,靜態(tài)編譯模塊直接進(jìn)內(nèi)核鏡像,動(dòng)態(tài)編譯模塊生成.ko文件。本文主要討論模塊的動(dòng)態(tài)加載。 參考一個(gè)簡(jiǎn)單的實(shí)例 http://www./Linux/2011-09/42068.htm
2 內(nèi)核模塊.ko的文件格式ELF 用命令file查看,ko文件,顯示 ELF 32-bit LSB relocatable ... ... Linux下常見(jiàn)的可執(zhí)行文件都是以ELF的形式存在。
section是ELF的主體,位于文件視圖中間部分的一個(gè)連續(xù)區(qū)域,模塊被加載時(shí),被分配到一塊內(nèi)存區(qū)域。
3 內(nèi)存視圖 (HDR視圖) 用戶空間程序insmod首先通過(guò)文件系統(tǒng)接口讀取內(nèi)存模塊的文件數(shù)據(jù),放在一塊用戶空間的存儲(chǔ)區(qū)域,然后通過(guò)系統(tǒng)調(diào)用sys_init_module和里面的load_module,后者將vmalloc分配一塊內(nèi)存空間,copy_from_user復(fù)制數(shù)據(jù),在內(nèi)核空間構(gòu)造出ELF的內(nèi)存視圖。 之后,內(nèi)存視圖留下CORE section部分搬移到一個(gè)最終的內(nèi)存地址,這部分?jǐn)?shù)據(jù)是模塊在系統(tǒng)中整個(gè)存活期會(huì)使用到的數(shù)據(jù)。
4 INIT和CORE 根據(jù)ELF spec,標(biāo)記有SHF_ALLOC的section表示在模塊的運(yùn)行過(guò)程中,需要占用內(nèi)存空間,其分為兩大類,INIT和CORE,INIT section所在的內(nèi)存區(qū)域會(huì)被最終釋放,CORE section中的數(shù)據(jù)將一直駐留在內(nèi)存中。
5 模塊的“未解決的引用” (unsolved symbol) 內(nèi)核模塊ELF中的“未解決的引用”符號(hào),是指當(dāng)模塊的編譯工具鏈對(duì)模塊進(jìn)行鏈接生成.ko文件時(shí),對(duì)于模塊中調(diào)用的一些函數(shù),鏈接工具無(wú)法在該模塊的所有目標(biāo)文件中找到這個(gè)函數(shù)的具體指令碼,只能暫時(shí)對(duì)這個(gè)函數(shù)標(biāo)記為“未解決的引用”,對(duì)它的處理將一直延續(xù)到內(nèi)核模塊被加載時(shí)從內(nèi)核或者其他模塊找到這個(gè)函數(shù)。
6 模塊導(dǎo)出符號(hào) (EXPORT_SYMBOL) 模塊不僅使用內(nèi)核和其他模塊導(dǎo)出的符號(hào),而且向外部導(dǎo)出自己的符號(hào)供內(nèi)核使用。
7. 模塊的參數(shù) 可以向內(nèi)核模塊傳遞一些參數(shù),比如 # insmod devdemo.ko dolphin=10 bobcat=5 驅(qū)動(dòng)程序里應(yīng)聲明模塊參數(shù)如下,
[cpp] view plaincopy
8. 模塊的版本控制 內(nèi)核和模塊之間協(xié)商出一種機(jī)制確保不同版本的模塊中的接口可以使用,Linux對(duì)此的解決方案是使用接口的校驗(yàn)和,也叫CRC校驗(yàn)碼。基本思想就是根據(jù)函數(shù)的參數(shù)生成一個(gè)大小為4個(gè)字節(jié)的CRC校驗(yàn)碼,當(dāng)雙方的校驗(yàn)碼相等時(shí)視為相同接口,否則為不同接口。內(nèi)核通過(guò)CONFIG_MODVERSIONS啟用版本控制特性。模塊源碼所在目錄下的.mod.c文件記錄了內(nèi)核導(dǎo)出的函數(shù)接口和其對(duì)應(yīng)的CRC校驗(yàn)碼。 |
|