网站建设查看框架的源代码,室内装修公司招聘信息,商标大全 logo,wordpress分类目录插件linux版本#xff1a;4.19 module_init()与module_exit()用于驱动的加载#xff0c;分别是驱动的入口与退出函数
module_init()#xff1a;内核启动时或动态插入模块时调用module_exit()#xff1a;驱动移除时调用 本篇文章介绍module_init()
module_init()
module_init…linux版本4.19 module_init()与module_exit()用于驱动的加载分别是驱动的入口与退出函数
module_init()内核启动时或动态插入模块时调用module_exit()驱动移除时调用 本篇文章介绍module_init()
module_init()
module_init()是驱动的入口函数该函数定义在include\linux\module.h文件
/*** module_init() - driver initialization entry point* x: function to be run at kernel boot time or module insertion** module_init() will either be called during do_initcalls() (if* builtin) or at module insertion time (if a module). There can only* be one per module.*/
#define module_init(x) __initcall(x);__initcall(x)函数定义在include\linux\init.h文件里面
#define __initcall(fn) device_initcall(fn)device_initcall(fn)定义也在include\linux\init.h文件里面
#define device_initcall(fn) __define_initcall(fn, 6)__define_initcall(fn, 6)定义也在include\linux\init.h文件里面
#define __define_initcall(fn, id) ___define_initcall(fn, id, .initcall##id)___define_initcall(fn, id, .initcall##id)定义也在include\linux\init.h文件里面
/** initcalls are now grouped by functionality into separate* subsections. Ordering inside the subsections is determined* by link order. * For backwards compatibility, initcall() puts the call in * the device init subsection.** The id arg to __define_initcall() is needed so that multiple initcalls* can point at the same handler without causing duplicate-symbol build errors.** Initcalls are run by placing pointers in initcall sections that the* kernel iterates at runtime. The linker can do dead code / data elimination* and remove that completely, so the initcall sections have to be marked* as KEEP() in the linker script.*/#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS
#define ___define_initcall(fn, id, __sec) \__ADDRESSABLE(fn) \asm(.section \ #__sec .init\, \a\ \n \__initcall_ #fn #id : \n \.long #fn - . \n \.previous \n);
#else
#define ___define_initcall(fn, id, __sec) \static initcall_t __initcall_##fn##id __used \__attribute__((__section__(#__sec .init))) fn;
#endif综上module_init调用顺序如下
module_init()---__initcall()---device_initcall()---__define_initcall()---___define_initcall()对___define_initcall()函数进行分析 首先了解一下#与##的作用
符号作用举例##“##”符号可以是连接的意思例如initcall_##fn##id为initcall_fnid假设fn为fbmem_initid6时initcall_##fn##id为initcall_fbmem_init6##符号可以是字符串的意思例如#id为“id”id6时#id为“6”
所以module_init(fbmem_init)函数相当于
static initcall_t __initcall_fbmem_init6 __used __attribute__((__section__(.initcall6.init))) fbmem_init这行代码定义了一个静态变量__initcall_fbmem_init6变量类型为initcall_t(是一个函数指针类型用于表示内核的初始化函数)__used 用于告诉编译器不要将“__initcall_fbmem_Init6”变量视为未使用的变量避免编译器优化移除它。 attribute((section(“.initcall6.init”)))编译器指令告诉编译器将“__initcall_fbmem_init6”变量放置在‘.initcall6.init’的代码段中这个代码段通常用于存放内核的初始化函数在启动的时候按顺序执行.initcall1.init、.initcall2.init 。。。 ‘ fbmem_init’ 这将’__initcall_fbmem_init6’初始化为指向‘fbmem_init’函数的指针。 总之这段代码的作用是将‘fbmem_init’函数注册为一个初始化函数使其在内核启动的时候执行。 对于编译成模块执行sudo insmod的时候是如何加载的等我知道后再来写