五、Linux內核模塊開發

Linux的模塊驅動 函數

 

  1. 接下來寫個最簡單的驅動程序,就像程序語言的hello world程序。
  2. 首先是:hello.c的代碼:

    這是個最簡單的驅動程序。就是打印hello的信息。驅動程序和咱們的程序語言結果有點不大同樣。驅動模塊的入口是倒數第二行的module_init()的函數。驅動模塊的出口是module_exit()的函數。 spa

3.接着是makfile文件:命令行

這也是一個很簡單的Makefile文件了。Obj-m後面跟的是咱們的最終目標依賴的文件hello.o。第三行的KDIR是咱們編譯進的內核的路徑。All是執行make獲得的目標,$(KDIR)指定內核的路徑,就是第三行的路徑。M=$(PWD)是模塊存放的路徑。接着就是清除生成的文件的命令。 3d

4.make的執行過程: blog

從上面的執行的過程,咱們能夠看到makefile的執行的過程。 字符串

 

 

 

若是在一個工程裏,當有兩個.c文件的時候的編寫: it

Hello.c: io

Function.c: 編譯

Makefile修改成: function

最後編譯的結果以下圖:

 

 

 

 

 

內核模塊的安裝和卸載:

insmod hello.ko

卸載內核模塊:

rmmod hello(卸載的時候不用加.ko)

查看模塊:

lsmod

 

執行的結果:

注意:內核模塊只有當沒有用戶用時才能夠卸載,如上圖:咱們的test是沒有被使用,而fuse有兩個用戶在使用。咱們試着卸載這兩個內核模塊的截圖:

 

 

 

內核模塊的可選的信息:模塊申明、模塊參數、符號信息。

模塊的申明:

    MODULE_LICENSE("遵照的協議")

申明該模塊遵照的許可證協議,如:"GPL"、"GPL v2"等。

    MODULE_AUTHOR("做者")

    申明模塊的做者

    MODULE_DESCRIPTION("該模塊的功能描述")

    MODULE_VERSION("v1.0")

申明模塊的版本

 

模塊申明可讓讀者知道該模塊所遵照的協議,增長模塊代碼的可讀性。

 

 

只是一個提示,增長可讀性的做用。

 

模塊參數的傳遞:

在咱們的應用程序中:int main(int argc,char** argv):argc表示命令行輸入的參數個數,argv中保存輸入端的參數。

那麼咱們的內核模塊中是怎麼傳入參數的呢?:

 

模塊參數跟咱們程序語言的參數有點不大同樣,除了用通常的數據類型來申明變量參數,咱們還得用module_param()這個宏來指定它是模塊參數:

Module_param(name,type,perm):

Name:變量的名稱

Type:變量的類型,bool,int,charp。

Perm:訪問權限。S_IRUGO:讀權限。S_IWUSR:寫權限。

例如:

Int a=33;

Char *st;

Module_param(a,int ,S_IRUGO);

Module_param(st,charp,S_IRUGO);

 

下面是執行的實例:

咱們定義了一個a=99;而後在14行打印出來。運行的結果:

上面是執行的過程,咱們也能夠在執行的時候給它加參數:

字符串也是同樣:

運行的結果:

 

 

最後是符號導出:

符號導出的實例:

修改Makefile:

 

修改function.c爲:

 

執行的過程:

 

同時產生了兩個.ko模塊。

當咱們去安裝hello.ko的時候,出現了這個錯誤:未定義的符號:

這是由於咱們程序中的extern int function();如今的系統中不存在這個函數。那是否是得先insmod function.ko呢!?

雖然系統已經出現了function函數,但是系統仍是找不到。能夠看出錯誤依然存在。

 

這就是模塊導出的問題:當咱們要去使用一個模塊裏面的變量,函數的時候,必須使用符號導出。也就是把變量和函數輸出到咱們的系統當中,使整個系統均可以使用。

修改function.c爲:

用EXPORT_SYMBOL()來申明,個人function是能夠被系統的其餘模塊使用的。不過,咱們應該先編譯function.ko,在編譯hello.ko。結果:

這就是符號輸出的使用。

總結與應用程序的區別:

內核的打印:

Printf和printk都是打印信息的。可是printk還有級別打印:

Hello.c:

 

輸出結果:

結果只有KERN_EMERG級別的纔在屏幕打印出來。這樣的打印級別,咱們能夠控制在那些地方能夠打印什麼。固然,咱們也能夠用輸入來代替級別。例如上面的"<0>",就是KERN_EMER。

 

相關文章
相關標籤/搜索