近日嘗試linux內核設備模塊編程,使用《linux內核編譯》一書,但在新版的2.6內核中,例子程序無法編譯通過,在網上搜尋了很久,都沒有找到一個完整的解決方案,最後終於在網站http://lwn.net/獲得幫助,現總結如下
init和clear命名方式改變,makefile改變
用一個hello world程序說明
原版如下:
#include <linux/kernel.h>
#include <linux/module.h>
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif
int init_module()
{
printk("Hello, world - this is the kernel speaking/n");
return 0;
}
void cleanup_module()
{
printk("Short is the life of a kernel module/n");
}
Mvakefile如下
CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
hello.o: hello.c /usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c hello.c
現在需要改成
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int hello_init(void)
{
printk("<1> Hello, world/n");
return 0;
}
static void hello_exit(void)
{
printk("<1> Goodbye, cruel world/n");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile 如下
ifneq ($(KERNELRELEASE),)
obj-m:= hello.o
else
KDIR:= /lib/modules/$(shell uname -r)/build
PWD:= $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif
有一點需要重點說明
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
這個句子前面一定要加一個TAB,切記切記
這樣生成的會有一個*.ko的文件,這個文件才能被insmod進去
不過我還遇到一個問題,就是我的GCC升級到3.4.1後編譯出來的文件無法insmod進去,提示要用GCC 3.3,好鬱悶,最終還是用GCC 3.3搞定了
另外就是這個東西insmod進去以後什麼提示也沒有,只是能在lsmod看到添加成功,rmmod時也是沒有任何信息,那語句中的printk輸出到哪裏了?用的是多用戶命令行方式,沒有打開X
以上程序在內核2.6.5上編譯通過
在 http://lwn.net/Articles/driver-porting/你會得到更多2.6內核改變的信息