背景
系统原本运行:
linux 7.1.8.arch1-3
并安装了针对:
7.1.8-arch1-3
编译的自定义 i915。
运行状态:
Panel power cycle delay: 2000
随后系统更新提供:
linux
7.1.8.arch1-3
→
7.1.9.arch1-2
以及:
linux-headers
7.1.8.arch1-3
→
7.1.9.arch1-2
这意味着旧模块不能继续使用。
一、为什么考虑 LTS
Arch 普通:
linux
更新频率较高。
而这种机器每次内核 release 改变后,都需要重新编译:
i915.ko
因此长期维护成本较高。
于是改用:
linux-lts
作为唯一主力内核。
需要注意:
LTS 并不意味着永远不用重新编译模块。
只要:
uname -r
发生变化,自定义 i915 原则上仍应重新编译。
但 LTS 的主线变化更保守,更适合作为长期维护基础。
二、安装 LTS
完整升级时安装:
sudo pacman -Syu linux-lts linux-lts-headers
当时实际得到:
linux-lts 6.18.45-2
linux-lts-headers 6.18.45-2
运行 release:
6.18.45-2-lts
三、升级后不要立即重启
这是整个维护流程中最重要的规则:
内核升级完成后,在新自定义 i915 准备完成之前不要重启。
此时:
磁盘上 = 新内核
内存中 = 旧内核
旧内核已经加载的自定义 i915 仍然正常工作。
这为编译新模块提供了一个安全窗口。
四、获取精确 Arch linux-lts 源码
使用 Arch 官方 packaging repository:
archlinux/packaging/packages/linux-lts
确认 tag:
6.18.45-2
对应:
pkgver=6.18.45
pkgrel=2
Git tag 为 annotated tag,因此:
tag object
→
实际 commit
属于正常现象。
五、PKGBUILD 中的 Arch 补丁
对应版本包含几个 Arch patch,例如:
0001-add-sysctl-to-allow-disabling-unprivileged-CLONE_NEW.patch
0002-drm-amdgpu-avoid-memory-allocation-in-the-critical-c.patch
0003-drm-amdgpu-use-GFP_ATOMIC-instead-of-NOWAIT-in-the-c.patch
这些 patch 与 i915 无直接关系,但仍应使用 Arch 的真实 package source tree,而不是随便下载 vanilla kernel 后假设二者完全相同。
六、PGP 验证
执行:
makepkg --nobuild --nodeps
首次遇到:
unknown public key 38DBBDC86092693E
通过 kernel.org 的 WKD 获取发布者公钥:
gpg --locate-keys gregkh@kernel.org
随后核对 fingerprint,并重新运行。
这一次:
linux-6.18.45.tar ... Passed
源码签名验证成功。
七、Rust build dependencies
完整 PKGBUILD 需要:
rust-bindgen
rust-src
由于目标只是单独构建 C 实现的 i915,没有必要为了这个目的安装完整 Rust 内核构建环境。
因此使用:
makepkg --nobuild --nodeps
准备源码。
olddefconfig 会使部分 Rust 相关选项发生变化,例如:
CONFIG_RUST
CONFIG_RUST_FW_LOADER_ABSTRACTIONS
CONFIG_ANDROID_BINDER_IPC_RUST
但关键模块配置仍一致:
CONFIG_DRM_I915=m
CONFIG_MODULE_SIG=y
CONFIG_MODULE_COMPRESS=y
CONFIG_MODULE_COMPRESS_ZSTD=y
八、确认 kernelrelease
Arch LTS 使用:
localversion.10-pkgrel
-2
以及:
localversion.20-pkgname
-lts
最终:
make -s kernelrelease
必须得到:
6.18.45-2-lts
与:
/usr/lib/modules/6.18.45-2-lts/build/include/config/kernel.release
完全一致。
九、重新应用 2000 ms patch
在:
drivers/gpu/drm/i915/display/intel_pps.c
找到:
intel_dp->pps.panel_power_cycle_delay =
pps_units_to_msecs(final->power_cycle);
增加:
intel_dp->pps.panel_power_cycle_delay =
max(intel_dp->pps.panel_power_cycle_delay, 2000);
使用 diff 确认整个源码只增加这一行。
十、构建 LTS i915
复制正式:
Module.symvers
然后:
make modules_prepare
make -j"$(nproc)" \
M=drivers/gpu/drm/i915 \
modules
成功得到:
i915.ko
大小约:
176 MiB
未压缩。
十一、验证 vermagic
自定义模块:
vermagic:
6.18.45-2-lts SMP preempt mod_unload
官方模块:
vermagic:
6.18.45-2-lts SMP preempt mod_unload
完全一致。
十二、模块签名
Arch 官方模块带:
Build time autogenerated kernel key
而自行构建模块没有官方 signer。
但内核配置:
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_ALL=y
# CONFIG_MODULE_SIG_FORCE is not set
同时 kernel command line 也没有:
module.sig_enforce=1
因此未签名自定义模块可以正常加载。
十三、压缩和安装
使用 zstd:
zstd -T0 -19 i915.ko \
-o /tmp/i915-custom.ko.zst
安装:
/usr/lib/modules/6.18.45-2-lts/updates/i915.ko.zst
然后:
sudo depmod -a 6.18.45-2-lts
验证:
modinfo -k 6.18.45-2-lts -n i915
得到:
/lib/modules/6.18.45-2-lts/updates/i915.ko.zst
modprobe --show-depends 也明确选择:
updates/i915.ko.zst
十四、官方模块继续保留
原始 Arch 模块仍位于:
/usr/lib/modules/6.18.45-2-lts/kernel/drivers/gpu/drm/i915/i915.ko.zst
因此没有进行破坏性覆盖。
需要回退时只需要删除:
updates/i915.ko.zst
然后:
sudo depmod -a 6.18.45-2-lts
即可恢复官方模块。
十五、GRUB 最初没有 LTS 项
安装 LTS 后发现:
/boot/vmlinuz-linux-lts
/boot/initramfs-linux-lts.img
已经存在。
但旧:
grub.cfg
是在安装 LTS 之前生成的,因此没有 LTS 启动项。
重新:
sudo grub-mkconfig -o /boot/grub/grub.cfg
后,默认:
Arch Linux
已经指向:
/boot/vmlinuz-linux-lts
/boot/initramfs-linux-lts.img
十六、第一次实际启动验证
重启后:
uname -r
得到:
6.18.45-2-lts
检查:
modinfo -n i915
得到:
/lib/modules/6.18.45-2-lts/updates/i915.ko.zst
最后读取:
i915_panel_timings
结果:
Panel power up delay: 200
Panel power down delay: 60
Panel power cycle delay: 2000
Backlight on delay: 1
Backlight off delay: 200
说明:
LTS kernel
+
custom i915
+
2000 ms workaround
全部真正进入运行状态。
十七、删除普通 Arch 内核
确认 LTS 稳定后,希望只保留:
linux-lts
linux-lts-headers
最初:
sudo pacman -R linux linux-headers
失败:
removing linux breaks dependency 'linux' required by tp_smapi
十八、发现 tp_smapi 遗留包
检查:
tp_smapi
说明:
Modules for ThinkPad's SMAPI functionality
其依赖:
Depends On: linux
且:
Required By: None
当前机器也没有加载:
tp_smapi
thinkpad_ec
hdaps
因此它属于完全不适用于当前硬件的遗留包。
正常删除:
sudo pacman -R tp_smapi linux linux-headers
没有使用:
-Rdd
这种绕过依赖数据库的方式。
十九、最终状态
完成后:
linux-lts 6.18.45-2
linux-lts-headers 6.18.45-2
普通:
linux
linux-headers
已经移除。
/boot 只剩:
vmlinuz-linux-lts
initramfs-linux-lts.img
GRUB 也只引用:
linux-lts
运行中的自定义驱动仍为:
/lib/modules/6.18.45-2-lts/updates/i915.ko.zst
并保持:
Panel power cycle delay: 2000
系统中历史遗留的:
/usr/lib/modules/5.x
/usr/lib/modules/6.x
/usr/lib/modules/7.x
旧目录暂时没有处理。
它们不参与当前启动,可以以后单独审计。
二十、以后升级 LTS 的标准流程
对于存在自定义 i915 的系统,以后不能简单:
pacman -Syu
reboot
推荐固定流程:
1. pacman -Syu
2. 不重启
3. 确认新的 linux-lts release
4. 获取精确 Arch linux-lts source
5. 应用 2000 ms PPS patch
6. 使用对应 Module.symvers 编译 i915
7. 检查 vermagic
8. 安装到新内核 updates/
9. depmod
10. modinfo -k <new-release> -n i915
11. 确认 GRUB
12. 最后 reboot
13. 验证 uname -r
14. 验证 modinfo -n i915
15. 验证 Panel power cycle delay = 2000
这就把一次临时 workaround,转化成了可以长期维护的内核升级流程。