這是撰寫kernel module 的小小筆記~

開發環境

Ubuntu 14.04 LTS
Kernel 3.19.0-31-generic

可以使用uname -a指令來察看自己的linux與kernel版本

jerry@router:/etc$ uname -a
Linux router 3.19.0-31-generic #36~14.04.1-Ubuntu SMP Thu Oct 8 10:21:08 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

建立hello.c

建立並進入一個測試目錄kernel_test,然後開始編輯hello.c檔案

$ mkdir kernel_test
$ cd kernel_test
$ vim hello.c

這裏面有兩個function,hello_init和hello_exit


// kernel_test/hello.c

#include <linux/init.h>
#include <linux/module.h>
 
MODULE_DESCRIPTION("Hello_world");
MODULE_LICENSE("GPL");
 
static int hello_init(void)
{
 printk(KERN_INFO "Hello world !\n");
 return 0;
}
 
static void hello_exit(void)
{
 printk(KERN_INFO "Bye !\n");
}
 
module_init(hello_init);
module_exit(hello_exit);


Makefile


// kernel_test/Makefile

PWD := $(shell pwd) 
KVERSION := $(shell uname -r)
KERNEL_DIR = /usr/src/linux-headers-$(KVERSION)/

MODULE_NAME = hello
obj-m := $(MODULE_NAME).o

all:
 make -C $(KERNEL_DIR) M=$(PWD) modules
clean:
 make -C $(KERNEL_DIR) M=$(PWD) clean


編譯module

在kernel_test目錄下執行make,看到以下的訊息就算是完成編譯了

$ make
make -C /usr/src/linux-headers-3.19.0-31-generic/ M=/home/jerry/kernel_test modules
make[1]: Entering directory `/usr/src/linux-headers-3.19.0-31-generic'
 Building modules, stage 2.
 MODPOST 1 modules
make[1]: Leaving directory `/usr/src/linux-headers-3.19.0-31-generic'

用ls可以看到編好的檔案們

$ ls
hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile modules.order Module.symvers

載入/移除 module

使用insmod指令來載入hello.ko

$ sudo insmod hello.ko

接著用lsmod指令來確認module是否成功載入

因為系統載入的module很多,這邊用grep來過濾出我們的hello module,如下所示

$ sudo lsmod | grep "hello" 
hello 16384 0

最後,把hello module移除

使用rmmod指令,就可以把module移除囉

$ sudo rmmod hello.ko

執行完載入與移除的動作,我們回過頭來看看hello.c裡頭的hello_init和hello_exit

這裡各呼叫了printk這個function,它會在系統日誌上輸出KERN_INFO級別的訊息

可以呼叫dmesg指令來察看系統日誌

$ dmesg
...(略)
[11261.743645] Hello world !
[12433.528440] Bye !

 

參考資料

一個簡單的 Linux Kernel Module

[Linux Kernel] 撰寫簡單 Hello, World module (part 1)