编译进入内核的驱动程序的init函数调用 [英] init function invocation of drivers compiled into kernel

查看:154
本文介绍了编译进入内核的驱动程序的init函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux中,如果将设备驱动程序构建为可加载的内核模块,则在插入设备驱动程序内核模块后,内核会调用module_init()宏指出的设备驱动程序的init函数.

In Linux if device drivers are built as loadable kernel modules, then upon inserting the device driver kernel module, the kernel calls the init function of the device driver as pointed out by module_init() macro.

这对于静态编译到内核中的设备驱动程序如何起作用?他们的init函数如何调用?

How does this work for device drivers that are statically compiled into the kernel ? How is their init function called ?

推荐答案

内置驱动程序的 init 例程仍可以使用module_init()宏声明该入口点.或者,当驱动程序永远不会被编译为可加载模块时,驱动程序可以使用device_initcall().或者要在启动顺序的早期阶段进行初始化,驱动程序可以使用subsys_initcall().

The init routine of a built-in driver can still use the module_init() macro to declare that entry point. Or the driver can use device_initcall() when the driver would never be compiled as a loadable module. Or to move its initialization very early in the boot sequence, the driver could use subsys_initcall().

include/linux/init.h中,调用这些 init 例程的顺序描述为:

In include/linux/init.h the sequence for invoking these init routines is described as:

/* initcalls are now grouped by functionality into separate 
 * subsections. Ordering inside the subsections is determined
 * by link order. 
 * For backwards compatibility, initcall() puts the call in 
 * the device init subsection.
 *
 * The `id' arg to __define_initcall() is needed so that multiple initcalls
 * can point at the same handler without causing duplicate-symbol build errors.
 */

我假设设备驱动程序的这些小节对应于Linux内核源代码树的drivers目录中的子目录,并且链接顺序记录在其中drivers中每个子目录的 built-in.o 文件.因此,在内核引导过程中,每个内置驱动程序的 init 例程最终都由init/main.c中的do_initcalls()执行.

I assume that these subsections for device drivers correspond to the subdirectories within the drivers directory of the Linux kernel source tree, and that the link order is recorded in the built-in.o file of each subdirectory in drivers. So during kernel boot the init routine of each built-in driver is eventually executed by do_initcalls() in init/main.c.

设备驱动程序的 init 例程负责探测系统,以验证硬件设备是否确实存在.探测失败时,驱动程序不应分配任何资源或注册任何设备.

The init routine of the device driver is responsible for probing the system to verify that the HW device actually exists. The driver should not allocate any resources or register any devices when the probe fails.

更新:
在内核命令行上传递选项"initcall_debug"将导致每个initcall的计时信息被打印到控制台. initcall用于初始化静态链接的内核驱动程序和子系统,并为Linux引导过程贡献大量时间.输出如下:

UPDATE:
Passing the option "initcall_debug" on the kernel command line will cause timing information to be printed to the console for each initcall. initcalls are used to initialize statically linked kernel drivers and subsystems and contribute a significant amount of time to the Linux boot process. The output looks like:

calling  tty_class_init+0x0/0x44 @ 1
initcall tty_class_init+0x0/0x44 returned 0 after 9765 usecs
calling  spi_init+0x0/0x90 @ 1
initcall spi_init+0x0/0x90 returned 0 after 9765 usecs

参考: http://elinux.org/Initcall_Debug

这篇关于编译进入内核的驱动程序的init函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