【问题标题】:How does the Linux kernel know which drivers to load at boot? [closed]Linux 内核如何知道启动时要加载哪些驱动程序? [关闭]
【发布时间】:2023-03-07 18:34:02
【问题描述】:

我想在第一次启动和后续启动时知道这一点。

我正在编译自己的内核并希望它尽可能精简。我想手动构建.config文件(主要作为学习经验),所以我需要知道所有可以排除的东西。我知道一个可能的解决方案是查看我当前的已加载驱动程序的发行版列表。不过,我很好奇我的发行版是如何发现最初要加载的驱动程序的。

TIA。

【问题讨论】:

标签: linux module kernel


【解决方案1】:

Greg Kroah 给出了一个很好的例子,说明如何准确找到内核所需的驱动程序。请格雷格在线免费赠送他的书

http://files.kroah.com/lkn/

格雷格书中的一句话

I'm especially proud of the chapter on how to figure out how to configure
a custom kernel based on the hardware running on your machine. This is an
essential task for anyone wanting to wring out the best possible speed and
control of your hardware. 

【讨论】:

  • 感谢您的回答阿德里安。实际上,我现在正在阅读本书的第 7 章。 Greg Kroah 详细介绍了发现正在运行的内核当前加载了哪些模块的过程——这非常有价值。我很好奇的是操作系统是如何知道加载这些模块的?
  • ASAIK 蛮力一般 - 它会尝试加载它 - 如果它不起作用,硬件可能不存在。
【解决方案2】:

Linux 内核如何知道启动时要加载哪些驱动程序?

内核为设备生成事件,例如插入时的 PCI 总线(热或冷;事件排队,直到用户空间运行 AFAIR)。 udev 将接收这些事件并执行 modprobe 调用,其中包括设备的 PID/VID(产品/供应商 ID);这通常是一个带有 * 的字符串。然后 modprobe 将计算 udev 的加载请求通配符表示的集合与内核模块的别名集合(它们本身可能是通配符)的交集。

由于 USB/火线/等。控制器通常连接到 PCI 总线,这就是加载 HCI 驱动程序的方式。事情就是这样递归的;然后当然是使用 USB/Firewire PID/VID 完成加载。

然而,网络协议模块(例如 ipv6)不通过 udev 处理;相反,当程序调用socket(AF_INET6, ...) 时,内核会直接调用 modprobe(更准确地说:/proc/sys/kernel/modprobe 中的任何内容)并使用非通配符别名 net-pf-10(在 IPv6 的情况下),因为 AF_INET6 的值恰好为 10。 modprobe 然后加载ipv6.ko,因为那是net-pf-10 别名。

同样对于文件系统,尝试mount -t foo 将导致内核也调用 modprobe(同样,通过____call_usermodehelper),这次使用foo 作为参数。

如果loop.ko 尚未加载,则访问设备节点(例如/dev/loop0,前提是它已经存在)具有相同的策略。这里的内核请求block-major-7-0(因为loop0通常有(7,0),参见ls -l),而loop.ko有合适的block-major-7-*别名。

【讨论】:

  • 难道没有像modules.syms这样的文件,列出启动时要加载的设备吗?
  • 这些事件什么时候开始触发?是在 initramfs 中调用 init 之前吗?或者是否需要通知内核可以开始初始事件触发?
猜你喜欢
  • 2018-03-19
  • 2014-07-09
  • 2010-10-31
  • 2021-06-22
  • 1970-01-01
  • 2014-09-30
  • 1970-01-01
  • 1970-01-01
  • 2021-02-08
相关资源
最近更新 更多