helloworld
/*Linux驱动源代码hello.c*/
#include<linux/init.h>
#include<linux/module.h>
static int __inithello_init(void)
{ /*模块初始化函数*/
printk(KERN_ALERT"Hello,world\n");
return 0;
}
static void __exithello_exit(void)
{ /*模块卸载函数*/
printk(KERN_ALERT "Goodbye,cruelworld\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("DualBSD/GPL");
所有的模块代码都必须包含两个头文件:
#include<linux/init.h>
#include<linux/module.h>
使用宏MODULE_LICENSE指明模块代码所使用的许可证
此外还有可选的其他描述符定义,比如
MODULE_AUTHOR("");
MODULE_DESCRIPTION("");
MODULE_VERSION("");
上述MODULE_声明习惯上放在文件最后
模块初始化函数定义通常如下
static int __initinitialization_function(void)
{
}
module_init(initialization_function);
使用module_init指明函数initialization_function为模块初始化函数
注意:__init标志标识这个函数应该位于初始化调用段里面,这个段里面的函数只会调用一次,调用后会回收,也可以不要这个标志。
模块卸载函数定义通常如下
static void __exitcleanup_function(void)
{
}
module_exit(cleanup_function);
使用module_exit指明函数cleanup_function为模块卸载函数编译这个驱动模块的Makefile如下
KERNELDIR=/arm/linux-2.6.32.2
PWD :=$(shell pwd)
ARCH=arm
CROSS_COMPILE=arm-linux-
CC=$(CROSS_COMPILE)gcc
obj-m:=hello.o
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD)
clean:
rm -f *.o *.ko Module.* *.mod.c
.PHONY:modules clean
obj-m := hello.o
代表了我们要构造的模块名为hell.ko,make 会在该目录下自动找到hell.c文件进行编译。
$(MAKE) -C$(KERNELDIR) M=$(PWD) modules
-C $(KERNELDIR) 指定了内核源代码的位置,其中保存有内核的顶层makefile文件。
M=$(PWD) 指定了模块源代码的位置
modules目标指向obj-m变量中设定的模块。
注意:
一定要linux内核配置中支持模块加载,编译内核后,再编译驱动,不然编译会有错误。内核版本为2.6.32.2
[*] Enable loadable module support --->
--- Enable loadable module support
[*] Module unloading