内核/Arch 构建系统

来自 ArchWiki

Arch 构建系统 可以用于基于官方 linux 软件包构建自定义内核。这种编译方法可以自动化整个过程,并且基于一个经过充分测试的软件包。你可以编辑 PKGBUILD 以使用自定义内核配置或添加额外的补丁

获取准备材料

由于你将使用 makepkg,首先请遵循其中概述的最佳实践。例如,你不能以 root 用户身份运行 makepkg。因此,首先在你的用户主目录中创建一个 build 目录。

$ mkdir ~/build/
$ cd ~/build/

安装 devtoolsbase-devel 软件包。

你需要一个干净的内核来开始你的自定义。通过运行以下命令,获取 PKGBUILD 源码 和其他一些文件到你的 build 目录中

$ pkgctl repo clone --protocol=https linux

此时,目录树看起来像这样(可能还有其他一些文件)

~/build/linux/-+
               +--config
               \__PKGBUILD

然后,从各自的来源获取你需要的任何其他文件(例如,自定义配置文件、补丁等)。

修改 PKGBUILD

编辑 PKGBUILD 并查找 pkgbase 参数。将其更改为你的自定义软件包名称,例如

PKGBUILD
pkgbase=linux-custom
警告: 不要linux 添加到 provides 数组中。你的自定义内核将与针对该内核构建的二进制模块不兼容,因此它无法满足该依赖关系。同样,由于类似的原因,不要将 linux-headers 添加到头文件软件包的 provides 数组中。

避免创建文档

大部分耗时的编译工作都用于创建文档。为了避免创建文档

  1. build() 中移除 make htmldocs
  2. pkgname 中移除 "$pkgbase-docs"

更改 prepare()

prepare() 函数中,你可以应用所需的内核补丁或更改内核构建配置。自 2018-08-01 起,PKGBUILD 会自动应用 source 中的所有 *.patch 文件。

如果你需要更改一些配置选项,你可以编辑 source 中的 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
...
警告: systemd 对于通用用途、特定用例(例如,UEFI)和特定的 systemd 功能(例如,bootchart)有许多内核配置要求。未能满足这些要求可能会导致你的系统性能下降或无法使用。所需和推荐的内核 CONFIG 列表可以在 /usr/share/doc/systemd/README 中找到。在编译之前检查它们。这些要求也会随时间变化。由于 Arch 假设你正在使用官方内核,因此不会发布有关这些更改的公告。在安装新版本的 systemd 之前,请查看版本发行说明,以确保你当前的自定义内核满足任何新的 systemd 要求。

生成新的校验和

#更改 prepare() 建议可能修改 $_srcname/.config。由于此路径不是下载软件包文件的最终位置,因此 makepkg 未检查其校验和(makepkg 实际上检查了 $_srcname/../../config)。

如果你在运行 makepkg 之前用另一个 config 替换了下载的 config,请安装 pacman-contrib 软件包,并通过运行以下命令生成新的校验和

$ updpkgsums

编译

现在你可以使用常用命令 makepkg 继续编译你的内核。

如果你选择了交互式程序来配置内核参数(如 menuconfig),则需要在编译期间保持在场。

$ makepkg -s

-s 参数将下载最近的内核使用的任何其他依赖项,例如 xml 和 docs。

注意
  • 内核源码是 PGP 签名的,并且 makepkg 将尝试验证它们。有关详细信息,请参阅 makepkg#签名检查
  • 根据硬件性能,编译可能需要几个小时才能完成。同时运行编译作业可以显着减少多核系统上的编译时间。
  • 使用 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”)。

更新

此文章或章节已过时。

原因: linux PKGBUILD 不再使用 git [1][2] 来获取其源代码。(在 Talk:Kernel/Arch build system 中讨论)

假设某人有一个想要更新的 arch 内核源码,一种方法是使用 https://github.com/archlinux/linux。在下文中,假设顶级内核源码目录位于 ~/build/linux/

通常,arch 使用两个本地 git 仓库设置 arch 内核源码。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-arch1Linux 5.2.7 之间的一些特定 archlinux 补丁。

最新的 PKGBUILD 以及 archlinux 内核配置文件可以使用包目录中的 git 拉取。

$ cd ~/build/linux/
$ git pull

现在你应该将位于 ~/build/linux/linux/* 中的文件合并~/build/linux/ 中。合并也可以手动完成,或者使用特定工具完成。查看 #更改 prepare(),并手动运行 PKGBUILD::prepare() 的大部分(如果不是全部)shell 命令。

此时,makepkg --verifysource 应该成功。在 #编译 时,请确保还向 makepkg 命令添加 --noextract 选项,因为它应该能够构建软件包,就像源码被 makepkg --nobuild 提取一样。然后你回到 #安装

清理

合并后,可能需要删除 ~/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

参见