【发布时间】:2016-07-29 15:28:35
【问题描述】:
我们如何自定义内置驱动加载顺序(让一些内置驱动模块先加载,依赖模块后加载)?
【问题讨论】:
标签: linux linux-kernel linux-device-driver
我们如何自定义内置驱动加载顺序(让一些内置驱动模块先加载,依赖模块后加载)?
【问题讨论】:
标签: linux linux-kernel linux-device-driver
内置驱动程序不会加载,因此是内置的。它们的初始化函数被调用,驱动程序在内核自行设置时被激活。这些初始化函数在init/main.c::do_initcalls() 中调用。所有的init调用都按级别分类,定义在initcall_levels和include/linux/init.h中
这些级别是在链接描述文件 (arch/*/kernel/vmlinux.lds.*) 中定义的实际符号。在内核编译时,链接器收集所有标记为module_init() 或其他*_initcall() 的函数,按级别分类,将同一级别中的所有函数放在同一位置,并像函数指针数组一样创建。
do_initcall_level() 在运行时所做的是调用数组中指针指向的每个函数。 do_initcall_level中除了levels之外没有调用策略,但是数组中的顺序是由链接时间决定的。
那么,现在你可以看到驱动的启动顺序在链接时是固定的,但是你能做什么呢?
Makefile的较高位置
如果您阅读了以上内容,第一个就很清楚了。即)如果合适,请改用 early_initcall()。
第二个需要更多解释。 Makefile 中的顺序之所以重要,是因为当前内核构建系统如何工作以及链接器如何工作。长话短说,构建系统获取obj-y 中的所有目标文件并将它们链接在一起。它高度依赖于环境,但链接器很有可能将第一个目标文件放在较低地址的obj-y 中,因此更早地调用。
如果您只是希望您的驱动程序比同一目录中的其他驱动程序更早被调用,这是最简单的方法。
【讨论】:
depmod 检查每个模块导出和需要的符号,并对它们进行拓扑排序,modprobe 稍后可以使用这些符号以正确的顺序加载模块。从您希望依赖的模块中请求符号就足以让它做正确的事情。
【讨论】:
最近我遇到了这个问题,我的充电器驱动程序依赖于 ADC 驱动程序,因此在加载 ADC 驱动程序之前,充电器驱动程序已加载并检查 DTS 文件中定义的 adc phandle,并且必须由 ADC 驱动程序初始化。它通过更改驱动程序/Makefile 中的模块顺序得到解决
【讨论】: