背景

已经通过独立实验确认:

Panel power cycle delay = 500 ms

对于目标机器的内置 eDP 面板过短。

实验结果:

0.5 秒 → 故障
1 秒   → 故障
2 秒   → 稳定
3 秒   → 稳定

因此决定修改 Linux i915 源码。


一、源码位置

相关实现位于:

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 =
        pps_units_to_msecs(final->power_cycle);

intel_dp->pps.panel_power_cycle_delay =
        max(intel_dp->pps.panel_power_cycle_delay, 2000);

实际也可以写成单行:

intel_dp->pps.panel_power_cycle_delay = max(intel_dp->pps.panel_power_cycle_delay, 2000);

二、为什么使用 max()

这个修改不是:

强制所有机器使用 2000 ms

而是:

最低不得低于 2000 ms

逻辑相当于:

firmware = 500
→ 2000

firmware = 1000
→ 2000

firmware = 2500
→ 2500

这样比直接:

panel_power_cycle_delay = 2000;

更合理。


三、为什么不修改其他 PPS 参数

原参数例如:

Panel power up delay: 200
Panel power down delay: 60
Panel power cycle delay: 500
Backlight on delay: 1
Backlight off delay: 200

实验只证明:

完整 OFF → ON 间隔

与故障高度相关。

没有证据表明:

power_up
power_down
backlight_on
backlight_off

存在问题。

因此遵循最小修改原则,只改变:

panel_power_cycle_delay

四、内核模块必须精确匹配当前内核

例如某次使用:

Linux 7.1.8-arch1-3

自定义模块的:

vermagic

也必须是:

7.1.8-arch1-3 SMP preempt mod_unload

不能拿旧模块直接加载到:

7.1.9-arch1-2

甚至不能假设同一个主版本的小更新也兼容。


五、Arch localversion 很重要

Arch 内核源码不仅包含:

VERSION
PATCHLEVEL
SUBLEVEL

还会使用:

localversion.10-pkgrel
localversion.20-pkgname

例如:

7.1.8-arch1-3

中的:

-arch1-3

必须正确生成。

否则编译出的模块可能出现:

vermagic mismatch

六、使用官方 Module.symvers

单独编译外部或局部模块时,一个关键文件是:

Module.symvers

应优先使用已安装、完全对应目标内核的:

/usr/lib/modules/<kernel-release>/build/Module.symvers

而不是重新生成一套不匹配的符号版本信息。


七、只编译 i915

无需编译整颗 Linux kernel。

准备完成后可以:

make -j"$(nproc)" \
    M=drivers/gpu/drm/i915 \
    modules

最终产生:

drivers/gpu/drm/i915/i915.ko

同时可能产生:

kvmgt.ko

等同目录模块。


八、BTF warning

编译过程中可能出现:

Skipping BTF generation for i915.ko
due to unavailability of vmlinux

对于这种局部模块构建,它不代表编译失败。

只要最终:

i915.ko

成功生成即可。


九、验证 vermagic

例如:

modinfo drivers/gpu/drm/i915/i915.ko |
    grep '^vermagic:'

必须与:

modinfo -k <kernel-release> i915 |
    grep '^vermagic:'

完全一致。


十、安装到 updates/

不覆盖 Arch 官方模块。

官方模块继续保留:

/usr/lib/modules/<kernel-release>/kernel/drivers/gpu/drm/i915/i915.ko.zst

自定义模块安装:

/usr/lib/modules/<kernel-release>/updates/i915.ko.zst

例如:

sudo install -Dm644 \
    /tmp/i915-custom.ko.zst \
    /usr/lib/modules/<kernel-release>/updates/i915.ko.zst

sudo depmod -a <kernel-release>

十一、为什么使用 updates/

kmod 默认会优先解析:

updates/

中的模块。

因此:

modinfo -k <kernel-release> -n i915

应返回:

/lib/modules/<kernel-release>/updates/i915.ko.zst

而官方文件仍然存在。

这样回退非常简单:

sudo rm \
    /usr/lib/modules/<kernel-release>/updates/i915.ko.zst

sudo depmod -a <kernel-release>

之后:

modinfo -k <kernel-release> -n i915

即可重新解析到官方版本。


十二、Late KMS 的好处

由于 i915 没有放入 initramfs:

NO I915 IN INITRAMFS

所以修改 /usr/lib/modules/.../updates/ 后不需要为了 i915 重新生成 initramfs。

如果未来改为 Early KMS,则需要重新评估:

mkinitcpio

流程。

Leave a Reply

Your email address will not be published. Required fields are marked *