Linux 内核如何知道在启动时加载哪些驱动程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8469732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does the Linux kernel know which drivers to load at boot?
提问by izzy
I'd like to know this for the first boot and for subsequent boots.
我想知道第一次启动和后续启动时的情况。
I'm compiling my own kernel and want it to be as lean as possible. I want to build the .config file by hand (mainly as a learning experience), so I need to know everything that can be excluded. I know a possible solution is to look at my current distros list of loaded drivers. However, I'm curious about how my distro discovered what drivers to load initially.
我正在编译自己的内核并希望它尽可能精简。我想手动构建 .config 文件(主要是作为学习经验),所以我需要知道可以排除的所有内容。我知道一个可能的解决方案是查看我当前已加载驱动程序的发行版列表。但是,我很好奇我的发行版是如何发现最初要加载哪些驱动程序的。
TIA.
TIA。
回答by Adrian Cornish
Greg Kroah give an excellent example on how to find exactly which drivers you need for you kernel. Kindly Greg gives his book away for free online
Greg Kroah 给出了一个很好的例子,说明如何准确找到内核所需的驱动程序。亲切的格雷格在线免费赠送他的书
A quote from Greg's books
格雷格书中的一句话
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.
回答by j?rgensen
How does the Linux kernel know which drivers to load at boot?
Linux 内核如何知道在启动时加载哪些驱动程序?
The kernel generates events for devices on e.g. the PCI bus when they are plugged (either hot or cold; events are queued until userspace runs AFAIR). udev will receive these events and do modprobe calls which include the PID/VID (product/vendor IDs) of the device(s); this is usually a string with some * in it. modprobe will then calculate the intersection of the set expressed by udev's load request wildcard and the set of aliases of kernel modules (themselves being possibly wildcards).
内核为设备在例如 PCI 总线上插入时生成事件(热的或冷的;事件排队直到用户空间运行 AFAIR)。udev 将接收这些事件并执行 modprobe 调用,其中包括设备的 PID/VID(产品/供应商 ID);这通常是一个带有 * 的字符串。然后 modprobe 将计算由 udev 的加载请求通配符表示的集合与内核模块别名集合(它们本身可能是通配符)的交集。
Since USB/Firewire/etc. controllers are usually attached to the PCI bus, that's how your HCI driver gets loaded. That is how things recurse down; loading is then done with USB/Firewire PID/VIDs of course.
由于 USB/火线/等。控制器通常连接到 PCI 总线,这就是你的 HCI 驱动程序被加载的方式。这就是事情递归下去的方式;当然,加载是通过 USB/Firewire PID/VID 完成的。
Network protocol modules (e.g. ipv6) are however not dealt with through udev; instead, when a program calls socket(AF_INET6, ...)
the kernel directly calls modprobe (more precisely: whatever is in /proc/sys/kernel/modprobe
) with a non-wildcarded alias, net-pf-10
in case of IPv6, because AF_INET6
happens to have value 10. modprobe then loads ipv6.ko
, because that is what has the net-pf-10
alias.
然而,网络协议模块(例如 ipv6)不通过 udev 处理;相反,当程序调用socket(AF_INET6, ...)
内核时/proc/sys/kernel/modprobe
,使用非通配别名直接调用 modprobe(更准确地说:在 中的任何内容),net-pf-10
在 IPv6 的情况下,因为AF_INET6
恰好具有值 10。 modprobe 然后加载ipv6.ko
,因为那是具有net-pf-10
别名的。
Similarly for filesystems, attempting to mount -t foo
will cause the kernel to also call modprobe (again, via ____call_usermodehelper
), this time with foo
as argument.
与文件系统类似,尝试mount -t foo
将导致内核也调用 modprobe (再次,通过____call_usermodehelper
),这次使用foo
as 参数。
Accessing device nodes (e.g. /dev/loop0
, provided it already exists) has the same strategy if loop.ko
is not already loaded. The kernel here requests block-major-7-0
(because loop0 usually has (7,0), cf. ls -l
), and loop.ko
has the fitting block-major-7-*
alias.
/dev/loop0
如果loop.ko
尚未加载,访问设备节点(例如,如果它已经存在)具有相同的策略。这里的内核请求block-major-7-0
(因为 loop0 通常有 (7,0), cf. ls -l
),并且loop.ko
有合适的block-major-7-*
别名。