linux 第一个内核模块Hello World
?
內核模塊是Linux內核向外部提供的一個插口,其全稱為動態可加載內核模塊(Loadable Kernel Module,LKM),我們簡稱為模塊。Linux內核之所以提供模塊機制,是因為它本身是一個單內核(monolithic kernel)。單內核的最大優點是效率高,因為所有的內容都集成在一起,但其缺點是可擴展性和可維護性相對較差,模塊機制就是為了彌補這一缺陷。
一、?什么是模塊
模塊是具有獨立功能的程序,它可以被單獨編譯,但不能獨立運行。它在運行時被鏈接到內核作為內核的一部分在內核空間運行,這與運行在用戶空間的進程是不同的。模塊通常由一組函數和數據結構組成,用來實現一種文件系統、一個驅動程序或其他內核上層的功能。
?
應用程序與內核模塊的比較
為了加深對內核模塊的了解,表一給出應用程序與內核模塊程序的比較。
表一?應用程序與內核模塊程序的比較
| ? | C語言應用程序 | 內核模塊程序 |
| 使用函數 | Libc庫 | 內核函數 |
| 運行空間 | 用戶空間 | 內核空間 |
| 運行權限 | 普通用戶 | 超級用戶 |
| 入口函數 | main() | module_init() |
| 出口函數 | exit() | module_exit() |
| 編譯 | Gcc –c | Makefile |
| 連接 | Gcc | insmod |
| 運行 | 直接運行 | insmod |
| 調試 | Gdb | kdbug, kdb,kgdb等 |
從表一我們可以看出,內核模塊程序不能調用libc庫中的函數,它運行在內核空間,且只有超級用戶可以對其運行。另外,模塊程序必須通過module_init()和module-exit()函數來告訴內核“我來了”和“我走了”。
二、?編寫一個簡單的模塊
模塊和內核都在內核空間運行,模塊編程在一定意義上說就是內核編程。因為內核版本的每次變化,其中的某些函數名也會相應地發生變化,因此模塊編程與內核版本密切相關。以下例子針對Ubuntu 9.10 ?內核2.6.31-14-generic
?
1.程序舉例
?
?
說明
所有模塊都要使用頭文件module.h,此文件必須包含進來。 頭文件kernel.h包含了常用的內核函數。 頭文件init.h包含了宏_init和_exit,它們允許釋放內核占用的內存。 lkp_init是模塊的初始化函數,它必需包含諸如要編譯的代碼、初始化數據結構等內容。 使用了printk()函數,該函數是由內核定義的,功能與C庫中的printf()類似,它把要打印的信息輸出到終端或系統日志。 lkp_cleanup是模塊的退出和清理函數。此處可以做所有終止該驅動程序時相關的清理工作。 module_init()和cleanup_exit()是模塊編程中最基本也是必須的兩個函數。 module_init()是驅動程序初始化的入口點。而cleanup_exit()注銷由模塊提供的所有功能。2 ?編寫Makefile?文件,與hello.c 放在同一個目錄里
?
?
(注意makefile里面要求的tab)
KERNELBUILD :=/lib/modules/$(shell uname -r)/build是編譯內核模塊需要的Makefile的路徑,Ubuntu下是
/lib/modules/2.6.31-14-generic/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 from hello world",因為如果你在字符終端而不是終端模擬器下運行的話,就會輸出,因為在終端模擬器下時會把內核消息輸出到日志文件/var/log/kern.log中。
#sudo rmmod ./hello
再用dmesg?可以看到 Bye world!
modutils是管理內核模塊的一個軟件包。可以在任何獲得內核源代碼的地方獲取Modutils(modutils-x.y.z.tar.gz)源代碼,然后選擇最高級別的patch.x.y.z等于或小于當前的內核版本,安裝后在/sbin目錄下就會有insomod、rmmod、ksyms、lsmod、modprobe等實用程序。當然,通常我們在加載Linux內核時,modutils已經被載入。
1.Insmod命令
調用insmod程序把需要插入的模塊以目標代碼的形式插入到內核中。在插入的時候,insmod自動調用init_module()函數運行。注意,只有超級用戶才能使用這個命令,其命令格式為:
# insmod??[path] modulename.ko
2. rmmod命令
調用rmmod程序將已經插入內核的模塊從內核中移出,rmmod會自動運行cleanup_module()函數,其命令格式為:
#rmmod??[path] modulename.ko
3.lsmod命令
調用lsmod程序將顯示當前系統中正在使用的模塊信息。實際上這個程序的功能就是讀取/proc文件系統中的文件/proc/modules中的信息,其命令格式為:
#lsmod
4.ksyms命令
ksyms這個程序用來顯示內核符號和模塊符號表的信息。與lsmod相似,它的功能是讀取/proc文件系統中的另一個文件/proc/kallsyms。
這就是在2.6.xx下一個最簡單的模塊編寫過程。
?
轉載于:https://www.cnblogs.com/int32bit/archive/2011/06/12/3187798.html
總結
以上是生活随笔為你收集整理的linux 第一个内核模块Hello World的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易原来也是个骗子
- 下一篇: 高并发网络架构解决方案分析