Linux 内核模块 编程相关

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

 

猜你喜欢

转载自blog.csdn.net/BlueBirdssh/article/details/89307467