内置内核模块驻留在哪里?

内置内核模块驻留在哪里?

我对内置内核模块的工作方式感到困惑。根据我的理解,可以通过将 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在你的例子中)。

相关内容