Ubuntu核心模組編譯

來源:互聯網
上載者:User

    核心模組是Linux核心向外部提供的一個插口,其全稱為動態可載入核心模組(Loadable Kernel Module,LKM),我們簡稱為模組。Linux核心之所以提供模組機制,是因為它本身是一個單核心(monolithic kernel)。單核心的最大優點是效率高,因為所有的內容都整合在一起,但其缺點是可擴充性和可維護性相對較差,模組機制就是為了彌補這一缺陷。

一、 什麼是模組

    模組是具有獨立功能的程式,它可以被單獨編譯,但不能獨立運行。它在運行時被連結到核心作為核心的一部分在核心空間運行,這與運行在使用者空間的進程是不同的。模組通常由一組函數和資料結構組成,用來實現一種檔案系統、一個驅動程式或其他核心上層的功能。

    應用程式與核心模組的比較

    為了加深對核心模組的瞭解,表一給出應用程式與核心模組程式的比較。

 

   

 

                        表一 應用程式與核心模組程式的比較

    從表一我們可以看出,核心模組程式不能調用libc庫中的函數,它運行在核心空間,且只有超級使用者可以對其運行。另外,模組程式必須通過module_init()和module_exit()函數來告訴核心“我來了”和“我走了”。

二、 編寫一個簡單的模組

    模組和核心都在核心空間運行,模組編程在一定意義上說就是核心編程。因為核心版本的每次變化,其中的某些函數名也會相應地發生變化,因此模組編程與核心版本密切相關。以下例子針對Ubuntu 11.04 核心2.6.37.2

1.hello.c

 

#include "linux/init.h"<br />#include "linux/kernel.h"<br />#include "linux/module.h"</p><p>MODULE_LICENSE("GPL");</p><p>static int __init hello_init(void) {<br /> printk(KERN_ALERT "Hello world!/n");<br /> return 0;<br />}</p><p>static void __exit hello_exit(void) {<br /> printk(KERN_ALERT "Goodbye!/n");<br />}</p><p>module_init(hello_init);<br />module_exit(hello_exit);<br />MODULE_AUTHOR("gengjia");<br />MODULE_DESCRIPTION("hello");

說明

hello.c檔案可以放在任意檔案夾之下。

所有模組都要使用標頭檔module.h,此檔案必須包含進來。

標頭檔kernel.h包含了常用的核心功能。

標頭檔init.h包含了宏_init和_exit,它們允許釋放核心佔用的記憶體。

hello_init是模組的初始化函數,它必需包含諸如要編譯的代碼、初始化資料結構等內容。

使用了printk()函數,該函數是由核心定義的,功能與C庫中的printf()類似,它把要列印的資訊輸出到終端或系統日誌。

hello_exit是模組的退出和清理函數。此處可以做所有終止該驅動程式時相關的清理工作。

module_init()和module_exit()是模組編程中最基本也是必須的兩個函數。

module_init()是驅動程式初始化的進入點。而module_exit()登出由模組提供的所有功能。

 2、Makefile

obj-m:=hello.o<br />KERNELBUILD :=/lib/modules/$(shell uname -r)/build<br />default:<br /> make -C $(KERNELBUILD) M=$(shell pwd) modules<br /> echo insmod ./hello.ko to turn it on<br />clean:<br /> rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers .tmp_versions

(注意makefile裡面要求的tab)

Makefile檔案與hello.c檔案放在同一個目錄。

KERNELBUILD :=/lib/modules/$(shell uname -r)/build是編譯核心模組需要的Makefile的路徑,我的Ubuntu下是

/lib/modules/2.6.37.2/build

make -C $(KERNELBUILD) M=$(shell pwd) modules 編譯核心模組。-C 將工作目錄轉到KERNELBUILD,調用該目錄下的Makefile,並向這個Makefile傳遞參數M的值是$(shell pwd) modules。

3. 編譯模組

#sudo make (調用第一個命令default)

這時,在hello.c 所在檔案夾就會有 hello.ko ,這個就是我們需要的核心模組啦。

#sudo make clean

清理編譯垃圾,hello.ko 也會清理掉。

4. 插入模組,讓其工作。注意必須是root許可權

#sudo insmod ./hello.ko 我們用dmesg就可以看到產生的核心資訊啦,Hello world!

如果沒有輸出"Hello world!",因為如果你在字元終端而不是終端模擬器下啟動並執行話,就會輸出,因為在終端模擬器下時會把核心訊息輸出到記錄檔/var/log/kern.log中。

#sudo rmmod ./hello.ko 再用dmesg可以看到Goodbye!

    modutils是管理核心模組的一個軟體包。可以在任何獲得核心原始碼的地方擷取Modutils(modutils-x.y.z.tar.gz)原始碼,然後選擇最進階別的patch.x.y.z等於或小於當前的核心版本,安裝後在/sbin目錄下就會有insomod、rmmod、ksyms、lsmod、modprobe等公用程式。當然,通常我們在載入Linux核心時,modutils已經被載入。

    1.insmod命令

    調用insmod程式把需要插入的模組以目標代碼的形式插入到核心中。在插入的時候,insmod自動調用module_init()函數運行。注意,只有超級使用者才能使用這個命令,其命令格式為:#insmod [path] modulename.ko

    2.rmmod命令

    調用rmmod程式將已經插入核心的模組從核心中移出,rmmod會自動運行module_exit()函數,其命令格式為:#rmmod [path] modulename.ko

    3.lsmod命令

    調用lsmod程式將顯示當前系統中正在使用的模組資訊。實際上這個程式的功能就是讀取/proc檔案系統中的檔案/proc/modules中的資訊,其命令格式為:#lsmod

 

以上就是在2.6.xx下一個最簡單的模組編寫過程。

 

本文轉載自:

http://www.xker.com/page/e2011/0214/100154_1.html

並對其做了一些修改。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.