简体   繁体   English

什么是Linux内置驱动程序加载顺序?

[英]What is the Linux built-in driver load order?

我们如何定制内置驱动程序加载顺序(首先加载一些内置驱动程序模块,然后加载依赖模块)?

Built-in drivers wont be loaded , hence built-in. 内置驱动程序无法加载 ,因此内置。 Their initialization functions are called and the drivers are activated when kernel sets up itself. 调用它们的初始化函数,并在内核自行设置时激活驱动程序。 These init functions are called in init/main.c::do_initcalls() . 这些init函数在init/main.c::do_initcalls()中调用。 All init calls are classified in levels, which are defined in initcall_levels and include/linux/init.h 所有init调用都按级别进行分类,这些级别在initcall_levelsinclude/linux/init.h

These levels are actuall symbols defined in linker script ( arch/*/kernel/vmlinux.lds.* ). 这些级别是链接器脚本( arch/*/kernel/vmlinux.lds.* )中定义的实际符号。 At kernel compile time, the linker collects all function marked module_init() or other *_initcall() , classify in levels, put all functions in the same level together in the same place, and create like an array of function pointers. 在内核编译时,链接器收集标记为module_init()或其他*_initcall()所有函数,在级别中进行分类,将所有函数放在同一级别的同一位置,并创建类似函数指针的数组。

What do_initcall_level() does in the run-time is to call each function pointed by the pointers in the array. do_initcall_level()在运行时执行的操作是调用数组中指针指向的每个函数。 There is no calling policy, except levels, in do_initcall_level, but the order in the array is decided in the link time. 在do_initcall_level中除了级别之外没有调用策略,但是数组中的顺序是在链接时决定的。

So, now you can see that the driver's initiation order is fixed at the link time, but what can you do? 所以,现在您可以看到驱动程序的启动顺序在链接时是固定的,但您可以做什么?

  1. put your init function in the higher level, or 将你的init函数放在更高级别,或者
  2. put your device driver at the higher position in Makefile 将您的设备驱动程序放在Makefile中的较高位置

The first one is clear if you've read the above. 如果你已经阅读了上述内容,那么第一个是清楚的。 ie) use early_initcall() instead if it is appropriate. 即)如果合适,请使用early_initcall()。

The second one needs a bit more explanation. 第二个需要更多解释。 The reason why the order in a Makefile matter is how the current kernel build system works and how the linkers works. Makefile的顺序很重要的原因是当前内核构建系统的工作方式以及链接器的工作方式。 To make a long story short, the build system takes all object files in obj-y and link them together. 简而言之,构建系统将所有目标文件都放在obj-y并将它们链接在一起。 It is highly environment dependent but there is high probability that the linker place first object file in the obj-y in lower address, thus, called earlier. 它高度依赖于环境,但链接器很可能将第一个目标文件放在较低地址的obj-y中,因此,之前会调用它。

If you just want your driver to be called earlier than other drivers in the same directory, this is simplest way to do it. 如果您只想比同一目录中的其他驱动程序更早地调用驱动程序,这是最简单的方法。

depmod examines the symbols exported and required by each module and does a topological sort on them that modprobe can later use to load modules in the proper order. depmod检查每个模块导出和要求的符号,并对它们进行拓扑排序, modprobe稍后可以按正确的顺序加载模块。 Requiring the symbols from modules you wish to be dependent on is enough for it to do the right thing. 要求您希望依赖的模块中的符号足以使其做正确的事情。

正确的模块顺序和依赖关系由modprobe处理,即使在initrd中也是如此

Recently i got this problem my charger driver is having dependency on ADC driver so before loading ADC driver charger driver has loaded and checking for adc phandle which is defined in DTS file and has to intialize by ADC driver. 最近我遇到了这个问题我的充电器驱动程序依赖于ADC驱动程序所以在加载ADC驱动程序充电器驱动程序之前加载并检查在DTS文件中定义的adc phandle并且必须由ADC驱动程序初始化。 its got resolved by changing the order of the module in drivers/Makefile 它通过更改drivers / Makefile中模块的顺序得到解决

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM