Linux內(nèi)核分析(二)內(nèi)核模塊簡(jiǎn)介和簡(jiǎn)單內(nèi)核模塊實(shí)現(xiàn)
一、Linux內(nèi)核模塊簡(jiǎn)介
1.?何為內(nèi)核模塊
在上一篇博文中我們先通過(guò)內(nèi)核配置,在配置的過(guò)程中我們對(duì)內(nèi)核的組件進(jìn)行了選擇(當(dāng)然這個(gè)選擇決定了我們內(nèi)核的大?。缓蟛派闪宋覀冏罱K的內(nèi)核,那么我們?nèi)绻胩砑咏M件,怎么辦?
最笨的方法是對(duì)內(nèi)核進(jìn)行重新配置,然后在重新編譯。這樣的話豈不是說(shuō)我加一個(gè)組件就得重新編譯內(nèi)核,這顯然不是很科學(xué)的方法,其實(shí)我們的linux內(nèi)核提供在運(yùn)行時(shí)可進(jìn)行擴(kuò)展的特性,這意味著當(dāng)系統(tǒng)啟動(dòng)并運(yùn)行時(shí),我們可以向內(nèi)核添加或移除部分功能。
我們?cè)谶\(yùn)行時(shí)添加到內(nèi)核中的代碼就被成為動(dòng)態(tài)可加載內(nèi)核模塊,我們簡(jiǎn)稱(chēng)為內(nèi)核模塊。
2.?內(nèi)核模塊的相關(guān)操作
a)?加載內(nèi)核模塊:insmod
b)?卸載內(nèi)核模塊:rmmod
c)?查看內(nèi)核模塊:lsmod
3.?模塊聲明
a)?MODULE_LICENSE(“GPL”):內(nèi)核可以識(shí)別的許可證有GPL(任意版本GNU通用公共許可證)、GPL v2等
b)?MODULE_AUTHOR(“作者”):聲明作者信息可以不用
c)?MODULE_VERSION(“版本”):聲明版本信息也可以不用
d)?MODULE_DESCRIPTION(“功能描述”):聲明模塊功能,可不用
4.?模塊參數(shù)
我們可以在加載內(nèi)核模塊的時(shí)候向其傳遞參數(shù),以讓同一代碼達(dá)到不同的效果。當(dāng)然我們的參數(shù)必須用module_param宏來(lái)聲明具體如下:
1 module_param(name,type,perm)
a)?name:變量名
b)?type:數(shù)據(jù)類(lèi)型內(nèi)核支持模塊參數(shù)類(lèi)型有:bool、invbool(bool的發(fā)轉(zhuǎn),true變?yōu)閒alse,false變?yōu)閠rue)、charp(char類(lèi)型指針值)、int、long、short、uint、ulong、ushort、
c)?perm:常見(jiàn)的訪問(wèn)許可值通常為S_IRUGO和S_IWUSR。通常情況下將他們按位或
同時(shí)我們也可以用下面的宏聲明數(shù)組:
1 Module_param_array(name,type,num,perm)
5.?模塊符號(hào)導(dǎo)出
當(dāng)一個(gè)模塊要使用另一個(gè)模塊的函數(shù)(變量)的時(shí)候,要使用EXPORT_SYMBOL(符號(hào)名)或者EXPORT_SYMBOL_GPL(符號(hào)名)來(lái)申明。
注:EXPORT_SYMBOL_GPL()只適用于遵循GPL協(xié)議的模塊
【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【865977150】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。?!

二、簡(jiǎn)單內(nèi)核模塊實(shí)現(xiàn)
想必大家都記得我們?cè)趯W(xué)習(xí)某種語(yǔ)言的時(shí)候,寫(xiě)的第一個(gè)程序大部分都是輸出hello world,所以我接下來(lái)用我們剛才介紹的內(nèi)核模塊去完成hello world。
1.?內(nèi)核模塊編寫(xiě)
通過(guò)上面部分內(nèi)容的介紹,要完成第一內(nèi)核模塊不是很難,下面是自己的代碼。
#include<linux/init.h>
2 #include<linux/module.h>
3 MODULE_LICENSE("GPL");
4 staticint hello_init(void)
5 {
6 printk("<0> hello world\n");
7 return0;
8 }
9 staticvoid hello_exit(void)
10 {
11 printk("<0> goodbye\n");
12 }
13 module_init(hello_init);//該宏在模塊的目標(biāo)代碼中增加一個(gè)特殊的段,用于說(shuō)明內(nèi)核初始化函數(shù)所在的位置
14 module_exit(hello_exit);//跟上面的宏對(duì)立
復(fù)制代碼
2.?Makefile編寫(xiě)
Makefile的編寫(xiě)也比較簡(jiǎn)單,要注意的地方代碼中已經(jīng)說(shuō)明。
obj-m := hello.o
2 DIRS :=/smbshare/linux-2.6.39///此處路徑為內(nèi)核源碼路徑,該內(nèi)核源碼必須要經(jīng)過(guò)編譯,不然會(huì)報(bào)錯(cuò)
3 all:
4 make -C $(DIRS) M=$(PWD) modules
5 clean:
6 rm -Rf*.o *.ko *.mod.c *.order *.symvers
經(jīng)過(guò)了上面兩個(gè)步驟,我們?nèi)缓缶幾g加載然后卸載我們的模塊進(jìn)行試驗(yàn)。
編譯:

加載:

查看:

卸載:

3.?Printk函數(shù)簡(jiǎn)介
printk函數(shù)為內(nèi)核打印函數(shù),其和printf函數(shù)功能類(lèi)似,不過(guò)比printf多了打印權(quán)限一共有8個(gè)級(jí)別,printk的日志級(jí)別定義如下(在include/linux/kernel.h中):
#define KERN_EMERG 0 //緊急事件消息,系統(tǒng)崩潰之前提示,表示系統(tǒng)不可用
2 #define KERN_ALERT ?1 //報(bào)告消息,表示必須立即采取措施
3 #define KERN_CRIT ? ?2 //臨界條件,通常涉及嚴(yán)重的硬件或軟件操作失敗
4 #define KERN_ERR ? ? 3 //錯(cuò)誤條件,驅(qū)動(dòng)程序常用KERN_ERR來(lái)報(bào)告硬件的錯(cuò)誤
5 #define KERN_WARNING ?4 //警告條件,對(duì)可能出現(xiàn)問(wèn)題的情況進(jìn)行警告
6 #define KERN_NOTICE 5 //正常但又重要的條件,用于提醒
7 #define KERN_INFO 6 ? ?//提示信息,如驅(qū)動(dòng)程序啟動(dòng)時(shí),打印硬件信息
8 #define KERN_DEBUG 7 //調(diào)試級(jí)別的消息
今天的內(nèi)容比較簡(jiǎn)單,只是對(duì)內(nèi)核模塊有了一個(gè)初步的了解,所以我今天在給大家推薦一個(gè)比較好用的工具,叫做exvim其將好多vim的工具進(jìn)行了集成,個(gè)人感覺(jué)十分方便,就是換電腦什么的也不怕自己的配置丟失了。貼一張自己使用的圖,大家有興趣的可以去http://exvim.github.io/?了解。
