主动控制驱动加载顺序.
编译进内核的驱动可以认为的调整驱动的加载顺序分为如下8个等级:
/*
* 一个“纯”的initcall不依赖于任何其他内容,它仅用于初始化那些无法静态初始化的变量。
*
* 这类initcall仅存在于内置代码中,不适用于模块。
* 请保持main.c中的initcall_level_names[]数组同步更新。
*/
#define pure_initcall(fn) __define_initcall(fn, 0)
#define core_initcall(fn) __define_initcall(fn, 1)
#define core_initcall_sync(fn) __define_initcall(fn, 1s)
#define postcore_initcall(fn) __define_initcall(fn, 2)
#define postcore_initcall_sync(fn) __define_initcall(fn, 2s)
#define arch_initcall(fn) __define_initcall(fn, 3)
#define arch_initcall_sync(fn) __define_initcall(fn, 3s)
#define subsys_initcall(fn) __define_initcall(fn, 4)
#define subsys_initcall_sync(fn) __define_initcall(fn, 4s)
#define fs_initcall(fn) __define_initcall(fn, 5)
#define fs_initcall_sync(fn) __define_initcall(fn, 5s)
#define rootfs_initcall(fn) __define_initcall(fn, rootfs)
#define device_initcall(fn) __define_initcall(fn, 6)
#define device_initcall_sync(fn) __define_initcall(fn, 6s)
#define late_initcall(fn) __define_initcall(fn, 7)
#define late_initcall_sync(fn) __define_initcall(fn, 7s)
/*
* 默认的优先级,使用module_init() 定义的驱动使用的这个优先级.
*/
#define __initcall(fn) device_initcall(fn)
如何使用这些加载顺序宏定义
通常我们使用module_init() 和 module_exit() "函数" 定义驱动的注册和注销函数.其实module_init 也是一个宏定义:
module_init(drm_core_init);
/*
* module_init() - 驱动初始化入口点
* @x: 在内核启动时间或模块插入时运行的函数
*
* module_init() 将在 do_initcalls() 期间(如果是内建驱动)或模块插入时间(如果是模块)被调用。
* 每个模块只能有一个这样的入口点。
*/
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
结合上面的宏定义可知,默认的驱动注册有顺序是6.
如果定义其他初始化顺序只需要使用相应的宏定义声明驱动的注册和注销函数即可.
参考: