從linux核心說起~模組篇(四)

來源:互聯網
上載者:User

這一節主要內容講解linux核心的模組機制。主要參考經典書籍《linux device drivers》。

 

①    大多數小規模及中規模的應用程式從頭到尾執行單個任務,而模組卻只是預先註冊自己一邊服務於將來的某個請求,然後他的初始化函數就立即結束了。

模組僅僅被連結到核心,因此它能調用的函數僅僅是由核心匯出的那些函數,而不存在任何可連結的函數庫。所以源檔案不能包含常用的標頭檔。核心模組只能使用作為核心一部分的函數。大多數相關的標頭檔儲存在核心源碼樹的(/home/sml/linux2.6.37.4/)標頭檔聲明裡,include/linux和include/asm目錄中。

②    最簡單的模組構造(helloworld)

1.     在虛擬機器上面建立hello.c和Makefile。

2.     Hello.c原始碼如下:

#include <linux/module.h>

#include <linux/init.h>

#include <linux/sched.h>

#include <linux/kernel.h>

MODULE_LICENSE("GPL");

 

static int hello_init(void)

{

       printk(KERN_EMERG "hello world!\n");

       return 0 ;

}

 

static void hello_exit(void)

{

       printk(KERN_EMERG "crule world!\n");

}

module_init(hello_init);

module_exit(hello_exit);

3. makefile檔案內容

obj-m := hello.o

4. 虛擬機器上必須要有核心源碼樹,我的在/home/sml/linux2.6.37.4,因為我們構造的模組最終要啟動並執行linux2.6.37.4核心上面,所以要在核心源碼樹下面編譯模組。執行make -C/home/sml/linux2.6.37.4 M=$PWD modules.

root@sml-VirtualBox:/home/sml/nfs_server#make -C /home/sml/linux-2.6.37.4 M=$PWD modules

make:進入目錄'/home/sml/linux-2.6.37.4'

  CC[M]  /home/sml/nfs_server/hello.o

  Buildingmodules, stage 2.

  MODPOST 1modules

  CC      /home/sml/nfs_server/hello.mod.o

  LD[M]  /home/sml/nfs_server/hello.ko

make:離開目錄“/home/sml/linux-2.6.37.4”

執行完命令,產生hello.ko模組。

5. make-C /home/sml/linux2.6.37.4 M=$PWD modules解析。

前面講到,模組依賴於核心匯出的一些符號,主要的標頭檔聲明在include/linux和include/asm目錄下。所以編譯模組肯定要依賴於核心源碼樹。-C 表示make切換到指定目錄。M是makefile中的一個變數,指定為目前的目錄,也就是hello.c 的所在目錄。Modules指向obj-m變數中設定的模組,就是hello模組。因為在hello.c的Makefile中沒有指定核心源碼樹的目錄,所以-C來告訴make核心源碼樹的路徑。(這個地方理解的不是很透徹,但是我們要明白:核心模組的編譯是依賴於核心源碼樹的。)。

6. 模組的裝載和卸載

裝載命令:insmod;卸載命令:rmmod;查看模組命令:lsmod;查看模組資訊:modinfo;

我們把上面的編譯的模組放在根檔案系統上面,然後執行裝載命令,即可看到我們要列印的資訊。如何放在開發板的根檔案系統上,請參見:NFS實現開發板和虛擬機器之間的檔案分享權限設定。Make工具的使用方法請參見:MAKE工具介紹。

③    核心符號表(模組層疊技術)

Insmod使用公用核心符號表來解析模組中未定義的符號。公用核心符號表中包含了所有的全域核心項(變數和函數)的地址,這是實現模組化驅動程式的必須的。當模組被裝入核心後,它所匯出的任何符號都會成為核心符號表的一部分。新模組可以使用有我們自己的模組匯出的符號。這樣我們可以在其他模組上層疊新的模組(模組層疊技術)。符號匯出實現模組之間的資源共用。驅動程式的模組層疊可以理解為抽象層為硬體驅動層提供符號,抽象層和硬體驅動層就相當於兩個(或多個)模組。我們可以將模組劃分為多個層,縮短開發時間。

符號匯出方法:

                       EXPORT_SYMBOL(name);

                       EXPORT_SYMBOL_GPL(name);

④    初始化和關閉

module_init(hello_init);

module_exit(hello_exit);

初始化和關閉是強制性的,是模組被insmod和rmmod時執行的。

⑤    模組的參數

核心允許驅動程式指定參數,而這些參數可以在裝載驅動程式模組時改變。驅動程式參數包括裝置編號,以及一些其他的控制驅動程式操作方式的參數。如:

insmod hellop howmany=10 whom=”sml”

在模組中,參數的申請方法,包含標頭檔

#include <moduleparam.h>

格式為:

Module_param(name,type,s perm);

如:

Module_param(howmany,int,S_IRUGO);

S_IRUGO表示任何人可讀取參數,但是不能更改;

S_IRUGO|S_IWUSR表示允許root使用者修改該參數。大多數情況下,我們不應該讓模組參數可寫。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.