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

生成新的校验和

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

如果你在运行 makepkg 之前用另一个文件替换了下载的 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 构建系统 中讨论)

假设有人有一个他们想要更新的 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

另请参阅