linux內(nèi)核自己添加模塊(內(nèi)核版本:3.0.101)

做內(nèi)核驅(qū)動(dòng)第一步都是學(xué)習(xí)如何添加模塊,這是基礎(chǔ),有了這個(gè)基礎(chǔ),剩下就是寫代碼了。

  由于2.4到2.6內(nèi)核版本的更新,無論是系統(tǒng)調(diào)用還是模塊添加機(jī)制都有了巨大的變化,本人也因此飽經(jīng)挫折,最后在3.0.101版本的內(nèi)核下成功。作為開源運(yùn)動(dòng)的支持者,自認(rèn)為有必要把自己的經(jīng)歷分享出來,以供后來學(xué)習(xí)者分享與交流。

再次聲明,本博客只分享我遇到了的問題,沒有交流的不代表不難或者不會(huì)遇到問題,只是我沒遇到,如果有閱讀本博客的朋友遇到了問題,非常歡迎大家一起討論,技術(shù)就是這么成長(zhǎng)的!

  關(guān)于添加模塊,步驟上還是那三步。

  1.編寫模塊函數(shù)

  編寫內(nèi)核模塊時(shí)必須要有的兩個(gè)函數(shù) :

  1> 加載 函數(shù):

  static int func1_init(void)

  2> 卸載函數(shù) 無返回值

  static void func2_exit(void)

  這里值得注意的是三點(diǎn),一是卸載函數(shù)必須是void,即無返回型,否則會(huì)報(bào)錯(cuò)。其二是推薦把加載函數(shù)改寫成static int __init func1_init(void),卸載函數(shù)同理。這里使用__init是利用2.6內(nèi)核以后的宏機(jī)制,具體機(jī)制。。。還在學(xué)習(xí)中。第三點(diǎn)就是人盡皆知的,加載函數(shù)的名字必須寫成*_init的樣子,卸載函數(shù)必須是*_exit的樣子。

  2.其次就是Makefile了。

  這方面的文章比較多,網(wǎng)上也講得非常詳細(xì),我就大概講一下模板和每步的意義。

obj-m := hello.o

kernel_path=/usr/src/linux-headers-$(shell uname -r)

all:

make -C $(kernel_path) M=$(PWD) modules

clean:

make -C $(kernel_path) M=$(PWD) clean

obj -m:= hello.o // 產(chǎn)生 hello 模塊的目標(biāo)

kernel_path // 定義內(nèi)核源文件目錄

all :

make -C $(kernel_path) M=$(PWD) modules

// 生成內(nèi)核模塊參數(shù)為內(nèi)核源代碼目錄以及模塊所在目錄

clean:

make -C $(kernel_path) M=$(PWD) clean

// 清除生成的模塊文件以及中間文件

這里就要尤為注意了,在2.6版本以后,引入了如下機(jī)制。2.6中模塊的編譯需要配置過的內(nèi)核源碼;編譯、連接后生成的內(nèi)核模塊后綴為.ko;編譯過程首先會(huì)到內(nèi)核源碼目錄下,讀取頂層的Makefile文件,然后再返回模塊源碼所在目錄。

接下來要講得就是最折磨人的改變了。

2.4內(nèi)核下, 執(zhí)行`cat /proc/ksyms`可看到內(nèi)核符號(hào)在名字后還跟隨著一串校驗(yàn)字符串,此校驗(yàn)字符串與內(nèi)核版本有關(guān)。在內(nèi)核源碼頭文件linux/modules 目錄下存在許多*.ver文件,這些文件起著為內(nèi)核符號(hào)添加校驗(yàn)后綴的作用,如ksyms.ver 文件里有一行 #define printk _set_ver(printk)。linux/modversions.h 文件會(huì)包含全部的 ver文件 。所以當(dāng)模塊包含linux/modversions.h文件后,編譯時(shí),模塊里使用的內(nèi)核符號(hào)實(shí)質(zhì)是帶有校驗(yàn)后綴的內(nèi)核符號(hào)。在加載模塊時(shí),如果模塊中所使用內(nèi)核符號(hào)的校驗(yàn)字符串與當(dāng)前運(yùn)行內(nèi)核所導(dǎo)出的相應(yīng)的內(nèi)核符號(hào)的校驗(yàn)字符串不一致,即當(dāng)前內(nèi)核空間并不存在模塊所使用的內(nèi)核符號(hào),就會(huì)出現(xiàn)"Invalid module format "的錯(cuò)誤。

