核心模組共享變數例項

2021-05-02 07:22:29 字數 3941 閱讀 9483

您的核心必須已經啟用這些選項進行了編譯:

loadable module support --->

[*] enable loadable module support

[*] module unloading

[ ] module versioning support (experimental)

[*] automatic kernel module loading

如果按照第一篇教程中的說明編譯核心,那麼就已經正確地設定了這些選項。否則,修改這些選項,重新編譯核心,並引導到新核心。

乙個簡單的模組骨架

首先,找到編譯當前 linux 核心的源**。將目錄切換到 linux 源**目錄中的drivers/misc/。現在,拷貝下面的**並將其貼上到乙個名為mymodule.c的檔案:

#include

#include

#include

static int __init mymodule_init(void)

static void __exit mymodule_exit(void)

module_init(mymodule_init);

module_exit(mymodule_exit);

module_license("gpl");

儲存這個檔案,並在同一目錄下編輯makefile檔案。新增這一行:

obj-m += mymodule.o

編譯模組:

# make -c subdirs=$pwd modules

使用insmod ./mymodule.ko載入這個模組,並檢視是否列印了您的訊息:dmesg | tail。應該會在輸出的結束處看到:

my module worked!

現在刪除核心模組:rmmod mymodule。再次檢視 dmesg;應該會看到:

unloading my module.

這樣您就已經編寫並執行了乙個新的核心模組!恭喜!

模組/核心介面

現在,我們來做一些與您的模組有關的更有趣的事情。要了解的乙個關鍵內容是,模組只能「看到」核心故意讓它訪問的函式和變數。首先,我們以錯誤的方式來進行嘗試。

編輯檔案kernel/printk.c,在所有包含檔案之後其他全域性變數宣告附近(但要在所有函式之外)新增下面一行:

int my_variable = 0;

現在重新編譯核心並引導到新核心。然後,將下面的內容新增到模組的mymodule_init函式起始處,置於其他**之前。

extern int my_variable;

printk ("my_variable is %d/n", my_variable);

my_variable++;

儲存修改並重新編譯模組:

# make -c subdirs=$pwd modules

載入模組(這將失敗):insmod ./mymodule.ko。模組的載入會失敗,並給出訊息:

insmod: error inserting './mymodule.ko': -1 unknown symbol in module

這說明核心不允許模組訪問那個變數。當模組載入時,它必須解析所有外部引用,比如函式名或者變數名。如果它不能找到核心匯出的符號列表中所有未解析的名稱,那麼模組就不能寫入那個變數或者呼叫那個函式。在核心中某個地方有為變數my_variable分配的空間,但模組不知道是**。

為解決此問題,我們將把my_variable新增到核心匯出的符號列表中。在很多核心目錄中,都有乙個特定的檔案,用於匯出在那個目錄中定義的符號。再次開啟kernel/printk.c檔案,在變數宣告之後新增下面一行:

export_symbol(my_variable);

重新編譯並重新引導到新核心。現在再一次嘗試載入模組:insmod ./mymodule.ko。這一次,當檢視 dmesg 時,應該看到:

my_variable is 0

my module worked!

# rmmod mymodule && insmod ./mymodule.ko

現在應該看到:

unloading my module.

my_variable is 1

my module worked!

my_variable都會增 1。您正在讀寫乙個在主核心中定義的變數。只要被export_symbol()顯式地宣告,模組就可以訪問主核心中的任何變數。例如,函式printk()是在核心中定義的,並且在檔案kernel/printk.c中被匯出。

簡單的可引導核心模組是用來研究核心的乙個有趣的途徑。例如,可以使用乙個模組來開啟或關閉printk,方法是在核心中定義乙個變數do_print(它初始化為 0)。然後,讓所有printk都依賴於「do_print」:

if (do_print)

然後,只有當您的模組被載入時才開啟它。

模組引數

引導模組時,可以向它傳遞引數。要使用模組引數載入模組,這樣寫:

insmod module.ko [param1=value param2=value ...]

為了使用這些引數的值,要在模組中宣告變數來儲存它們,並在所有函式之外的某個地方使用巨集module_parm(variable, type)module_parm_desc(variable, description)來接收它們。type引數應該是乙個格式為[min[-max]]字串,其中 min 和 max 是陣列的長度限度。如果兩者都忽略了,則預設為 1。最後乙個字元是型別說明符:

b byte

h short

i int

l long

s string

可以在module_parm_descdescription域中新增任何需要的說明符。

Java Runnable執行緒共享例項變數

測試runnable執行緒可以共享例項變數 public class testrunnable implements runnable public static void main string args 使用相同的runnable建立了100個執行緒,每個執行緒對其i變數加一併輸出,可發現100...

類 作用域 共享變數 例項變數

類變數和例項變數在操作上的區別 被所有例項共享的變數 class sapm spam spam x sapm y sapm x.spam spam y.spam spam sapm.data 123 x.data,y.data 123 123 對例項的屬性進行賦值運算會在該例項內建立或修改變數名,而...

PB 關於共享變數與例項變數

例項與共享詳解共享變數 乙個屬於物件定義的變數,並且存在於物件的所有例項中。當乙個物件被關閉並再次開啟時,共享變數保留了它們的值。共享變數總是私有的。它們只能用於物件的指令碼和與物件相關聯的控制項。共享變數可以屬於應用程式物件 視窗 使用者物件或選單。例項變數 乙個屬於乙個物件的變數,它與該物件的乙...