内核/Arch 构建系统
Arch 构建系统 可以用于基于官方 linux 软件包构建自定义内核。这种编译方法可以自动化整个过程,并且基于一个经过充分测试的软件包。你可以编辑 PKGBUILD 以使用自定义内核配置或添加额外的补丁。
获取准备材料
由于你将使用 makepkg,首先请遵循其中概述的最佳实践。例如,你不能以 root 用户身份运行 makepkg。因此,首先在你的用户主目录中创建一个 build
目录。
$ mkdir ~/build/ $ cd ~/build/
安装 devtools 和 base-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
数组中。避免创建文档
大部分耗时的编译工作都用于创建文档。为了避免创建文档
- 在
build()
中移除make htmldocs
- 在
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 ...
/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”)。
更新
假设某人有一个想要更新的 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-arch1
和 Linux 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