拆解最簡單的核心模組(隨記)

2021-10-10 01:42:04 字數 2866 閱讀 5556

#include

#include

static

int __init hello_init

(void

)static

void __exit hello_exit

(void

)module_license

("dual bsd/gpl");

module_author

("zhou");

module_init

(hello_init)

;module_exit

(hello_exit)

;

#define __init		__section(.init.text) __cold notrace

#define __exit __section(.exit.text) __exitused __cold notrace

意思是,將**存放在初始化**區域。對於模組來說,假如要載入模組,它會載入到核心的初始化區域(記憶體),執行完成後,它們都會釋放,從而節省了一部分記憶體。

被修飾的**,最終被編譯器鏈結到 .init.text段中。

printk函式是linux內部的函式,而printf是c庫的函式。在linux剛執行的時候,c語言所需要的環境還沒完成初始化,即對堆疊的初始化等,所以,無法執行printf列印核心資訊,只能使用printk來列印。在模組中時候使用,情況也類似,我們編譯模組時候,沒有鏈結到c庫函式,c庫函式是在gcc的目錄下。

在使用printk時候,我們還可以設定列印級別,可以理解為優先順序。根據不同的情況來設定它的級別,數字越小,優先順序肯定越高,同時也意味著也緊急。

#define kern_emerg        "<0>" 

/* system is unusable */

#define kern_alert "<1>"

/* action must be taken immediately */

#define kern_crit "<2>"

/* critical conditions */

#define kern_err "<3>"

/* error conditions */

#define kern_warning "<4>"

/* warning conditions */

#define kern_notice "<5>"

/* normal but significant condition */

#define kern_info "<6>"

/* informational */

#define kern_debug "<7>"

/* debug-level messages */

printk(kern_debug "hello world enter!\n");

**中的kern_debug感覺在printk有點突兀,其實它就是乙個巨集定義,乙個字串,我們可以等效為:printk(「<7>」 "hello world enter!\n");printk("<7>hello world enter!\n");

從2.4.10版本核心開始,模組必須通過module_license巨集宣告此模組的許可證,否則在載入此模組時,會收到核心被汙染 「kernel tainted」 的警告。從linux/module.**件中可以看到,被核心接受的有意義的許可證有 「gpl」,「gpl v2」,「gpl and additional rights」,「dual bsd/gpl」,「dual mpl/gpl」,「proprietary」。

至於為什麼要這麼做,可以理解為這是linux作為開源的一種手段吧,記住末尾要宣告它的許可證就行了。

module_init、 module_exit

這其實也是兩個巨集,至於為什麼不寫成大寫,我也拿寫核心的沒辦法,記住它的外形就好。

它的功能是什麼呢?將模組載入到對應核心的段中。其實,它本質作用的是乙個「搬運工」,將模組的資訊搬到核心中,什麼時候被觸發呢?通過insmodrmmod命令。由於**被宣告為__init和__exit,所以,載入後只執行一遍,就釋放了。

這些巨集定義在下

module_author

(name)

定義驅動的程式設計者,name為string

module_license

(license)

定義驅動的license,一般為gpl,或相關公司的license

module_description

(desc)

對驅動程式的描述,string

module_supported_device

(name)

驅動程式所支援的裝置,string

module_parm

(var,type)

提供在執行時通過控制台將引數傳遞給模組 (在insmod時)

程式設計ko檔案後,可以通過modinfo命令檢視模組的資訊。

ko檔案是kernel object,也就是核心物件,是給核心使用的,不像應用程式那樣子。我們不能使用gcc來獲取ko檔案,需要通過make來編譯。make的時候,它需要使用核心原始碼的一些資訊,比如,核心的版本號等等,還有原始碼當中的標頭檔案。所以,我們makefile需要指定linux原始碼的目錄。

這時候,你需要輸入dmesg命令。其實ubuntu是有列印的,只不過需要我們手動檢視。

最簡單的核心模組例子

include include include static int init hello init void static void exit hello exit void module init hello init module exit hello exit static int init...

乙個最簡單的Linux核心模組

include include static int init hello init void static void exit hello exit module init hello init module exit hello exit module license gpl 這個最簡單的核心模...

Linux環境下最簡單核心模組的實踐

1.最簡單驅動原始檔 include include module license dual bsd gpl static int hello init void static void hello exit void module init hello init module exit hello...