Kernel/Traditional compilation
本文介绍了如何从 kernel.org 源码构建自定义内核。这种编译内核的方法是所有发行版通用的传统方法。根据您的背景,它可能比使用 Kernel/Arch 构建系统 更为复杂。请考虑 Arch 构建系统 工具的开发和维护是为了使可重复的编译任务高效且安全。
准备工作
内核准备工作没有必要(也不建议)使用 root 账户或 root 权限(即通过 sudo)。
安装核心软件包
安装 base-devel 元软件包,它会拉取必要的软件包,例如 make 和 gcc。还建议安装以下软件包,它们在默认 Arch 内核 PKGBUILD 中列出:xmlto、kmod、inetutils、bc、libelf、git、cpio、perl、tar、xz。
创建内核编译目录
建议为您的内核创建一个单独的构建目录。在本例中,目录 kernelbuild
将在 home
目录中创建
$ mkdir ~/kernelbuild
下载内核源码
/usr/share/doc/systemd/README
。从 https://linuxkernel.org.cn 下载内核源码。这应该是您选择的内核的 tarball (.tar.xz) 文件。
可以通过在浏览器中右键单击 tar.xz
链接并选择 Save Link As...
来下载,或者通过使用 HTTP、TFTP、Rsync 或 Git 的其他图形或命令行工具来下载。
- 最好验证任何下载的内核 tarball 的 PGP 签名。这可以确保其合法性,并有助于构建信任网络。请参见 kernel.org/signature。
- 对于某些版本(例如
-rc
版本),下载的存档和生成的目录将不严格遵循此页面示例中使用的A.B.C
命名,请根据您的需要进行调整。
在以下命令行命令中,wget 已安装,并在 ~/kernelbuild
目录中使用以获取内核 A.B.C
$ cd ~/kernelbuild $ wget https://cdn.kernel.org/pub/linux/kernel/vA.x/linux-A.B.C.tar.xz
您还应该在信任下载之前验证下载的正确性。首先获取签名,然后使用签名获取签名密钥的指纹,然后使用指纹获取实际的签名密钥
$ wget https://cdn.kernel.org/pub/linux/kernel/vA.x/linux-A.B.C.tar.sign $ gpg --list-packets linux-A.B.C.tar.sign | grep -i keyid | awk '{print $NF}' | xargs gpg --recv-keys
请注意,签名是为 tar 存档(即扩展名 .tar
)生成的,而不是您下载的压缩 .tar.xz
文件。您需要解压缩后者,而无需解压缩它。验证您是否已安装 xz,然后您可以像这样继续
$ unxz linux-A.B.C.tar.xz $ gpg --verify linux-A.B.C.tar.sign linux-A.B.C.tar
如果结果输出不包含字符串 "Good signature",请勿继续。
如果在构建目录中未使用 wget
,则需要将 tarball 移动到其中,例如
$ mv /path/to/linux-A.B.C.tar.xz ~/kernelbuild/
半官方内核镜像
kernel.org Git 仓库的一些半官方镜像由其各自的维护者提供。这些镜像的克隆速度往往比 kernel.org 快。
- 主线分支镜像在 Linus Torvalds 的 GitHub 帐户上:https://github.com/torvalds/linux.git。
- 稳定分支镜像在 Greg Kroah-Hartman 的 GitHub 帐户上:https://github.com/gregkh/linux。 [1]
解包内核源码
在构建目录中,解包内核 tarball
$ tar -xvf linux-A.B.C.tar
为了绝对确保不会发生权限错误,需要运行 chown 以将文件夹的所有权转移给当前用户。
要将文件夹及其中的每个文件的所有权转移给我们的用户,请运行 chown 命令。
$ chown -R $USER:$USER linux-A.B.C
这将把文件夹中每个文件的所有权转移给您,因此您不会遇到任何与权限相关的错误。
为了完成准备工作,请确保内核树绝对干净;不要依赖于解包后源码树是干净的。为此,首先进入新创建的内核源码目录,然后运行 make mrproper
命令
$ cd linux-A.B.C $ make mrproper
内核配置
这是自定义默认内核以反映您计算机的精确规格的最关键步骤。内核配置在其 .config
文件中设置,其中包括 内核模块 的使用。通过正确设置 .config
中的选项,您的内核和计算机将以最高效的方式运行。
您可以执行以下两件事的组合
- 使用来自官方内核的默认 Arch 设置(推荐)
- 手动配置内核选项(可选,高级且不推荐)
默认 Arch 配置
此方法将使用默认 Arch 内核设置为自定义内核创建 .config
文件。如果正在运行 stock Arch 内核,则可以在自定义内核源码目录中使用以下命令
$ zcat /proc/config.gz > .config
否则,可以在 官方 Arch Linux 内核 软件包中在线找到默认配置。
- 如果您正在升级内核,则某些选项可能已更改或已删除。在这种情况下,当在 #编译 下运行
make
时,系统会要求您为版本之间已更改的每个配置选项提供答案。要接受默认值而不提示,请运行make olddefconfig
。 - modprobed-db 可用于从默认 Arch
.config
中剥离不需要的模块。一旦获得 正确填充的数据库,运行make LSMOD=$HOME/.config/modprobed.db localmodconfig
以删除modprobed.db
数据库中不存在的所有模块。
.config
文件编译内核,请不要忘记在新 .config
中或使用 #高级配置 下列出的用户界面之一,重命名您的内核版本 "CONFIG_LOCALVERSION" 或 General Setup > Local version - append to kernel release 选项。如果您跳过此步骤,则存在错误覆盖现有内核之一的风险。高级配置
有几种工具可用于微调内核配置,这些工具提供了另一种选择,否则您将花费数小时手动配置编译期间可用的每个选项。
y
表示启用,n
表示禁用,m
表示作为内核模块启用(必要时加载)。这些工具是
make menuconfig
:命令行 ncurses 界面,已被nconfig
取代make nconfig
:用于命令行的较新的 ncurses 界面make xconfig
:用户友好的图形界面,需要安装 packagekit-qt5 作为依赖项。这是推荐的方法 - 特别是对于经验不足的用户 - 因为它更容易导航,并且还显示有关每个选项的信息。make gconfig
: 图形化配置,类似于 xconfig,但使用 GTK。这需要 gtk2、 glib2 和 libgladeAUR。
选择的方法应在内核源代码目录内运行,所有方法都将创建一个新的 .config
文件,或者覆盖现有的文件(如果存在)。所有可选配置都将自动启用,但任何较新的配置选项(即使用较旧内核的 .config
)可能不会自动选择。
完成更改后,保存 .config
文件。最好在源代码目录之外制作一个备份副本。您可能需要多次执行此操作,直到获得所有正确的选项。
如果不确定,仅在编译之间更改几个选项。如果您无法启动新构建的内核,请参阅此处列出的必要项目。
从 live media 运行 lspci -k #
会列出正在使用的内核模块的名称。最重要的是,您必须保持 cgroups 支持。这对于 systemd 是必要的。有关更详细的信息,请参阅 Gentoo:Kernel/Gentoo Kernel Configuration Guide 和 Gentoo:Intel#Kernel 或 Gentoo:Ryzen#Kernel,了解 Intel 或 AMD Ryzen 处理器。
编译
arch/x86/Makefile
- 查找您在
Processor type and features > Processor Family
中选择的CONFIG_MK8,CONFIG_MPSC,CONFIG_MCORE2,CONFIG_MATOM,CONFIG_GENERIC_CPU
- 将
call cc-options
标志从-march=native
更改为您在 Processor Family 中选择的标志,例如cflags-$(CONFIG_MK8) += $(call cc-option,-march=native)
。这可能是使用-march=native
进行编译的最佳方式,因为它有效。
编译时间将从短短的十五分钟到超过一个小时不等,具体取决于您的内核配置和处理器能力。一旦为自定义内核设置了 .config
文件,请在源代码目录中运行以下命令进行编译
$ make
-jX
参数一起运行,其中 X
是并行作业的整数数量。通常使用机器中 CPU 核心的数量可以获得最佳结果;例如,对于双核处理器,运行 make -j2
。有关更多信息,请参阅 Makepkg#Improving build times。安装
安装模块
内核编译完成后,必须安装其模块。首先构建模块
$ make modules
然后安装模块。以 root 用户身份或使用 root 权限,运行以下命令执行此操作
# make modules_install
这会将编译后的模块复制到 /lib/modules/A.B.C/
中。这会将各个内核使用的模块分开。
将内核复制到 /boot 目录
bzImage
内核文件。请参阅下文。内核编译过程将生成该内核的压缩 bzImage
(big zImage),如果未生成,您可能需要运行
make bzImage
此文件必须复制到 /boot
目录并在过程中重命名。只要名称以 vmlinuz-
为前缀,您就可以随意命名内核。在下面的示例中,已复制并重命名已安装和编译的 A.B.C 内核为 vmlinuz-linuxAB
# cp -v arch/x86/boot/bzImage /boot/vmlinuz-linuxAB
制作初始 RAM 磁盘
linuxmajor_revisionminor_revision
约定。此约定将使维护多个内核、定期使用 mkinitcpio 和构建第三方模块更加容易。modprobe dm-mod
。如果您不知道制作初始 RAM 磁盘是什么,请参阅 Wikipedia 上的 Initramfs 和 mkinitcpio。
自动预设方法
可以复制和修改现有的 mkinitcpio 预设,以便可以像为官方内核一样生成自定义内核 initramfs 镜像。这在打算重新编译内核(例如,在更新的情况下)时很有用。在下面的示例中,将复制并修改用于 stock Arch 内核的预设文件,以用于上面安装的内核 A.B.C。
首先,复制现有的预设文件,将其重命名为与自定义内核的名称匹配,该名称在复制 bzImage
时指定为 /boot/vmlinuz-
的后缀
# cp /etc/mkinitcpio.d/linux.preset /etc/mkinitcpio.d/linuxAB.preset
其次,编辑该文件并为自定义内核进行修改。请注意(再次),ALL_kver=
参数也与复制 bzImage
时指定的自定义内核的名称匹配
/etc/mkinitcpio.d/linuxAB.preset
... ALL_kver="/boot/vmlinuz-linuxAB" ... default_image="/boot/initramfs-linuxAB.img" ... fallback_image="/boot/initramfs-linuxAB-fallback.img"
最后,以与官方内核相同的方式为自定义内核生成 initramfs 镜像
# mkinitcpio -p linuxAB
手动方法
除了使用预设文件外,mkinitcpio 也可以用于手动生成 initramfs 文件。命令的语法是
# mkinitcpio -k kernel_version -g /boot/initramfs-file_name.img
-k
(--kernel kernel_version
): 指定在生成 initramfs 镜像时要使用的模块。kernel_version
名称将与其模块目录的名称相同,该目录位于/usr/lib/modules/
中(或者,可以使用内核镜像的路径)。-g
(--generate file_name
): 指定要在/boot
目录中生成的 initramfs 文件的名称。同样,建议使用上面提到的命名约定。
例如,上面安装的 A.B.C 自定义内核的命令将是
# mkinitcpio -k A.B.C -g /boot/initramfs-linuxAB.img
复制 System.map
启动 Linux 不需要 System.map
文件。它是一种内核特定构建中函数的“电话簿”列表。System.map
包含内核符号(即函数名称、变量名称等)及其对应地址的列表。此“符号名到地址的映射”被以下项使用
- 一些进程,如 klogd、ksymoops 等。
- 当必须在内核崩溃期间将信息转储到屏幕时(即,类似崩溃发生在哪个函数中的信息),由 OOPS 处理程序使用。
如果您的 /boot
位于支持符号链接的文件系统上(即不是 FAT32),请将 System.map
复制到 /boot
,并将内核名称附加到目标文件。然后创建一个从 /boot/System.map
指向 /boot/System.map-linuxAB
的符号链接
# cp System.map /boot/System.map-linuxAB # ln -sf /boot/System.map-linuxAB /boot/System.map
完成上述所有步骤后,您应该在 /boot
目录中拥有以下 3 个文件和 1 个软符号链接以及任何其他先前存在的文件
- 内核:
vmlinuz-linuxAB
- Initramfs:
initramfs-linuxAB.img
- System Map:
System.map-linuxAB
- System Map 内核符号链接:
System.map
(它符号链接到System.map-linuxAB
)
引导加载程序配置
在引导加载程序的配置文件中为您的新内核添加一个条目。有关可能的引导加载程序、其 wiki 文章和其他信息,请参阅 Arch boot process#Feature comparison。
另请参阅
- https://cateee.net/lkddb/web-lkddb/ 包括内核配置字符串和随附文本的完整列表,按字母顺序排序。