如何快速构建精简的 Linux 内核¶

循序渐进指南¶

原则上,编译您自己的 Linux 内核很容易。有很多种方法可以做到这一点。哪些方法实际上有效并且是最好的取决于具体情况。

本指南介绍了一种非常适合那些想从源码快速安装 Linux 而不受复杂细节困扰的人的方法;目标是涵盖在运行于商品 PC 或服务器硬件上的主流 Linux 发行版上通常需要的一切。

所描述的方法非常适合用于测试目的,例如尝试建议的修复程序或检查问题是否已在最新的代码库中修复。尽管如此,以这种方式构建的内核对于日常使用也完全没问题,同时也很容易保持最新状态。

以下步骤描述了该过程的重要方面;后面的综合参考部分更详细地解释了其中的每一个步骤。它有时还会描述替代方法、陷阱以及可能在特定点发生的错误——以及如何重新开始。

创建一个新的备份,并将系统修复和还原工具放在手边,以便为发生意外情况做好准备。

[详情]

在具有“安全启动”或类似技术的平台上,准备好一切,以确保系统以后允许您自行编译的内核启动。在商品 x86 系统上实现此目的的最快、最简单的方法是在 BIOS 设置实用程序中禁用此类技术;或者,通过 mokutil --disable-validation 启动的过程来删除其限制。

[详情]

安装构建 Linux 内核所需的所有软件。通常您需要:‘bc’、‘binutils’(‘ld’ et al.)、‘bison’、‘flex’、‘gcc’、‘git’、‘openssl’、‘pahole’、‘perl’ 以及 ‘libelf’ 和 ‘openssl’ 的开发头文件。参考部分显示了如何在各种流行的 Linux 发行版上快速安装这些文件。

[详情]

确保有足够的可用空间来构建和安装 Linux。对于后者,/lib/ 中 150 兆字节和 /boot/ 中 100 兆字节是一个安全的选择。对于存储源码和构建工件,您的主目录中通常应该有 12 GB 的空间。如果您的可用空间较少,请务必查看参考部分中解释调整内核构建配置的步骤:它提到了一个技巧,可以将 /home/ 中所需的空间减少到大约 4 GB。

[详情]

检索您要构建的 Linux 版本的源码;然后更改到包含它们的目录中,因为本指南中的所有其他命令都应从那里执行。

[注意:以下段落描述了如何通过部分克隆 Linux 稳定 git 存储库来检索源码。这称为浅克隆。参考部分解释了两种替代方法: 打包的存档 和 完整的 git 克隆 ;如果下载大量数据不会困扰您,则首选后者,因为它将避免参考部分解释的浅克隆的一些 特殊特性 。]

首先,执行以下命令来检索新的主线代码库

git clone --no-checkout --depth 1 -b master \

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git ~/linux/

cd ~/linux/

如果您想访问最近的主线版本和预发布版本,请将克隆的历史记录加深到您感兴趣的最旧的主线版本

git fetch --shallow-exclude=v6.0 origin

如果您想访问稳定/长期版本(例如 v6.1.5),只需添加包含该系列的 branch;之后,至少获取到启动该系列的主线版本(v6.1)的历史记录

git remote set-branches --add origin linux-6.1.y

git fetch --shallow-exclude=v6.0 origin

现在检出您感兴趣的代码。如果您刚刚执行了初始克隆,您将能够检出一个新的主线代码库,这对于检查开发人员是否已经修复了问题非常理想

git checkout --detach origin/master

如果您加深了克隆,则可以指定您加深到的版本(上面的 v6.0)而不是 origin/master;后面的版本(如 v6.1)和预发布版本(如 v6.2-rc1)也可以正常工作。如果按所述添加了适当的稳定/长期 branch,则稳定或长期版本(如 v6.1.5)的工作方式相同。

[详情]

如果您想应用内核补丁,请立即执行。通常这样的命令可以解决问题

patch -p1 < ../proposed-fix.patch

是否实际需要 -p1 取决于补丁的创建方式;如果它不适用,请尝试不使用它。

如果您使用 git 克隆了源码,并且出现任何问题,请运行 git reset --hard 以撤消对源码的任何更改。

[详情]

如果您已修补了内核,或者已经安装了相同版本的内核,最好为要构建的内核添加一个唯一的标签

echo "-proposed_fix" > localversion

稍后在您的内核下运行 uname -r 将打印类似 “6.1-rc4-proposed_fix” 的内容。

[详情]

基于现有配置为您的内核创建构建配置。

如果您已经自己准备了这样的 “.config” 文件,请将其复制到 ~/linux/ 并运行 make olddefconfig。

如果您的发行版或其他人已经根据您或您的硬件的需求定制了您正在运行的内核,请使用相同的命令:然后 make target “olddefconfig” 将尝试使用该内核的 .config 作为 base。