為內(nèi)核符號(hào)添加校驗(yàn)字符串來驗(yàn)證模塊的版本與內(nèi)核的版本是否匹配是繁雜和浪費(fèi)內(nèi)核空間的;而且隨著SMP(對(duì)稱多處理器)、PREEMPT(可搶占內(nèi)核)等機(jī)制在2.6內(nèi)核的引入和完善,模塊運(yùn)行時(shí)對(duì)內(nèi)核的依賴不僅取決于內(nèi)核版本,還取決于內(nèi)核的配置,此時(shí)內(nèi)核符號(hào)的校驗(yàn)碼是否一致不能成為判斷模塊可否被加載的充分條件。2.6 內(nèi)核下,在linux/vermagic.h中定義有VERMAGIC_STRING,VERMAGIC_STRING不僅包含內(nèi)核版本號(hào),還包含有內(nèi)核使用的gcc版本,SMP與PREEMPT等配置信息。模塊在編譯時(shí),我們可以看到屏幕上會(huì)顯示"MODPOST"。在此階段, VERMAGIC_STRING會(huì)添加到模塊的modinfo段。 在內(nèi)核源碼目錄下scripts/mod/modpost.c文件中可以看到模塊后續(xù)處理部分的代碼。模塊編譯生成后,通過`modinfo mymodule.ko`命令可以查看此模塊的vermagic等信息。2.6 內(nèi)核下的模塊裝載器里保存有內(nèi)核的版本信息,在裝載模塊時(shí),裝載器會(huì)比較所保存的內(nèi)核vermagic與此模塊的modinfo段里保存的vermagic信息是否一致,兩者一致時(shí),模塊才能被裝載。譬如Fedora core 4 與core 2 使用的都是2.6 版本內(nèi)核, 在Fedore Core 2下去加載Fedora Core4下編譯生成的hello.ko,會(huì)出現(xiàn)"invalid module format" 錯(cuò)誤。

因此,細(xì)心的朋友注意到我給出的Makefile模板中編譯目標(biāo)是內(nèi)核源碼樹。這里必須是這樣,否則會(huì)出錯(cuò)。而且必須對(duì)應(yīng),即,如果你當(dāng)前內(nèi)核版本是3.0.101,就必須是以3.0.101的內(nèi)核源碼樹為目標(biāo)進(jìn)行編譯得到*.ko,否則會(huì)報(bào)錯(cuò)。反之亦然。兩者必須一一對(duì)應(yīng),這一點(diǎn)希望朋友們務(wù)必注意,否則會(huì)痛不欲生。

以上就是我學(xué)習(xí)這部分最痛苦最值得分享的部分了,希望可以幫到大家。

由于2.6下各位朋友肯定希望自己的模塊能兼容2.4下的模式,所以,我這里再提供一套Makefile,有IBM官方給出,值得學(xué)習(xí)。

# Makefile2.6
ifneq ($(KERNELRELEASE),)
#kbuild syntax. dependency relationshsip of files and target modules are listed here.
mymodule-objs := file1.o file2.o
obj-m := mymodule.o 
else
PWD  := $(shell pwd)
KVER ?= $(shell uname -r)
KDIR := /lib/modules/$(KVER)/build
all:
	$(MAKE) -C $(KDIR) M=$(PWD) 
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

endif

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評(píng)論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,860評(píng)論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評(píng)論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評(píng)論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,025評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,421評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,642評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,177評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,970評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,157評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,410評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評(píng)論 1 289
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,896評(píng)論 3 395
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,157評(píng)論 2 375

推薦閱讀更多精彩內(nèi)容