2015年4月17日 星期五

Linux kernel module 嘗試 (1)

因為最近說不定有機會用到 kernel driver
所以藉此看了一下基本的使用
大致研究了一下,基本上這東西一般被認為不難寫
寫起來很無聊,只要照著硬體的 spec 去呼叫就會動
會寫的人就覺得很簡單,難的是如何呼叫到正確的函數
一個基本的 hello world module 是這樣寫

hello.c

#include <linux/module.h>

// Called upon insmod
static __init int Init(void) {
printk(KERN_ERR "Hello Golden Mosaic\n");
return 0;
}

// Called upon rmmod
static __exit void Exit(void) {
printk(KERN_ERR "Bye");
}

module_init(Init);
module_exit(Exit);

這邊就是登記了系統使用 insmod/rmmod 你的 module 時會被呼叫的函數
應該很直覺
printk,嗯…就跟 printf 很像,但是會印在系統紀錄檔裡面
前面可以選擇加上紀錄的嚴重性,總共七級
這邊用 KERN_ERR 是因為有時候系統不會紀錄不重要的訊息

Makefile 的部份

其實大部分工作交給 kernel source 附贈的 Makefile 就好了,很簡單:

# A very general Linux kernel driver syntax

# The driver and its dependencies
obj-m = the_driver.o
the_driver-objs = hello.o

# Kernel path, the path may vary under different Linux version
KVERSION=$(shell uname -r)
# centos?
# KDIR = /lib/modules/$(KVERSION)/build
# debian?
KDIR = /usr/src/linux-headers-$(KVERSION)

all:
    make -C $(KDIR) M=$(shell pwd) modules

clean:

    make -C $(KDIR) M=$(shell pwd) clean

最重要的部份有兩個

一是定義你想產生的 driver,以及這個 driver 需要哪些 object file
obj-m = the_driver.o
the_driver-objs = hello.o
就是這兩行,obj-m 定義了你的 driver 名稱,用 .o 結尾
接下來是用那個名稱定義相依性,就是把你所有的 .c 都變成 .o
只要注意兩行 the_driver 這兩個字要一樣就好,這應該很明顯
剩下的會自動幫你做完:自動產生出 obj-m 的那個 .ko 檔
注意不要把 driver 名稱跟現有的 .c 檔一樣,好像會出事

二是找出系統裡面安裝的 kernel source code
我設定變數 KVERSION, KDIR 就是在做這件事
找到之後下面幾行作的事情只有一個:
把工作丟給系統的 kernel source 裡面的 makefile,這樣就好了
(基本上最下面那幾行大家都是這樣打)

結果

我們把 module 插入再拔除
接著看系統的紀錄

insmod the_driver.ko
rmmod the_driver
dmesg | tail

以下就是我們會看到的東西
[ 8192.983526] Hello Golden Mosaic
[ 8197.511315] Bye

果然是 hello world 等級的沒什麼用的東西 XD

沒有留言:

張貼留言