对于其他人来说,使用此 make target 也可以,但您通常可以通过使用此命令来节省大量时间

yes "" | make localmodconfig

这将尝试选择您发行版的内核作为 base,然后为您的设置显然多余的任何功能禁用模块。这将大大减少编译时间,尤其是当您运行来自商品 Linux 发行版的通用内核时。

有一个问题:“localmodconfig” 可能会禁用自您启动 Linux 以来未使用的内核功能——例如,当前断开连接的外围设备的驱动程序或尚未使用的虚拟化软件。您可以使用参考部分概述的技巧来减少或几乎消除这种风险;但是,当构建仅用于快速测试目的的内核时,缺少此类功能通常可以忽略不计。但是,在使用使用此 make target 构建的内核时,您应该牢记这一方面,因为它可能是您偶尔使用的某些功能停止工作的原因。

[详情]

检查您是否可能想要或必须调整一些内核配置选项

评估您希望如何处理调试符号。如果以后可能需要解码堆栈跟踪(例如在 “panic”、“Oops”、“warning” 或 “BUG” 中找到的堆栈跟踪),请启用它们;另一方面,如果您存储空间不足或更喜欢较小的内核二进制文件,请禁用它们。有关如何执行这两种操作的详细信息,请参阅参考部分。如果两者都不适用,那么简单地不去管它可能就可以了。[详情]

您是否正在运行 Debian?然后通过执行参考部分中解释的其他调整来避免已知问题。[详情]。

如果您想影响配置的其他方面,请立即使用 “menuconfig” 或 “xconfig” 之类的 make target 来进行操作。[详情]。

构建内核的镜像和模块

make -j $(nproc --all)

如果您希望将内核打包为 deb、rpm 或 tar 文件,请参阅参考部分中的替代方案。

[详情]

现在安装您的内核

command -v installkernel && sudo make modules_install install

通常,您之后要做的就是 reboot,因为许多商品 Linux 发行版会在您的引导加载程序的配置中创建一个 initramfs(也称为 initrd)和内核的条目;但是在某些发行版上,您必须手动执行这两个步骤,原因参考部分解释了。

在少数发行版(如 Arch Linux 及其衍生产品)上,上面的命令根本不起作用;在这种情况下,您必须手动安装内核,如参考部分所述。

如果您正在运行不可变的 Linux 发行版,请查看其文档和网络,以了解如何在其中安装您自己的内核。

[详情]

稍后要构建另一个内核,您需要类似的步骤,但有时需要略有不同的命令。

首先,切换回源码树

cd ~/linux/

如果您想构建来自您尚未使用的稳定/长期系列的某个版本(例如 6.2.y),请告诉 git 跟踪它

git remote set-branches --add origin linux-6.2.y

现在获取最新的上游更改;您再次需要指定您关心的最早版本,因为 git 否则可能会检索整个提交历史

git fetch --shallow-exclude=v6.0 origin

现在切换到您感兴趣的版本——但请注意,此处使用的命令将丢弃您执行的任何修改,因为它们会与您要检出的源码冲突

git checkout --force --detach origin/master

此时,您可能想再次修补源码或设置/修改构建标签,如前所述。之后,使用 olddefconfig 将构建配置调整为新的代码库,这将使用您之前为下一个内核准备的 localmodconfig (~/linux/.config) 调整配置文件

# reminder: if you want to apply patches, do it at this point

# reminder: you might want to update your build tag at this point

make olddefconfig

现在构建您的内核

make -j $(nproc --all)

之后,如上所述安装内核

command -v installkernel && sudo make modules_install install

[详情]

您的内核稍后很容易删除,因为它的各个部分仅存储在两个位置,并且可以通过内核的版本名称清楚地识别出来。只需确保不要删除您正在运行的内核,因为这可能会导致您的系统无法启动。

首先删除包含内核模块的目录,该目录以其版本名称命名——在以下示例中为 “6.0.1-foobar”

sudo rm -rf /lib/modules/6.0.1-foobar

现在尝试以下命令,该命令将在某些发行版上删除所有其他已安装的内核文件,同时从引导加载程序配置中删除内核的条目

command -v kernel-install && sudo kernel-install -v remove 6.0.1-foobar

如果该命令没有任何输出或失败,请参阅参考部分;如果 /boot/ 中仍然存在任何名为“6.0.1-foobar”的文件,请执行相同的操作。

[详情]

您在遵循上述任何步骤时是否遇到问题,而以下参考部分未清除这些问题?或者您是否有任何想法可以改进文本?然后请花一点时间,并通过电子邮件告知本文档的维护者(Thorsten Leemhuis ),理想情况下,同时抄送 Linux 文档邮件列表(linux-doc@vger.kernel.org)。这种反馈对于进一步改进本文档至关重要,这符合每个人的利益,因为它将使更多人能够掌握此处描述的任务。