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

时间:2022-06-02 15:33:52

How can we customize the built-in driver load order (to make some built-in driver module load first, and the dependent module load later)?

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

4 个解决方案

#1


32  

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(). All init calls are classified in levels, which are defined in initcall_levels and include/linux/init.h

内置驱动程序无法加载,因此内置。调用它们的初始化函数,并在内核自行设置时激活驱动程序。这些init函数在init / main.c :: do_initcalls()中调用。所有init调用都按级别分类,这些级别在initcall_levels和include / linux / init.h中定义

These levels are actuall symbols defined in linker script (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.

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

What do_initcall_level() does in the run-time is to call each function pointed by the pointers in the array. 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()在运行时执行的操作是调用数组中指针指向的每个函数。在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
  2. 将你的init函数放在更高级别,或者
  3. put your device driver at the higher position in Makefile
  4. 将您的设备驱动程序放在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. To make a long story short, the build system takes all object files in obj-y and link them together. 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.

第二个需要更多解释。 Makefile中的顺序很重要的原因是当前内核构建系统的工作方式以及链接器的工作方式。简而言之,构建系统将所有目标文件都放在obj-y中并将它们链接在一起。它高度依赖于环境,但链接器很可能将第一个目标文件放在较低地址的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.

如果您只想比同一目录中的其他驱动程序更早地调用驱动程序,这是最简单的方法。

#2


2  

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. Requiring the symbols from modules you wish to be dependent on is enough for it to do the right thing.

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

#3


0  

Correct module order and dependencies are handled by modprobe, even within the initrd.

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

#4


0  

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. its got resolved by changing the order of the module in drivers/Makefile

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

#1


32  

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(). All init calls are classified in levels, which are defined in initcall_levels and include/linux/init.h

内置驱动程序无法加载,因此内置。调用它们的初始化函数,并在内核自行设置时激活驱动程序。这些init函数在init / main.c :: do_initcalls()中调用。所有init调用都按级别分类,这些级别在initcall_levels和include / linux / init.h中定义

These levels are actuall symbols defined in linker script (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.

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

What do_initcall_level() does in the run-time is to call each function pointed by the pointers in the array. 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()在运行时执行的操作是调用数组中指针指向的每个函数。在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
  2. 将你的init函数放在更高级别,或者
  3. put your device driver at the higher position in Makefile
  4. 将您的设备驱动程序放在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. To make a long story short, the build system takes all object files in obj-y and link them together. 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.

第二个需要更多解释。 Makefile中的顺序很重要的原因是当前内核构建系统的工作方式以及链接器的工作方式。简而言之,构建系统将所有目标文件都放在obj-y中并将它们链接在一起。它高度依赖于环境,但链接器很可能将第一个目标文件放在较低地址的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.

如果您只想比同一目录中的其他驱动程序更早地调用驱动程序,这是最简单的方法。

#2


2  

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. Requiring the symbols from modules you wish to be dependent on is enough for it to do the right thing.

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

#3


0  

Correct module order and dependencies are handled by modprobe, even within the initrd.

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

#4


0  

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. its got resolved by changing the order of the module in drivers/Makefile

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