linux的初始化函数(late_initcall和module_init)

本文详细解析了Linux内核初始化过程中使用到的纯初始化、核心初始化、子系统初始化等不同级别的初始化函数定义及其作用,特别强调了函数指针在初始化流程中的应用,并解释了不同初始化阶段的调用顺序。此外,文章还概述了模块初始化的两种常用方式:`module_init`和`late_initcall`,并讨论了它们在实际开发中的应用场景。

在init.h 中有如下定义

#define pure_initcall(fn)  __define_initcall("0",fn,1)

#define core_initcall(fn)  __define_initcall("1",fn,1)
#define core_initcall_sync(fn)  __define_initcall("1s",fn,1s)
#define postcore_initcall(fn)  __define_initcall("2",fn,2)
#define postcore_initcall_sync(fn) __define_initcall("2s",fn,2s)
#define arch_initcall(fn)  __define_initcall("3",fn,3)
#define arch_initcall_sync(fn)  __define_initcall("3s",fn,3s)
#define subsys_initcall(fn)  __define_initcall("4",fn,4)
#define subsys_initcall_sync(fn) __define_initcall("4s",fn,4s)
#define fs_initcall(fn)   __define_initcall("5",fn,5)
#define fs_initcall_sync(fn)  __define_initcall("5s",fn,5s)
#define rootfs_initcall(fn)  __define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn)  __define_initcall("6",fn,6)
#define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
#define late_initcall(fn)  __define_initcall("7",fn,7)
#define late_initcall_sync(fn)  __define_initcall("7s",fn,7s)

#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)


所有的__init函数在区段.init.text区段中,同时还在.initcall.init中还保存了一份函数指针,
在初始化时内核会通过这些函数指针调用这些__init函数指针,
并在整个初始化完成后,释放整个init区段(包括.init.text,.initcall.init等)。

这些函数在内核初始化过程中的调用顺序只和这里的函数指针的顺序有关

中所述的这些函数本身在.init.text区段中的顺序无关。

在2.6内核中,initcall.init区段又分成7个子区段

不同的区段,调用的顺序不一样,数字越小的优先级越高。


也就是说 late_initcall 还要在 module_init的后面。

 

 

注:驱动函数的初始化应该可以用late_initcall() ,也可以用module_init().

<think> 首先,用户的问题是关于Linux内核中的late_initcallmodule_init的加载先后顺序。我需要根据提供的引用来回答。 回顾引用: - 引用[1]: 提到了late_initcall_sync、late_initcallmodule_init的区别,但具体加载顺序未明确。 - 引用[2]: 指出late_initcall用于需要最后执行的初始化,优先级为7,而module_init等效于device_initcall。 - 引用[3]: 直接说明late_initcallmodule_init之后加载,因为module_init定义为device_initcall,而late_initcall优先级更高(更晚)。 - 引用[4]: 描述了内核初始化等级,有7个等级,module_init是其中一种。 - 引用[5]: 显示了初始化调用段的顺序,其中.initcall7.init对应于late_initcall。 关键点: - 从引用[3]: "late_initcall还要在module_init的后面",意思是late_initcallmodule_init之后加载。 - 引用[2]: late_initcall优先级7,module_init等效于device_initcall(优先级6),所以优先级数字小的先加载。 - 在Linux内核初始化中,优先级数字越小,越早执行。优先级顺序是early_initcall (优先级0 to 5?),device_initcall (6), late_initcall (7)。 总结顺序: - early_initcall: 优先级4或5? 参考引用[5],段顺序是.initcall0.init到.initcall7.init,数字小的先。 - 具体优先级: - device_initcall: 优先级6 (引用[2]) - late_initcall: 优先级7 (引用[2]) - module_init: 定义为device_initcall,所以优先级6 (引用[3]) 因此,加载顺序:device_initcall (module_init)late_initcall 之前执行,因为6 < 7。 在回答中,我需要: - 使用中文。 - 结构清晰。 - 引用相关段落时添加引用标识,如[^1]。 - 生成相关问题(在末尾)。 回答结构: 1. 解释两者的定义优先级。 2. 说明加载先后顺序。 3. 引用适当的引用。 最后,添加相关问题。 §§相关问题§§(用户可见层) 相关问题应该基于主题,比如: 1. 如何修改初始化顺序? 2. 其他初始化宏的区别? 3. 实际应用场景? 确保回答真实可靠。 </think> ### late_initcall module_init 的加载先后顺序 在 Linux 内核中,`late_initcall` `module_init` 都是用于模块初始化的宏,但它们的加载顺序由内核的初始化优先级决定。内核初始化分为多个优先级等级(1~7),优先级数字越小越早执行。以下是具体分析: 1. **module_init 的优先级**: `module_init` 宏定义为 `device_initcall`,其优先级为 6。这意味着使用 `module_init` 注册的初始化函数在内核启动的中间阶段执行,主要用于设备驱动初始化[^2][^3]。 例如: ```c module_init(my_driver_init); // 等效于 device_initcall(my_driver_init) ``` 2. **late_initcall 的优先级**: `late_initcall` 宏的优先级为 7,是内核初始化序列中最后执行的等级。它用于依赖其他驱动的初始化任务,如需要所有核心设备就绪后才能运行的代码[^2][^4]。 例如: ```c late_initcall(my_late_init); ``` 3. **加载先后顺序**: 由于 `module_init`(优先级 6)的优先级数字小于 `late_initcall`(优先级 7),因此 **`module_init` 注册的函数先于 `late_initcall` 执行**。 内核初始化调用段的链接顺序(从 `.initcall0.init` 到 `.initcall7.init`)也确认了这一顺序:`device_initcall`(module_init)对应 `.initcall6.init`,而 `late_initcall` 对应 `.initcall7.init`,数字小的段先加载[^3][^5]。 总结顺序: - 优先级 0~5:早期初始化(如 `core_initcall`)。 - **优先级 6:`module_init`(或 `device_initcall`)**。 - **优先级 7:`late_initcall`**。 ### 为什么这个顺序重要? - `module_init` 适用于大多数驱动,优先执行确保硬件基础就绪。 - `late_initcall` 用于“收尾”任务,例如依赖其他驱动初始化的复杂模块(如文件系统或网络协议栈)[^2][^4]。 如果需要调整顺序,可以通过修改宏或链接脚本实现[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值