日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

編寫簡單的Linux2.6內(nèi)核模塊(1)

 iceberg_horn 2009-05-05

編寫簡單的Linux2.6內(nèi)核模塊(1)

作者來源:IBM  
閱讀 數(shù) 363 人次 , 2006-3-18 13:58:00 

您的內(nèi)核必須已經(jīng)啟用這些選項進行了編譯:


                        Loadable module support  --->
                        [*] Enable loadable module support
                        [*]   Module unloading
                        [ ]   Module versioning support (EXPERIMENTAL)
                        [*]   Automatic kernel module loading
                        

如果按照第一篇教程中的說明編譯內(nèi)核,那么就已經(jīng)正確地設(shè)置了這些選項。否則,修改這些選項,重新編譯內(nèi)核,并引導(dǎo)到新內(nèi)核。

一個簡單的模塊骨架

首先,找到編譯當前 Linux 內(nèi)核的源代碼。將目錄切換到 Linux 源代碼目錄中的 drivers/misc/?,F(xiàn)在,拷貝下面的代碼并將其粘貼到一個名為 mymodule.c 的文件:


                        #include <linux/module.h>
                        #include <linux/config.h>
                        #include <linux/init.h>
                        static int __init mymodule_init(void)
                        {
                        printk ("My module worked!\n");
                        return 0;
                        }
                        static void __exit mymodule_exit(void)
                        {
                        printk ("Unloading my module.\n");
                        return;
                        }
                        module_init(mymodule_init);
                        module_exit(mymodule_exit);
                        MODULE_LICENSE("GPL");
                        
保存這個文件,并在同一目錄下編輯 Makefile 文件。添加這一行:


                        obj-m += mymodule.o
                        
編譯模塊:


                        # make -C <top directory of your kernel source> SUBDIRS=$PWD modules
                        
使用 insmod ./mymodule.ko 加載這個模塊,并查看是否打印了您的消息: dmesg | tail。應(yīng)該會在輸出的結(jié)束處看到:


                        My module worked!
                        
現(xiàn)在刪除內(nèi)核模塊:rmmod mymodule。再次查看 dmesg;應(yīng)該會看到:


                        Unloading my module.
                        
這樣您就已經(jīng)編寫并運行了一個新的內(nèi)核模塊!恭喜!

模塊/內(nèi)核接口

現(xiàn)在,我們來做一些與您的模塊有關(guān)的更有趣的事情。要了解的一個關(guān)鍵內(nèi)容是,模塊只能“看到”內(nèi)核故意讓它訪問的函數(shù)和變量。首先,我們以錯誤的方式來進行嘗試。

編輯文件 kernel/printk.c,在所有包含文件之后其他全局變量聲明附近(但要在所有函數(shù)之外)添加下面一行:


                        int my_variable = 0;
                        
現(xiàn)在重新編譯內(nèi)核并引導(dǎo)到新內(nèi)核。然后,將下面的內(nèi)容添加到模塊的 mymodule_init 函數(shù)起始處,置于其他代碼之前。


                        extern int my_variable;
                        printk ("my_variable is %d\n", my_variable);
                        my_variable++;
                        
保存修改并重新編譯模塊:


                        # make -C <top directory of your kernel source> SUBDIRS=$PWD modules
                        
加載模塊(這將失?。?code>insmod ./mymodule.ko。模塊的加載會失敗,并給出消息:


                        insmod: error inserting './mymodule.ko': -1 Unknown symbol in module
                        
這說明內(nèi)核不允許模塊訪問那個變量。當模塊加載時,它必須解析所有外部引用,比如函數(shù)名或者變量名。如果它不能找到內(nèi)核導(dǎo)出的符號列表中所有未解析的名稱,那么模塊就不能寫入那個變量或者調(diào)用那個函數(shù)。在內(nèi)核中某個地方有為變量 my_variable 分配的空間,但模塊不知道是哪里。

為解決此問題,我們將把 my_variable 添加到內(nèi)核導(dǎo)出的符號列表中。在很多內(nèi)核目錄中,都有一個特定的文件,用于導(dǎo)出在那個目錄中定義的符號。再次打開 kernel/printk.c 文件,在變量聲明之后添加下面一行:


                        EXPORT_SYMBOL(my_variable);
                        
重新編譯并重新引導(dǎo)到新內(nèi)核?,F(xiàn)在再一次嘗試加載模塊:insmod ./mymodule.ko。這一次,當查看 dmesg 時,應(yīng)該看到:


                        my_variable is 0
                        My module worked!
                        
重新加載模塊:


                        # rmmod mymodule && insmod ./mymodule.ko
                        
現(xiàn)在應(yīng)該看到:


                        Unloading my module.
                        my_variable is 1
                        My module worked!
                        
每次重新加載那個模塊,my_variable 都會增 1。您正在讀寫一個在主內(nèi)核中定義的變量。只要被 EXPORT_SYMBOL() 顯式地聲明,模塊就可以訪問主內(nèi)核中的任何變量。例如,函數(shù) printk() 是在內(nèi)核中定義的,并且在文件 kernel/printk.c 中被導(dǎo)出。

簡單的可引導(dǎo)內(nèi)核模塊是用來研究內(nèi)核的一個有趣的途徑。例如,可以使用一個模塊來打開或關(guān)閉 printk,方法是在內(nèi)核中定義一個變量 do_print(它初始化為 0)。然后,讓所有 printk 都依賴于“do_print”:


                        if (do_print) {
                        printk ("Big long obnoxious message\n");
                        }
                        
然后,只有當您的模塊被加載時才打開它。

模塊參數(shù)

引導(dǎo)模塊時,可以向它傳遞參數(shù)。要使用模塊參數(shù)加載模塊,這樣寫:


                        insmod module.ko [param1=value param2=value ...]
                        
為了使用這些參數(shù)的值,要在模塊中聲明變量來保存它們,并在所有函數(shù)之外的某個地方使用宏 MODULE_PARM(variable, type)MODULE_PARM_DESC(variable, description) 來接收它們。type 參數(shù)應(yīng)該是一個格式為 [min[-max]]{b,h,i,l,s} 字符串,其中 min 和 max 是數(shù)組的長度限度。如果兩者都忽略了,則默認為 1。最后一個字符是類型說明符:


                        b       byte
                        h       short
                        i       int
                        l       long
                        s       string
                        

可以在 MODULE_PARM_DESCdescription 域中添加任何需要的說明符。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多