linux 核心模組程式設計之hello word(二)
我們的目的是要編譯個hello.ko的檔案,然後安裝到核心中。
先來看下需要的程式碼,hello.c檔案如下
#include <linux/module.h> #include <linux/init.h> static int hello_init(void) { printk(KERN_WARNING"Hello world!\n"); return 0; } static void hello_exit(void) { printk(KERN_INFO"Goodbye world!\n"); } module_init(hello_init); module_exit(hello_exit);
函式說明:
模組載入函式(必需)
安裝模組時被系統自動呼叫的函式,通過module_init巨集來指定。
模組解除安裝函式(必需)
解除安裝模組時被系統自動呼叫的函式,通過module_exit巨集來指定。
1、Printk的列印級別如下:
級別 | 描述 |
KERN_EMERG |
緊急情況,系統可能會崩潰 |
KERN_ALERT |
必須立即響應 |
KERN_CRIT |
臨界情況 |
KERN_ERR |
錯誤資訊 |
KERN_WARNING |
警告資訊 |
KERN_NOTICE |
普通的但可能需要注意的資訊 |
KERN_INFO |
提示性資訊 |
KERN_DEBUG |
除錯資訊 |
如果沒有指定訊息的級別,printk()會使用預設的DEFAULT_MESSAGE_LOGLEVEL(通常是KERN_WARNING)。
2、控制檯的日誌級別(console_loglevel
當printk指定的訊息級別小於指定的控制檯日誌級別時,訊息的內容就會顯示在該控制檯上。控制檯的日誌級別定義在include/linux/kernel.h檔案中,預設為DEFAULT_CONSOLE_LOGLEVEL(值等於7),也就是說預設情況下,比KERN_DEBUG級別高的printk()訊息內容都可以在控制檯上顯示。
我們可以執行下面的命令使任何級別的printk()訊息都被列印在終端上
$ echo 8 > /proc/sys/kernel/printk
3、printk()的變體
核心在include/linux/kernel.h檔案中提供了兩個printk()的變體pr_debug和pr_info,它們的定義為:
235 #define pr_debug(fmt,arg...) /
236 printk(KERN_DEBUG fmt,##arg)
244 #define pr_info(fmt,arg...) /
245 printk(KERN_INFO fmt,##arg)
4、 printk()不是萬能的
printk()雖然很好用,但它並不是萬能的,在系統啟動時,終端還沒有初始化之前,它並不能被使用,不過如果不是在除錯系統的啟動過程的話,這並不能算是個問題。
其實核心提供了一個printk()的變體early_printk(),專門用於在系統啟動的初期在終端上列印訊息,它與printk()的區別僅僅在於名字的不同以及它能夠更早地工作。
Makefile檔案如下ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KERNELDIR ?= /home/grb/grb/arm/linux-2.6.38/
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *~ *.order
endif
還有一種makefile的形式如下,可以做參考用
obj-m :=hello.o
KERNELDIR ?= /home/grb/grb/arm/linux-2.6.38/
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *~ *.order
由makefile可以看出我都呼叫了/home/grb/grb/arm/linux-2.6.38/,這個路徑是我已經交叉編譯好了的友善之臂開發板的核心路徑,所以這個路徑可以根據自己實際情況做更改。
命令說明:
載入 insmod (insmod hello.ko)
解除安裝 rmmod (rmmod hello)
檢視 lsmod
載入 modprobe (modprobe hello)
Modprobe 如同insmod,也是載入一個模組到核心,他的不同之處在於他會根據檔案/lib/modules/<$version>/modules.dep來檢視要載入的模組。看他是否還依賴於其他模組,如果是,modprobe會首先找到這些模組,把它們先載入到核心。
所有前期工作都準備好之後,便可以直接make了,如下
這樣就可以看到我們編譯出來的hello.ko檔案了。接下來就是安裝測試了。將這個hello.ko檔案拷貝到我們的開發板上,執行如下:
由結果可以看出,我們hello的核心模組是正常的了。