我对内置内核模块的工作方式感到困惑。根据我的理解,可以通过将 kconfig 选项设置为 来在编译 Linux 内核时嵌入内核模块MODULE_NAME=y
。然后,它不必加载eg modprobe
。内置内核模块可以用cat /lib/modules/$(uname -r)/modules.builtin
.
当我执行此命令时,列表显示.ko
文件。但如果它们嵌入到内核中,为什么会显示这个?例如:
~$ cat /lib/modules/$(uname -r)/modules.builtin | grep -i bsg #just picking something random
kernel/block/bsg.ko
~$ cat /boot/config-6.5.0-14-generic | grep -i bsg
CONFIG_BLK_DEV_BSG_COMMON=y #implying this is a builtin module
CONFIG_BLK_DEV_BSGLIB=y
CONFIG_BLK_DEV_BSG=y
CONFIG_SCSI_UFS_BSG=y
~$ modinfo bsg
name: bsg
filename: (builtin)
license: GPL
file: block/bsg #why "file"? Isn't it compiled inside the kernel?
...
~$ cat /lib/modules/6.5.0-14-generic/kernel/block/bsg.ko
cat: /lib/modules/6.5.0-14-generic/kernel/block/bsg.ko: No such file or directory
所以我的问题是:
- 内置内核模块究竟发生了什么以及它们驻留在系统内的什么位置?
- 它们是否位于 vmlinuz 内并以某种方式提取?
- 为什么它们显示为
.ko
文件,但不存在于我期望的目录中?
考虑到它们确实嵌入在 vmlinu(x/z) 中,它们最终如何被“注册”以便我们可以使用找到它们modinfo
?如果它位于内核二进制文件中,为什么它仍然有一个如 modinfo 显示的文件(block/bsg)?
答案1
内置内核“模块”(它们不是真正的模块)vmlinux
在压缩之前是主内核二进制文件的一部分。它们永远不会作为单独的实体提取,而是与内核的其余部分一起加载。
它们以.ko
文件的形式出现modules.builtin
,以便其他工具更容易使用,例如用于模块依赖性分析。通过将它们列为.ko
文件,可以像模块一样处理它们。
当内核的组件是内置的,但它们的源文件包含模块声明时,那里提供的信息存储在modules.builtin
和 中modules.builtin.modinfo
(请参阅Kbuild 文档)。modules.builtin
允许modprobe
处理内置模块的加载请求,并modules.builtin.modinfo
允许modinfo
提供有关它们的信息。内置组件没有文件名(对于可加载模块来说,它指向.ko
磁盘上的实际内容),但它们确实有一个文件——这是一个特定于内置模块的条目,存储了模块的名称来源包含模块声明的文件(block/bsg.c
在你的例子中)。