module_init和init_module的区别
在看CS8900的驱动时,发现其驱动的模块加载函数是init_module(),由于看到大多数的驱动用的模块加载函数大多是module_init()函数,所以一时没缓过神来,总是在找CS8900的加载函数。
那么,module_init()和init_module()这两个加载函数有什么区别吗?
init_module是默认的模块的入口,如果你想指定其他的函数作为模块的入口就需要module_init函数来指定。
init_module()是真正的入口,module_init是宏,如果在模块中使用,最终还是要转换到init_module()上。如果不是在模块中使用,module_init可以说没有什么作用。总之,使用module_init方便代码在模块和非模块间移植。
init_module 模块入口, 加载时 初始化模块的编码
cleanup_module 卸载时, 注销模块的编码
module_init(dri_arch_init_module); 加载本驱动是执行
module_exit(dri_arch_cleanup_module);卸载驱动时执行
一、编写源代码文件helloworld.c
#include <linux/init.h> //所有模块都必须包含的头文件
#include <linux/module.h> //一些宏定义,例如这里的KERN_INFO
#define DRIVER_AUTHOR "[email protected]"
#define DRIVER_DESC "A sample driver"
int __init init_module(void)
{
printk(KERN_INFO "------------Hello world----------\n");//前面的宏表示打印的级别
return 0; //返回非0表示模块初始化失败,无法载入
}
void __exit cleanup_module(void)
{
printk(KERN_INFO "------------hello exit-----------\n");
}
//模块的许可证
MODULE_LICENSE("GPL");
//模块的作者
MODULE_AUTHOR(DRIVER_AUTHOR);
//模块的描述
MODULE_DESCRIPTION(DRIVER_DESC);
二、编写Makefile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
else
obj-m := helloworld.o
endif
三、编译内核模块
执行make all或make命令,生成helloworld.ko模块。
四、安装内核模块
insmod helloworld.ko
五、查看已安装的内核模块
lsmod
xz@ubuntu2018:~/kernel/helloworld_2$ lsmod
Module Size Used by
helloworld 16384 0
六、查看输出信息
dmesg
[150013.700804] ------------Hello world----------
七、卸载已安装的内核模块
rmmod helloworld