我正在为网络启动项目构建一个完全自定义的 initramfs,并在此过程中学习了很多相关知识,但我对模块的加载感到有点困惑。
我知道modprobe
可以用来加载模块,但是它如何决定加载哪些模块呢?
我现在所拥有的是 initramfs 在虚拟框中启动并运行 shell。但lsmod
显示没有加载模块。我需要init
做的是加载正确的网络模块,以便我可以建立网络。
如果我modprobe e1000
真的加载了正确的模块。
在查看 Ubuntu 启动过程时,我看不到 Ubuntu 决定它应该如何加载e1000
。我本以为它只是modprobe
每个可用的网卡驱动程序,但它似乎并没有这样做。
我猜UDEV 与此有关?
答案1
我知道modprobe可以用来加载模块,但是它如何决定加载哪些模块呢?
当内核需要一个不常驻于内核的功能时,内核模块守护进程kmod
1execsmodprobe
加载模块。modprobe
以两种形式之一传递一个字符串。
- 模块名称,如 softdog 或 ppp。
- 更通用的标识符,例如 char-major-10-30
因此,让我解释一下我在系统中发现的内容,而不是从链接粘贴。
cat /proc/modules
- 此命令列出了加载的模块,并且该列表是一个相当大的列表。
现在,在系统启动期间,正如我已经提到的,kmod
守护进程执行modprobe
来加载模块。我们可以按照已经讨论过的两种方式指定要加载的模块。如果我们指定了通用标识符,它将在/etc/modprobe.conf
别名中查找该条目。因此,在我的 中/etc/modprobe.conf
,我有一个别名,如下所示。
alias eth0 tg3
因此,我运行以下命令来检查系统中的 tg3 是什么。
-bash-3.2$ cat /proc/modules | grep tg3
tg3 139225 0 - Live 0xf8bd1000
接下来,modprobe
查看该文件/lib/modules/version/modules.dep
,看看在加载请求的模块之前是否必须加载其他模块。该文件由模块依赖项创建depmod -a
并包含模块依赖项。
最后,modprobe
用于insmod
首先将所有必备模块加载到内核中,然后再加载所请求的模块。modprobe
指向[ insmod
3 /lib/modules/version/
],模块的标准目录。insmod
旨在对模块的位置相当愚蠢,而modprobe
了解模块的默认位置,知道如何找出依赖关系并以正确的顺序加载模块。
但新硬件是如何检测到的呢?
这些环是由 CPU 而不是操作系统创建的。任何操作系统内核都运行在最高特权级别的 Ring 0 中,可以直接与硬件和 CPU 通信。环 1 和环 2 通常用于设备驱动程序。环 3 用于用户空间应用程序(媒体播放器、Web 服务器以及用户可以直接通信的任何其他内容)。设备驱动程序是用户空间应用程序和硬件之间的“桥梁”。
Linux 内核不断扫描所有计算机总线以查找任何更改和新硬件。一旦检测到任何总线上的任何变化,魔法就开始了。
魔术
- 将硬件信息导出到用户空间 (SYSFS)
- *通知用户空间工具硬件可用(UEVENT 和 UDEVD)
- 是的,你的假设是正确的。 udev 与魔法有关:)*
- 处理事件,将它们与 /ETC/UDEV/RULES.D/ 中的规则进行匹配,并填充 /DEV 目录(UDEVD 和 UDEV)
- 加载设备驱动程序(UDEV、MODPROBLE)
- 通知用户空间应用程序(通过 D-BUS)
udevd 只是一个守护进程,位于内核和所有 udev 系统之间,并执行一些重要的功能(我稍后会提到)。 udev 守护进程 (udevd) 在启动时启动,然后读取并解析 /etc/udev/rules.d/ 中找到的所有规则,并将这些规则保存在内存(udev 数据库)中以供 udev 进一步使用。稍后 udevd 开始在 netlink 上侦听来自内核驱动程序核心的 uevents。