2012-07-25 84 views

回答

29

内置驱动程序不会是加载,因此内置。它们的初始化函数被调用,当内核自行建立时驱动程序被激活。这些初始化函数在init/main.c::do_initcalls()中调用。所有初始化呼叫分类水平,这是在initcall_levels定义和include/linux/init.h

这些级别是在连接器脚本(arch/*/kernel/vmlinux.lds.*)定义实际工作中的符号。在内核编译时,链接器收集标记为module_init()或其他*_initcall()的所有函数,按级别进行分类,将所有函数放在同一级别,并创建一个类似于函数指针数组的函数。

do_initcall_level()在运行时所做的是调用数组中指针指向的每个函数。除do_initcall_level中的级别之外,没有调用策略,但数组中的顺序在链接时间中确定。

所以,现在你可以看到司机的启动顺序是固定在链接时间,但你可以做什么?

  1. 把你的初始化函数在较高的水平,或
  2. 把你的设备驱动程序在较高位置Makefile

如果你看了上面的第一个是明确的。即)使用early_initcall(),而不是适当的。

第二个需要更多的解释。为什么Makefile问题中的命令是当前内核构建系统如何工作以及连接器如何工作的原因。长话短说,构建系统将获取obj-y中的所有对象文件并将它们链接在一起。它依赖于环境,但链接器很有可能将第一个目标文件放置在较低地址的obj-y中,因此早些时候调用该文件。

如果你只是想让你的驱动程序比同一个目录下的其他驱动程序更早被调用,这是最简单的方法。

+0

感谢@Yasushi Shoji为您提供了非常详细的解释! – 2012-07-26 06:49:11

+0

这是一个很好的答案! – VividD 2014-08-20 08:39:18

0

正确的模块顺序和相关性由modprobe处理,即使在initrd内也是如此。

2

depmod检查每个模块导出和需要的符号,并对它们进行拓扑排序,以便modprobe稍后可以用来以正确的顺序加载模块。要求你想依赖的模块中的符号足以让它做正确的事情。

0

最近我遇到了这个问题,我的充电器驱动程序依赖ADC驱动程序,因此在加载ADC驱动程序充电器驱动程序之前已加载并检查在DTS文件中定义的adc phandle并且必须通过ADC驱动程序进行初始化。它通过更改驱动程序/ Makefile中模块的顺序得到解决