Linux內核分析(二)----內核模塊簡介|簡單內核模塊實現


Linux內核分析(二)

昨天我們開始了內核的分析,網上有很多人是用用源碼直接分析,這樣造成的問題是,大家覺得很枯燥很難理解,從某種意義上來說linux系統本身就是由一個個模塊構成的,所以我會結合內核模塊的設計,去分析內核,從而達到對linux內核的理解。

今天我們會分析到以下內容:

1.      Linux內核模塊簡介

2.      簡單內核模塊實現

 

l  Linux內核模塊簡介

1.       何為內核模塊

在上一篇博文中我們先通過內核配置,在配置的過程中我們對內核的組件進行了選擇(當然這個選擇決定了我們內核的大小),然后才生成了我們最終的內核,那么我們如果想添加組件,怎么辦?

最笨的方法是對內核進行重新配置,然后在重新編譯。這樣的話豈不是說我加一個組件就得重新編譯內核,這顯然不是很科學的方法,其實我們的linux內核提供在運行時可進行擴展的特性,這意味着當系統啟動並運行時,我們可以向內核添加或移除部分功能。

我們在運行時添加到內核中的代碼就被成為動態可加載內核模塊,我們簡稱為內核模塊。

2.       內核模塊的相關操作

a)        加載內核模塊:insmod

b)        卸載內核模塊:rmmod

c)        查看內核模塊:lsmod

3.       模塊聲明

a)        MODULE_LICENSE(“GPL”):內核可以識別的許可證有GPL(任意版本GNU通用公共許可證)、GPL v2

b)        MODULE_AUTHOR(“作者”):聲明作者信息可以不用

c)        MODULE_VERSION(“版本”):聲明版本信息也可以不用

d)        MODULE_DESCRIPTION(“功能描述”):聲明模塊功能,可不用

4.       模塊參數

我們可以在加載內核模塊的時候向其傳遞參數,以讓同一代碼達到不同的效果。當然我們的參數必須用module_param宏來聲明具體如下:

 1 module_param(name,type,perm) 

a)        name變量名

b)        type數據類型內核支持模塊參數類型有:boolinvboolbool的發轉,true變為falsefalse變為true)、charpchar類型指針值)、intlongshortuintulongushort

c)        perm常見的訪問許可值通常為S_IRUGOS_IWUSR。通常情況下將他們按位或

同時我們也可以用下面的宏聲明數組:

  1.             1 Module_param_array(name,type,num,perm) 

5.       模塊符號導出

當一個模塊要使用另一個模塊的函數(變量)的時候,要使用EXPORT_SYMBOL(符號名)或者EXPORT_SYMBOL_GPL(符號名)來申明。

注:EXPORT_SYMBOL_GPL()只適用於遵循GPL協議的模塊

l  簡單內核模塊實現

想必大家都記得我們在學習某種語言的時候,寫的第一個程序大部分都是輸出hello world,所以我接下來用我們剛才介紹的內核模塊去完成hello world

1.       內核模塊編寫

通過上面部分內容的介紹,要完成第一內核模塊不是很難,下面是自己的代碼。

  1.  1 #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);//該宏在模塊的目標代碼中增加一個特殊的段,用於說明內核初始化函數所在的位置
    14 module_exit(hello_exit);//跟上面的宏對立

2.       Makefile編寫

Makefile的編寫也比較簡單,要注意的地方代碼中已經說明。

 

1 obj-m := hello.o
2 DIRS :=/smbshare/linux-2.6.39///此處路徑為內核源碼路徑,該內核源碼必須要經過編譯,不然會報錯
3 all:
4 make -C $(DIRS) M=$(PWD) modules
5 clean:
6 rm -Rf*.o *.ko *.mod.c *.order *.symvers

 

經過了上面兩個步驟,我們然后編譯加載然后卸載我們的模塊進行試驗。

編譯:

加載:

查看:

卸載:

3.       Printk函數簡介

printk函數為內核打印函數,其和printf函數功能類似,不過比printf多了打印權限一共有8個級別,printk的日志級別定義如下(在include/linux/kernel.h中):

 

1 #define KERN_EMERG 0 //緊急事件消息,系統崩潰之前提示,表示系統不可用
2 #define KERN_ALERT  1 //報告消息,表示必須立即采取措施
3 #define KERN_CRIT    2 //臨界條件,通常涉及嚴重的硬件或軟件操作失敗
4 #define KERN_ERR     3 //錯誤條件,驅動程序常用KERN_ERR來報告硬件的錯誤
5 #define KERN_WARNING  4 //警告條件,對可能出現問題的情況進行警告
6 #define KERN_NOTICE 5 //正常但又重要的條件,用於提醒
7 #define KERN_INFO 6    //提示信息,如驅動程序啟動時,打印硬件信息
8 #define KERN_DEBUG 7 //調試級別的消息

 

今天的內容比較簡單,只是對內核模塊有了一個初步的了解,所以我今天在給大家推薦一個比較好用的工具,叫做exvim其將好多vim的工具進行了集成,個人感覺十分方便,就是換電腦什么的也不怕自己的配置丟失了。貼一張自己使用的圖,大家有興趣的可以去http://exvim.github.io/ 了解。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM