linux設備驅動編程-初探(2)--在內核中構造和運行模塊

【參考資料】:

1:O'REILLY 寫的《LINUX 設備驅動程序》第三版

2:http://hi.baidu.com/freshwater2009/blog/item/9dc7a0c0b4ed27100ff47730.html 

3:http://blog.csdn.net/sunnyclub/archive/2009/07/24/4377305.aspx

在真正進入編寫linux下的設備驅動程序之前,我覺得有必要把相關的基礎知識看仔細,理解清楚,然後還需要將所涉及到的相關環境,代碼版本也需要一一搞清楚,這樣才能準備好,養成良好的習慣,以致以後在實際的開發中,不要因爲之前準備工作的不足,發生意想不到的錯誤。廢話不多說,直接上實用的。。。。

【成爲2.6.x內核構造模塊的條件】

1:從kernel.org網站下載一個”主線“內核,安裝到自己的系統中【目前內核最新版本2.6.34】;

2:還必須要在自己的內核中構造好自己的內核源代碼樹;

這裏我的理解是:首先爲什麼要成爲內核的模塊,因爲之後我們對於設備的驅動程序都是以模塊話註冊到內核中去的,作爲一個內核的模塊,在操作系統的控制下,供應用程序及相關的代碼進行調用,保證了驅動程序的正確發揮其作用。爲什麼要模塊話?這個問題我想可以這麼說,驅動程序模塊化之後,可以將驅動程序部分的內容像一個部件一樣,可以自由的安裝(註冊)拆卸(卸載),保證對內核的其他模塊的干擾,也方便驅動開發人員與內核的其他開發人員依賴性降低。對於以上的第1點,下載一個主線內核,指的是從kernel.org網站中下載的標準內核源碼,我下載的版本是2.6.34,至於說安裝到自己的系統中,我用的是ubuntu8.10,內核版本是:2.6.27-16-generic.如何安裝”主線“內核到自己的系統中,可以參考以下網址:

http://hi.baidu.com/freshwater2009/blog/item/9dc7a0c0b4ed27100ff47730.html 

http://blog.csdn.net/sunnyclub/archive/2009/07/24/4377305.aspx

中寫的文章,安裝完成之後,基本的linux設備驅動程序所需要的內核源代碼樹也就建成了。

嘗試運行內核模塊】

使用一個示例來運行任何模塊化驅動程序,在linux下編寫的驅動一般都是以模塊化在內核中運行。在之前已經設定好示例相關的環境,接下去按照書上一個示例來進行理解:

#include
#include

MODULE_LICENSE(“Dual BSD/GPL”) /* special MARCO, register free license */

static int hello_init(void)      { printk(KERN_ALERT "<1>Hello, world/n"); return 0; }  /* use the function when the module  is registed to the kernel */
static void hello_exit(void)  { printk(KERN_ALERT "<1>Goodbye cruel world/n"); }  /* use the function when the module  is exit from the kernel */

module_init(hello_init); /* 針對這2個特殊的宏,再另外一篇中總結一下 */

module_exit(hello_exit);

其中【KERN_ALERT】是一個定義優先級的字符串,這裏書上指明這裏這樣寫的原因是由於默認的優先級可能讓消息不會輸出到控制檯上,所以這裏需要提高優先級,使示例程序的消息輸出能夠顯示出來。

另外執行這個測試程序需要一個makefile文件:

obj-m := hello_printk.o

KDIR  := /lib/modules/$(shell uname -r)/build

PWD   := $(shell pwd)

default:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

這個makefile文件經過我的調查和理解如以下內容:

▲obj-m指出將要編譯成的內核模塊列表。.o格式文件會自動地有相應的.c文件生成(不需要顯示的羅列所有源代碼文件)

▲KDIR表示是內核源代碼的位置。在當前標準情況是鏈接到包含着正在使用內核對應源代碼的目錄樹位置。

▲PWD指示了當前工作目錄並且是我們自己內核模塊的源代碼位置

▲default是默認的編譯連接目標;即,make將默認執行本條規則編譯目標,除非程序員顯示的指明編譯其他目標。這裏的的編譯規則的意思是,在包含內核源代碼位置的地方進行make,然後之編譯$(PWD)(當前)目錄下的modules。這裏允許我們使用所有定義在內核源代碼樹下的所有規則來編譯我們的內核模塊。

編譯及運行代碼的過程:

1:轉到儲存該代碼的目錄,執行命令 cd hello_printk

2:執行命令: make 這樣在該目錄下會多出幾個文件 Module.symvers, hello_printk.ko, hello_printk.mod.c, hello_printk.mod.o, hello_printk.o, modules.order;

3:裝載該內核模塊,執行命令: sudo insmod ./hello_printk.ko 然後使用命令dmesg,在屏幕中可以看到 Hello world!出現了。

4:卸載該內核模塊的命令: rmmod hello_printf 然後再使用命令dmesg,在屏幕中可以看到 Goodbye, world!出現了。

以上就是在linux內核中如何加載一個模塊和卸載一個模塊的方法。設備驅動程序也是通過這樣使之成爲一個模塊,然後向內核進行加載和卸載的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章