Kernel/Arch 构建系统
使用 Arch 构建系统 可以基于官方 linux 包来构建自定义内核。这种编译方法可以自动化整个过程,并且基于一个经过充分测试的包。您可以编辑 PKGBUILD 来使用自定义内核配置或添加额外的 补丁。
准备工作
由于您将使用 makepkg,请先遵循其中概述的最佳实践。例如,您不能以 root 用户 的身份运行 makepkg。因此,请先在您的用户主目录中创建一个 build 目录。
$ mkdir ~/build/ $ cd ~/build/
安装 devtools 和 base-devel 包。
您需要一个干净的内核作为自定义的基础。通过运行以下命令,将 PKGBUILD 源 和其他一些文件检索到您的构建目录中:
$ pkgctl repo clone --protocol=https linux
此时,目录结构看起来是这样的(可能还有其他一些文件)
~/build/linux/-+
+--config
\__PKGBUILD
然后,从相应来源获取您需要的任何其他文件(例如,自定义配置文件、补丁等)。
修改 PKGBUILD
编辑 PKGBUILD 并找到 pkgbase 参数。将其更改为您的自定义包名,例如:
PKGBUILD
pkgbase=linux-custom
linux 添加到 provides 数组中。您的自定义内核将无法与针对该内核构建的二进制模块兼容,因此无法满足该依赖。同样,出于类似原因,不要将 linux-headers 添加到头文件包的 provides 数组中。避免生成文档
漫长的 编译 过程中有很大一部分是用于生成文档。为了避免生成文档:
- 在
build()中移除make htmldocs - 在
pkgname中移除"$pkgbase-docs"
修改 prepare()
在 prepare() 函数中,您可以 应用所需的内核补丁 或更改内核的构建配置。自 2018-08-01 起,PKGBUILD 会自动应用源中的所有 *.patch 文件。
如果您需要更改一些配置选项,可以编辑源中的 config 文件。
或者,您可以使用 GUI 工具来调整选项。在 PKGBUILD 的 prepare() 函数中注释掉 make olddefconfig,并添加您喜欢的工具(运行 make help 列出所有可能的配置目标)。
PKGBUILD
... msg2 "Setting config..." cp ../config .config #make olddefconfig make nconfig # new CLI menu for configuration #make menuconfig # CLI menu for configuration #make xconfig # X-based configuration #make oldconfig # using old config from previous kernel version # ... or manually edit .config make prepare ...
/usr/share/doc/systemd/README 中找到。在编译之前进行检查。这些要求也会随时间而变化。由于 Arch 假定您使用官方内核,因此不会发布这些变化的通知。在安装新版本的 systemd 之前,请检查版本发布说明,以确保您当前的自定义内核满足任何新的 systemd 要求。生成新的校验和
#Changing prepare() 建议对 $_srcname/.config 进行可能的修改。由于下载的文件并非在此路径下结束,因此其校验和未被 makepkg 检查(实际检查的是 $_srcname/../../config)。
如果您在运行 makepkg 之前用另一个文件替换了下载的 config,请安装 pacman-contrib 包,并通过运行以下命令生成新的校验和:
$ updpkgsums
编译
您现在可以继续通过 usual command makepkg 来编译您的内核。
如果您选择了交互式程序来配置内核参数(如 menuconfig),那么在编译过程中您需要待在电脑旁。
$ makepkg -s
-s 参数将下载最近内核使用的任何额外依赖项,如 xml 和 docs。
- 内核源代码是 PGP 签名的,makepkg 会尝试验证它们。有关详细信息,请参阅 makepkg#Signature checking。
- 编译可能需要长达数小时,具体取决于硬件性能。在多核系统上,同时运行编译任务可以显著缩短编译时间。
- 使用
time命令运行上述makepkg会很有信息量,可以了解系统花费了多长时间来完成编译。
安装
编译步骤会在 ~/build/linux 文件夹中留下两个包,一个用于内核,一个用于内核头文件。它们可能名称如下:
linux-custom-5.8.12-x86_64.pkg.tar.zst linux-custom-headers-5.8.12-x86_64.pkg.tar.zst
最佳实践是同时 安装这两个包,因为它们可能都需要(例如 DKMS)。
# pacman -U linux-custom-headers-5.8.12-x86_64.pkg.tar.zst linux-custom-5.8.12-x86_64.pkg.tar.zst
(替换文件夹中实际的文件名)
引导加载程序
如果您修改了 pkgbase 以便将新内核与默认内核并排安装,那么您需要更新您的 引导加载程序 配置文件,并为您的自定义内核和相关的 initramfs 镜像添加新的条目('default' 和 'fallback')。
更新
假设有一个 arch 内核源需要更新,其中一种方法是使用 https://github.com/archlinux/linux。下面将顶部内核源目录假定为 ~/build/linux/。
通常,arch 会设置一个 arch 内核源,其中包含两个本地 git 仓库。archlinux-linux/ 是一个指向 https://github.com/archlinux/linux.git 的本地裸 git 仓库。另一个位于 src/archlinux-linux/,从裸仓库拉取。可能的本地补丁和构建预期在 src/archlinux-linux/ 中。
在这个例子中,本地安装的裸 git 仓库源 archlinux-linux/ 的 HEAD 最初指向
$ cd ~/build/linux/archlinux-linux/ $ git log --oneline --max-count 1 HEAD
4010b622f1d2 Merge branch 'dax-fix-5.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm
它介于 v5.2.5-arch1 和 v5.2.6-arch1 之间。
$ git fetch --verbose
可以看到它获取了 v5.2.7-arch1,这是最新的 archlinux 标签,因为它会打印出新获取的标签。如果没有获取新标签,则没有更新的 archlinux 源可用。
现在可以更新实际进行构建的源了。
$ cd ~/build/linux/src/archlinux-linux/ $ git checkout master $ git pull $ git fetch --tags --verbose $ git branch --verbose 5.2.7-arch1 v5.2.7-arch1 $ git checkout 5.2.7-arch1
您可以使用类似这样的命令来验证您是否跟上了进度:
$ git log --oneline 5.2.7-arch1 --max-count=7
13193bfc03d4 Arch Linux kernel v5.2.7-arch1 9475c6772d05 netfilter: nf_tabf676926c7f60les: fix module autoload for redir 498d650048f6 iwlwifi: Add support for SAR South Korea limitation bb7293abdbc7 iwlwifi: mvm: disable TX-AMSDU on older NICs f676926c7f60 ZEN: Add CONFIG for unprivileged_userns_clone 5e4e503f4f28 add sysctl to disallow unprivileged CLONE_NEWUSER by default 5697a9d3d55f Linux 5.2.7
这显示了 Arch Linux kernel v5.2.7-arch1 和 Linux 5.2.7 之间的一些特定 archlinux 补丁。
可以通过在包目录中使用 git 来拉取最新的 PKGBUILD 以及 archlinux 内核配置文件:
$ cd ~/build/linux/ $ git pull
现在您应该 合并文件,这些文件位于 ~/build/linux/linux/* 中,合并到 ~/build/linux/。合并也可以手动进行,或使用 特定的实用程序。回顾 #Changing prepare(),并手动执行 PKGBUILD::prepare() 中几乎所有 shell 命令。
此时,makepkg --verifysource 应该会成功。在 #Compiling 时,请确保在 makepkg 命令中也添加 --noextract 选项,因为它可以像 makepkg --nobuild 提取源一样构建包。然后您就可以回到 #Installing 了。
清理
合并后,您可能需要删除 ~/build/linux/linux/。此外,如果以这种方式进行更多最近的更新,~/build/linux/src/archlinux 会以 5.2.7-arch1 的形式累积分支。可以使用以下命令删除它们:
$ cd ~/build/linux/src/archlinux $ git branch --delete --force --verbose 5.2.7-arch1