用于构建外部模块的 Linux 内核文档页面 (https://www.kernel.org/doc/Documentation/kbuild/modules.txt)这样说:
=== 2. 如何构建外部模块
要构建外部模块,您必须有一个可用的预构建内核,其中包含构建中使用的配置和头文件。此外,内核必须在启用模块的情况下构建。如果您使用的是发行版内核,则您的发行版将为您运行的内核提供一个软件包。
另一种方法是使用“make”目标“modules_prepare”。这将确保内核包含所需的信息。该目标仅作为准备内核源代码树以构建外部模块的简单方法而存在。
我的问题如下:
要构建外部模块,您必须有一个预构建的内核包含构建中使用的配置和头文件的可用文件
“预构建内核”是指编译后的二进制映像(通常命名为 vmlinux/vmlinuz)吗?为什么需要二值图像?配置文件、头文件和编译器不就够了吗?
要构建外部模块,您必须有一个可用的预构建内核包含配置和头文件在构建中使用。
如果预构建内核意味着二进制映像,那么“包含配置和头文件”是什么意思?我可以理解源代码树需要“包含配置和头文件”,但在二进制文件的情况下,这些文件只是用于生成指令,对吗?那么“包含”是什么意思呢? “预构建内核”是否意味着构建内核的整个源代码树?
另外,内核必须是启用模块构建。
他们指的是这里的“制作模块”步骤还是有什么不同?
如果您使用的是发行版内核,会有一个包裹对于您正在运行的内核,由您的发行版提供。
我想他们在这里指的是 kernel-devel 包,它提供了内核构建过程中使用的头文件和配置文件。那是对的吗?
另一种方法是使用“make”目标“modules_prepare”。这将确保内核包含所需的信息。
这是什么意思?这是否意味着如果我们在源目录中执行“make module_prepare”,我们不需要构建内核二进制文件就能够构建外部模块?
答案1
ad 1. 和 2. 内核映像称为 vmlinux,没错,但是当您想要构建外部模块时,这并不是您实际需要的。这是配置和头文件从这个内核中得到所需要的。
ad 3. 要构建内部或外部模块,您需要在该内核中支持可加载模块,当然,您要为其构建模块,因此必须使用 __modulesenabled_ 配置内核。
内核由配置程序之一进行配置,该程序可帮助您.config
在内核源代码树或路径中创建文件$KBUILD_OUTPUT
,以进行树外构建。
ad 4. 在哪里找到此类包或它们的命名方式取决于您的发行版,但我认为它通常被称为kernel-devel
.我实际上不知道,因为我多年来一直使用自己的内核树。
ad 5. 是的,您实际上不需要内核二进制文件来编译外部模块,但您抑制了下面的注释
注意:即使设置了 CONFIG_MODVERSIONS,“modules_prepare”也不会构建 Module.symvers;因此,需要执行完整的内核构建才能使模块版本控制工作。
我认为大多数内核都使用 CONFIG_MODVERSIONS。您可以在您的.config
文件中看到这一点
$ grep MODVERSIONS .config
CONFIG_MODVERSIONS=y
这意味着,您构建的模块将仅适用于您为其构建的内核版本和配置。
因此,您可以为该内核和内核版本构建一个模块,但如果没有该内核和内核版本,则无法运行它。
这就是为什么您可以在没有完整内核源代码树的情况下为发行版内核构建外部模块,如果您安装了构建该发行版内核的内核配置和头文件。
实际上,大多数时候您只想为运行系统的内核构建一个外部模块。如果您自己从内核源代码树构建内核,您将已经拥有与该内核匹配的内核配置和头文件。
如果您运行发行版内核,则必须从发行版安装该文件。