內(nèi)核開發(fā)往往給人開發(fā)難度大的印象,大家覺得內(nèi)核開發(fā)非常神秘,很高大上。其實內(nèi)核開發(fā)并沒有想象的那么復雜,它跟普通的用戶態(tài)開發(fā)基本類似,稍微復雜一點的是內(nèi)核的調(diào)試。本文通過一個簡單的內(nèi)核程序,讓大家了解內(nèi)核開發(fā),并進入內(nèi)核開發(fā)的大門。
開發(fā)環(huán)境
為了避免將自己的操作系統(tǒng)搞掛,本文在虛擬機中進行開發(fā),這樣我們可以隨便折騰。本文所用的環(huán)境信息如下。
操作系統(tǒng):Ubuntu 16.04 Server版
內(nèi)核版本:4.4.0-31
編譯環(huán)境:gcc 5.4.0
程序代碼
主程序代碼
本文代碼也遵從慣例,開發(fā)一個非常簡單的HelloWorld程序,在程序啟動的時候打印一條HelloWorld信息,先展示代碼。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
static int hello_init(void)
{
printk("Hello, itworld123.com");
return 0;
}
static void hello_exit(void)
{
printk("Bye!");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("SunnyZhang<shuningzhang@126.com>");
可以是用任何文本工具將本代碼保存在一個文本文件(hello.c)中進行測試。在Linux系統(tǒng)中可以順序執(zhí)行如下命令:
mkdir helloworld
cd helloworld
vim hello.c
用vim打開文件后,將上述代碼拷貝到里面,然后保存退出(好啰嗦,不會使用vim的話,請搜索相關(guān)內(nèi)容學習)。
工程管理
在用戶態(tài)開發(fā)時,為了方便編譯,通常需要一個Makefile文件管理我們的源文件。內(nèi)核開發(fā)也需要一個Makefile文件。具體內(nèi)容如下:
obj-m += hello.o
CURRENT_PATH := $(shell pwd)
LINUX_KERNEL := $(shell uname -r)
LINUX_KERNEL_PATH := /usr/src/linux-headers-$(LINUX_KERNEL)
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
同樣,還是在helloworld目錄下,通過vim命令建立一個名稱為Makefile的文件,并拷貝上述內(nèi)容。
完成上述內(nèi)容后,我們其實就完成了一個最簡單內(nèi)核程序的開發(fā),本文先不具體解釋上述代碼的具體含義,先編譯運行看一下效果。
程序運行
在helloworld目錄下面執(zhí)行make命令就可以進行編譯,最后會生成一個名稱為hello.ko的問題。該文件就是我們最終完成的可執(zhí)行文件。在root用戶下,執(zhí)行如下命令:
insmod hello.ko
如果不是root用戶會報錯,此時可以切換到root用戶,或者執(zhí)行如下命令:
sudo insmod hello.ko
在生產(chǎn)環(huán)境通常是不建議直接使用root用戶的,但為了學習方便可以使用root用戶。
執(zhí)行上述命令后,我們繼續(xù)執(zhí)行如下命令:
dmesg
此時可以看到在最后有我們打印的信息:
Hello, itworld123.com
完成測試之后,可以執(zhí)行如下命令卸載程序(模塊):
rmmod hello
由于排版等問題,正文中的代碼可能無法直接編譯運行。配套代碼可以從本號的github下載,https://github.com/shuningzhang/linux_kernel