__init和__exit
/* 入口函数 */static int __init _driver_init(void){int ret; printk("dht11 %s\n", __FUNCTION__); ret = platform_driver_register(&_platform_driver); //注册platform驱动return ret;}/* 出口函数 */static void __exit _driver_exit(void){ printk("dht11 %s\n", __FUNCTION__); platform_driver_unregister(&_platform_driver);}
如上,写过linux驱动的应该都见多__init和__exit修饰模块的出口和入口函数,
那这两个东西是什么干嘛用的呢?
如下所示,__init和__exit在内核中定义如下,它们本质是宏定义,作用是将模块出口和入口函数放到指定的段。
#define __init __section(.init.text) // 放入初始化代码段#define __exit __section(.exit.text) // 放入清理代码段
为什么要将出入口函数放到指的段?
__init的核心作用
内核会把该函数放到专门的初始化内存段,这个函数只在模块加载的时候执行一次,执行完就没用了
模块加载成功后,内核会释放掉这段内存。
__exit的核心作用
编译后内核会把模块出口函数放到清理函数内存段,模块卸载执行该函数,如何内核编译禁用模块卸载功能,
内核会丢弃该函数,不占用内存。
可以不用它们修饰出入口函数么?
语法上可以,能编译、加载、卸载
但是,在工程上绝对不行,违反Linux内核规范了。
如果不修饰会造成内存浪费,初始化函数执行完后,代码还驻留内核内存中,始终占用。
特别在嵌入式、服务器场景下,会浪费宝贵内存。