1.第一个模块
hello.c:
<span style="font-size:14px;">#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init( void ){
printk(KERN_ALERT "Hello World ! " );
return 0;
}
static void __exit hello_exit(void){
printk(KERN_ALERT "Goodbye! ");
}
module_init( hello_init);
module_exit( hello_exit);
MODULE_LICENSE( "GPL" );
MODULE_AUTHOR( "MyName" );</span>
这个简单的程序以包含了模块的主要特征,每个模块都有一个入口和出口,在这个程序中是hello_init()和hello_exit(),它们分别通过module_init()和module_exit()系统调用注册到内核中,内核在加载这个模块时,调用hello_init()函数,在这个函数中一般做一些初始化工作,如果初始化顺利完成,返回零,否则返回一个非零值。hello_exit()是模块的出口函数,内核在卸载该模块是调用,负责释放资源等。 MODULE_LICENSE用于指定版权,linux一般使用"GPL"。 MODULE_AUTHOR用于指定代码的工作。
2.构建模块
<span style="font-size:14px;">Makefile:
obj-m := hello.o
KERNELDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD)
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions</span>
3.加载模块
要加载或卸载以root用户运行命令insmod或rmmod:
<span style="font-size:14px;">insmod ./hello.ko</span>
使用下面的命令可以看到我们的模块已经加载了:
<span style="font-size:14px;">lsmod | grep hello</span>
使用下面的命令可以卸载该模块:
<span style="font-size:14px;">rmmod hello</span>
我们还可能使用modinfo来看看关于模块更多的东西:
modinfo hello.ko
4.这是在用lsmod就看不到hello模块了。但是我们的输入信息到那去了呢,不急,如果你是在X Windows下的XTerm中insmod的,你不会看到输出,使用dmesg就可能看到在加载和卸载模块时的输出内容,只有直接在console下才能直接显示到屏幕上。
5.4.printk()函数
记住这里用的是printk而不是printf,在内核中我们是不能调用C库中的函数的,不过C库上的大部份函数在内核中都有实现。
printk主要是为内核提供日志功能, 记录内核信息或用来给出警告用的,因些在调用printk时,我们可以指定输入信息的级别,下表列出了可用的级别。
---------------------------
级别 说明
---------------------------
| KERN_EMERG 紧急情况
| KERN_ALERT 需要立即被注意的错误
| KERN_CRIT 临界情况
| KERN_ERR 错误
| KERN_WARNING 警告
| KERN_NOTICE 普通的
| KERN_INFO 非正式的消息
| KERN_DEBUG 调试信息
---------------------------
以上级别没有一个绝对的定义应该在什么时候用,只能你自己拿主意了。