HelloWorld內核
開始斷斷續續學習內核,大概半年了,多少開始對內核有點感悟了,但是對于這個龐然大物我顯得很渺小,在枯燥的內核源碼之中似乎沒有一點點成功的喜悅,因此我選擇學習內核模塊編程,通過編寫一些內核模塊來體驗那一點點小小的成就感吧!
什么是內核模塊
內核模塊是具有獨立功能的程序。它可以被單獨編譯,但是不能單獨運行,它的運行必須被鏈接到內核作為內核的一部分在內核空間中運行。
最簡單的內核模塊
#include
一個Makefile來編譯這個內核模塊
obj-m += hello-1.oall: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
注意:本文所有環節都是基于Centos6.5下測試OK,你可能在有的書上看見Makefile是這樣寫的
make -C /usr/src/linux-headers-$(shell uname -r) M=$(PWD) modules 其實/lib/modules/$(shell uname -r)/build 這個路徑就是上面路徑的一個軟鏈接 [root@localhost 2.6.32-431.el6.x86_64]# ls -al build lrwxrwxrwx. 1 root root 44 Mar 16 05:26 build -> /usr/src/kernels/2.6.32-504.12.2.el6.x86_64/
編寫好makefile文件后,使用make進行編譯,編譯完就出現一個.ko的文件,這個就是內核模塊,需要載入運行
載入內核模塊進行運行
載入內核模塊的方法有很多比如: modprobe 和 insmod前者會分析模塊的依賴關系,并且會去指定路徑查找內核模塊載入,而后者需要指定內核模塊的絕對路徑進行載入并且不解決模塊的依賴關系。這里我們使用insmod來載入內核模塊,使用rmmod卸載內核模塊 [root@localhost kernel_module]# insmod hello-1.ko使用dmes查看內核模塊的輸出Hello world 1.卸載內核模塊 [root@localhost kernel_module]# rmmod hello-1 dmesg查看輸出Goodbye world 1.
內核模塊編程和應用程序編程的異同
內核模塊編程是不能去使用標準庫(比如malloc free等)和一些第三方的庫
內核模塊編程是沒有內存保護的,如果內存訪問錯誤,就會出現oops錯誤
內核模塊編程是沒有main函數的,只有一個初始化函數,和一個提出函數
內核模塊編程需要使用內核提供的頭文件和API
內核模塊編程的標準輸出是輸出到文件,而不是輸出到屏幕
內核模塊編程的debug是不能使用gdb來進行調試的。
內核模塊進階
內核模塊的編程不僅僅是上面的一個HelloWorld,內核模塊編程還有一些更高級的寫法,下面會一一介紹:
去掉init_module/cleanup_module
在上面的HelloWorld模塊中,你會發現初始化函數和退出函數好像是固定的名稱,那么有沒有辦法自己自定義名稱呢其實是可以的,你可以自己自定義名稱,然后進行注冊即可(注冊其實就是做了一個函數指針的賦值而已)下面是自定義名稱的寫法:
//不需要固定內核模塊的初始化函數的名字和結束的名字#include
__init/__initdata/__exit
在有的內核模塊編程的書籍或者介紹內核模塊編程的博客中,你或許會發現有這樣的一些特殊關鍵字__init ,_initdata ,__exit等等,其實這些都是gcc的擴展屬性:__init宏最常用的地方是驅動模塊初始化函數的定義處,其目的是將驅動模塊的初始化函數放入名叫.init.text的輸入段。當內核啟動完畢后,這個段中的內存會被釋放掉供其他使用。__initdata宏用于數據定義,目的是將數據放入名叫.init.data的輸入段。其它幾個宏也類似。
模塊描述信息
可以使用modinfo去查看一個模塊的模塊信息,下面是自己編寫的模塊和系統自帶的模塊的兩個模塊信息的對比
[root@localhost kernel_module]# modinfo hello-1.kofilename: hello-1.kosrcversion: 0D3956C127A907CC9E7114Fdepends: vermagic: 2.6.32-504.12.2.el6.x86_64 SMP mod_unload modversions [root@localhost kernel_module]# modinfo/lib/modules/2.6.32-431.el6.x86_64/kernel/fs/ext4/ext4.ko filename: /lib/modules/2.6.32-431.el6.x86_64/kernel/fs/ext4/ext4.kolicense: GPLdescription: Fourth Extended Filesystemauthor: Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others srcversion: 345EBDA2AEFF60FFED78864 depends: mbcache,jbd2 vermagic: 2.6.32-431.el6.x86_64 SMP mod_unload modversions
從上面的對比可知,自己編寫的模塊的模塊信息很少,沒有作者信息,沒有許可證信息等等,其實這些都可以設置
#include
模塊參數
在用戶態編寫程序的時候我們都應該清楚,是可以給程序傳遞參數的,那么同樣內核模塊同樣也有這樣的需求,下面的例子展示了如何去給內核模塊傳遞參數:
#include
模塊文件分割
在用戶態寫程序的時候,你會將一個大的程序分割成好幾個文件,這樣程序脈絡就顯的很清晰。在這里我們將初始化函數和退出函數分開在兩個文件中編寫。
start.c中#include
-
helloworld
+關注
關注
0文章
13瀏覽量
4473 -
內核模塊
+關注
關注
0文章
10瀏覽量
3213
原文標題:黑客內核:編寫屬于你的Hello world
文章出處:【微信號:C_Expert,微信公眾號:C語言專家集中營】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
Linux 內核模塊工作原理及內核模塊編譯案例

詳解Linux內核模塊的編寫方法
Linux內核模塊間通訊方法

Linux內核模塊程序結構
高效學習Linux內核——內核模塊編譯
什么是內核模塊?如何編寫一個簡單的模塊?
如何在Petalinux創建Linux內核模塊?
嵌入式LINUX系統內核和內核模塊調試

評論