轉自:http://hi.baidu.com/zkheartboy/blog/item/18d4fdc48b0249aa8326ac7c.html
看到昨天有好幾個問linux核心編程問題的文章,不少是卡在了入門問題上,就整理一下入門的初步流程。針對2.6核心的Linux系統,需要你的機器上已經安裝了kernel-devel這個包,也就是編譯模組所必須的東西:核心的標頭檔和一些Makefile。
一,Hello World程式:
CODE:/*file: hello.c*/
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <linux/init.h>;
#include <linux/module.h>;
#include <linux/kernel.h>;
static int hello_init(void)
{
printk(KERN_ALERT "Hello, The fucking crazy world/n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Bye, The fucking crazy world!/n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("albcamus <albcamus@163.com>;");
2.6核心的kbuild子系統跟2.4相比有本質的改變。我們下面嘗試兩種方式編譯這個程式:
1, 你可以在本目錄下這樣寫一個Makefile
CODE:obj-m := hell.o
clean:
rm -rf *.o .*.cmd *.ko *.mod.c .tmp_versions
然後用這樣的命令列編譯:
make -C /lib/modules/`uname -r`/build M=`pwd` modules
這時ls一下,就能看到產生了很多檔案,其中hello.ko就是我們需要的核心模組。
2, 專業點兒,Makefile這樣寫:
CODE:obj-m := hello.o
KERNELBUILD := /lib/modules/`uname -r`/build
default:
make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
rm -rf *.o .*.cmd *.ko *.mod.c .tmp_versions
然後只要make一下就可以了。
插入模組用insmod命令:
insmod ./hello.ko
這 時候大家可能會問:為什麼我的螢幕上沒有見到輸出?這個是console的日誌記錄層級和你printk訊息時指定的層級(本例中指定為
KERN_ALERT,為次高,僅次於KERN_EMERG)決定的。無論如何,你可以tail
或者cat看看系統日誌的最後幾行,系統日誌一般為/var/log/messages,或者直接用dmesg命令,肯定能看到輸出了。
二,標頭檔問題。
C 程式員都知道,要使用某個外部的函數,應當#include某個標頭檔,這個標頭檔包含了那個函數的原型(prototype)。核心的標頭檔在
include/下,其中include/asm是個符號連結,指向你所用核心的具體的體繫結構目錄,比方說我的系統是i386的,那麼
include/asm就指向include/asm-i386 。
核心編程中我們不能連結libc庫,不能使用libc庫中的函數,所以很有些
麻煩。一些重要的函數,象strcpy/strcmp/snprintf等,kernel也為我們實現並匯出(export)了,而我們需要
#include相關的標頭檔,在include/linux和include/asm中,你需要自己尋找你所要使用的函數在哪個標頭檔中聲明,並將其
#include進來。