我的Linux版本是Redhat enterprise 2.6内核
以为主要参考
最简单的模块hello.c
/hello.c
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, worldn");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT"Goodbye, cruel worldn");
}
module_init(hello_init);
module_exit(hello_exit);
编译模块
内核代码在/usr/src/kernels/2.6.9-42.EL-smp-x86_64/下面
也存在于/lib/modules/2.6.9-42.ELsmp/build/
1,Makefile 文件
obj-m :=hello.o
再直接运行
make -C /usr/src/kernels/2.6.9-42.EL-smp-x86_64/ SUBDIRS=$PWD modules
得到结果
make: Entering directory `/usr/src/kernels/2.6.9-42.EL-smp-x86_64'
CC [M] /root/luckyball/device/hello.o
Building modules, stage 2.
MODPOST
CC /root/luckyball/device/hello.mod.o
LD [M] /root/luckyball/device/hello.ko
make: Leaving directory `/usr/src/kernels/2.6.9-42.EL-smp-x86_64'
生成结果
[root@localhost device]# ls
hello.c hello.ko hello.mod.c hello.mod.o hello.o Makefile
2,Makefile 文件于上面一样
运行
make -C /lib/modules/2.6.9-42.ELsmp/build/ SUBDIRS=$PWD modules
得到运行结果
make: Entering directory `/usr/src/kernels/2.6.9-42.EL-smp-x86_64'
CC [M] /root/luckyball/device/hello.o
Building modules, stage 2.
MODPOST
CC /root/luckyball/device/hello.mod.o
LD [M] /root/luckyball/device/hello.ko
make: Leaving directory `/usr/src/kernels/2.6.9-42.EL-smp-x86_64'
可见两个内核代码是相关联的
生成结果 同上
3,直接写Makefile 文件
1 ifneq ($(KERNElRELEASE),)
2 obj-m := hello.o
3 else
4 obj-m := hello.o
5 KERNELDIR ?= /lib/modules/$(shell uname -r)/build
6 PWD := $(shell pwd)
7
8 default:
9 $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
10 endif
其中/lib/modules/$(shell uname -r)/build 就是上面的
/lib/modules/2.6.9-42.ELsmp/build/
得到运行结果
make -C /lib/modules/2.6.9-42.ELsmp/build SUBDIRS=/root/luckyball/device modulesmake[1]: Entering directory `/usr/src/kernels/2.6.9-42.EL-smp-x86_64'
CC [M] /root/luckyball/device/hello.o
Building modules, stage 2.
MODPOST
CC /root/luckyball/device/hello.mod.o
LD [M] /root/luckyball/device/hello.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.9-42.EL-smp-x86_64'
生成结果通上
注意: Makefile文件中的4行,是中没有的,我认为必需加,且我的实践证明也必需加
if ,else 两个独立的语句,都应该运行obj-m :=hello.o,即说明有一个模块需要从目标文件
hello.o构造,且名字为hello.ko.
装载和卸载模块
insmod ./hello.ko
rmmod hello
如果不能在终端打印消息,可以/var/log/syslog查看,也可以修改printk优先级使其在终端上先是,参看
31 #define KERN_EMERG "" /* system is unusable */
32 #define KERN_ALERT "" /* action must be taken immediately */
33 #define KERN_CRIT "" /* critical conditions */
34 #define KERN_ERR "" /* error conditions */
35 #define KERN_WARNING "" /* warning conditions */
36 #define KERN_NOTICE "" /* normal but significant condition */
37 #define KERN_INFO "" /* informational */
38 #define KERN_DEBUG "" /* debug-level messages */
把KERN_ALERT 改成 KERN_EMERG
问题自然就解决了!