Series: 机械革命无界 15XPro

  • 在机械革命无界 15XPro 暴风雪上运行 Linux

    This entry is part 1 of 4 in the series 机械革命无界 15XPro

    最近把工作电脑换成了机械革命无界 15XPro 暴风雪,在收货后小小折腾了一两天后,终于让他大部分的功能工作正常了。

    键盘背光跟散热风扇的驱动

    可以参考这篇文章中的介绍安装来自德国一家公司维护的驱动。驱动安装好后,还可以安装类似鸡哥控制面板的 TUXEDO 控制面板,切换性能模式跟调整键盘背光 RGB:

    内置屏幕掉帧

    笔记本内置屏幕在 60Hz 时会频繁随机掉帧,这个现象跟 VRR 有关,需要强制启用 VRR。

    除此之外我还遇到了使用 Spectacle 截图时,外置显示器闪烁的问题,需要强制关闭外置显示器的 VRR。

    睡眠(suspend)后被立即唤醒

    当通过睡眠按键(Fn + F1)或者 systemctl suspend 进入睡眠状态时,系统会被立即唤醒,需要第二次尝试才能成功睡眠。

    反复阅读 https://wiki.archlinux.org/title/Power_management 系列文章后,我在 deepseek-r1 的帮助下成功地找出了这个问题的根因。

    TLDR

    创建一个 udev rule,禁用 PS/2 键盘的 Wakeup Trigger。

    # sudoedit /etc/udev/rules.d/99-disable-keyboard-wakeup.rules
    # Disable wakeup for PS/2 keyboard controller
    ACTION=="add", SUBSYSTEM=="serio", KERNEL=="serio0", ATTR{power/wakeup}="disabled"

    然后重载 udev rules:

    sudo udevadm control --reload-rules
    sudo udevadm trigger

    重启系统后验证是否生效:

    $ cat /sys/devices/platform/i8042/serio0/power/wakeup
    disabled

    现在尝试睡眠,就不会被立即唤醒了。

    排查过程

    首先安装 amd-debug-tools,运行 amd-s2idle test ,查看当前系统是否满足 s2idle 的要求:

    $ amd-s2idle test
    💻 AMD Ryzen AI 9 H 365 w/ Radeon 880M (family 1a model 24)
    💻 MECHREVO WUJIE Series (STX\KRK)
    🐧 Arch Linux
    🐧 Kernel 6.12.32-1-lts
    🔋 Battery BAT0 (OEM standard) is operating at 100.00% of design
    ✅ ASPM policy set to 'default'
    ✅ GPIO driver `pinctrl_amd` available
    ✅ PMC driver `amd_pmc` loaded (Program 11 Firmware 93.4.0)
    ✅ USB3 driver `xhci_hcd` bound to 0000:65:00.4, 0000:67:00.0, 0000:67:00.3, 0000:67:00.4
    ✅ USB4 driver `thunderbolt` bound to 0000:67:00.6
    ✅ System is configured for s2idle
    ✅ GPU driver `amdgpu` bound to 0000:65:00.0
    ✅ PC6 and CC6 enabled
    ✅ SMT enabled
    ✅ IOMMU properly configured
    ✅ ACPI FADT supports Low-power S0 idle
    🚦 Logs are provided via dmesg, timestamps may not be accurate over multiple cycles
    ✅ LPS0 _DSM enabled
    ✅ WLAN driver `mt7921e` bound to 0000:62:00.0
    ❌ Kernel is tainted: 12288
    💯 Your system does not meet s2idle prerequisites!
    🗣️ Explanations for your system
    🚦 Kernel is tainted
    A tainted kernel may exhibit unpredictable bugs that are difficult for this script to characterize. If this is intended behavior run the tool with --force. 
    For more information on this failure see:https://gitlab.freedesktop.org/drm/amd/-/issues/3089

    可以看到这里提示我的 kernel 被 tainted 了,这是安装 mechrevo-drivers-dkms 引起的,可以忽略。

    既然系统符合 s2idle 的要求,说明可能是某个设备在唤醒系统,deepseek 给出了接下来的排查思路,启用 PM 日志:

    # Enable verbose PM debugging
    echo 1 | sudo tee /sys/power/pm_print_times<br>echo 1 | sudo tee /sys/power/pm_debug_messages
    # Now try to suspend again
    systemctl suspend
    # Check dmesg after resume
    dmesg | grep -i "wake\|resume\|acpi"

    再次执行 systemctl suspend 复现问题后,可以在 dmesg 中看到下面的日志:

    [ 4636.873132] xhci_hcd 0000:67:00.4: PM: pci_pm_suspend_noirq returned 0 after 42252 usecs  
    [ 4636.873146] thunderbolt 0000:67:00.6: PM: pci_pm_suspend_noirq returned 0 after 42269 usecs  
    [ 4636.873169] pcieport 0000:00:08.3: PM: calling pci_pm_suspend_noirq @ 29723, parent: pci0000:00  
    [ 4636.878632] pcieport 0000:00:02.1: PM: pci_pm_suspend_noirq returned 0 after 10561 usecs  
    [ 4636.878653] pcieport 0000:00:03.2: PM: pci_pm_suspend_noirq returned 0 after 11025 usecs  
    [ 4636.885192] pcieport 0000:00:08.1: PM: pci_pm_suspend_noirq returned 0 after 12279 usecs  
    [ 4636.885300] pcieport 0000:00:08.3: PM: pci_pm_suspend_noirq returned 0 after 12119 usecs  
    [ 4636.885359] PM: noirq suspend of devices complete after 54.690 msecs  
    [ 4636.885376] ACPI: _SB_.PCI0.GPP5: LPI: Constraint not met; min power state:D1 current power state:D0  
    [ 4636.885381] ACPI: _SB_.PCI0.GPP6: LPI: Constraint not met; min power state:D1 current power state:D0  
    [ 4636.885388] ACPI: _SB_.PCI0.GPP4.SDCR: LPI: Constraint not met; min power state:D3hot current power state:D0  
    [ 4636.886012] PM: Triggering wakeup from IRQ 9  
    [ 4636.886504] ACPI: _SB_.PEP_: Successfully transitioned to state screen off  
    [ 4636.887420] ACPI: _SB_.PEP_: Successfully transitioned to state lps0 ms entry  
    [ 4636.887625] ACPI: _SB_.PEP_: Successfully transitioned to state lps0 entry  
    [ 4636.888555] PM: suspend-to-idle  
    [ 4636.888592] ACPI: EC: ACPI EC GPE status set  
    [ 4636.888623] ACPI: PM: Rearming ACPI SCI for wakeup  
    [ 4636.891279] PM: Triggering wakeup from IRQ 1  
    [ 4639.593124] amd_pmc: SMU idlemask s0i3: 0xffff1abd  
    [ 4639.593188] ACPI: PM: Wakeup unrelated to ACPI SCI  
    [ 4639.593189] PM: resume from suspend-to-idle  
    [ 4639.594699] amd_pmc AMDI000A:00: Last suspend didn't reach deepest state  
    [ 4639.595185] ACPI: _SB_.PEP_: Successfully transitioned to state lps0 exit  
    [ 4639.595760] PM: Triggering wakeup from IRQ 9  
    [ 4639.596746] ACPI: _SB_.PEP_: Successfully transitioned to state lps0 ms exit  
    [ 4639.597719] ACPI BIOS Error (bug): Could not resolve symbol [_SB.ACDC.RTAC], AE_NOT_FOUND (20240827/psargs-332)  
    [ 4639.597729] ACPI Error: Aborting method _SB.PEP._DSM due to previous error (AE_NOT_FOUND) (20240827/psparse-529)  
    [ 4639.597737] ACPI: _SB_.PEP_: Failed to transitioned to state screen on

    Deepseek 大胆推断是 IRQ 1 (typically the i8042 keyboard controller) 造成的问题,可以通过下面的方法来验证:

    echo "disabled" | sudo tee /sys/devices/platform/i8042/serio0/power/wakeup

    重试睡眠后,系统果然安然入睡了~

    进入 s2idle 睡眠后,一晚上大概会消耗 10% 左右的电量。

    Firefox 播放视频时会触发 GPU 图形崩溃

    当启用 Firefox 的硬件加速后,播放视频会让 GPU 崩溃,丢失全部的显存内容。还好这个问题已经被 AMD 修复,升级到最新的内核即可。

    色彩管理

    机械革命提供了官方的色彩文件,但必须要在 Windows 下安装机械革命控制台才能下载(官方客服并不受理此类咨询)。加载了官方的色彩配置文件后,可以比较明显地缓解低亮度下对比度过低的问题。为了方面读到这篇文章的你,点击下面的链接就可以下载到这份色彩配置文件~

    ipfs://QmaR5ZxFXNwcsjn9XZq6CpDfRFyoffDEr9fpi15Hmb31K7

    开机后有概率屏幕卡死

    开启自适应同步后可解决,感谢 LY 提供的解决方案。

  • 提升机械革命无界 15XPro 暴风雪的充电速度

    This entry is part 2 of 4 in the series 机械革命无界 15XPro

    无界15XPro 的 99Wh 电池容量属实很大,但充电速度一言难尽,基本上要 4~5 小时左右才能从 10% 充到 100%。经过一番搜索后,总算找到了提升充电速度的方法。

    安装 Tuxedo Control Center 后,可以在 Settings 中找到 Battery Charging Options,只需要将 USB-C charging options 设置为 Priorize battery charing speed 就行。另外,如果长时间插电使用,还可以将 Charging profiles 设置成 Stationary use,这将会在硬件层面限制电池充电到 80% (但系统设置仍会显示充电到 100%)。

    如果你没安装 Tuxedo Control Center 也没关系,只要安装了驱动程序 (aur/mechrevo-drivers-dkms) ,就能通过下面两个 sysfs 接口实现同样的功能:

    cat /sys/bus/platform/drivers/tuxedo_keyboard/tuxedo_keyboard/charging_profile/charging_profile
    cat /sys/bus/platform/drivers/tuxedo_keyboard/tuxedo_keyboard/charging_priority/charging_prio
  • 似乎修复了唤醒后键盘短暂失效的问题

    This entry is part 3 of 4 in the series 机械革命无界 15XPro

    之前一篇文章的评论区有人提到过机械革命15XPro 暴风雪在唤醒后键盘会短暂失效的问题,往往需要重新睡眠再唤醒才能激活键盘。经过我的排查后发现,在该问题出现时,有两个比较重要的 Log 线索:

    Aug 27 09:04:52 arch kernel: atkbd serio0: Failed to deactivate keyboard on isa0060/serio0
    Aug 27 09:04:52 zarch kernel: atkbd serio0: Failed to enable keyboard on isa0060/serio0

    根据 Claude 以及互联网上相关的讨论,这个问题大概率跟内置键盘的驱动有关,通常可以通过尝试不同的 i8042/atkbd 相关参数来解决。

    跟 Claude 讨论一番过后,我决定添加如下 kernel parameters:

    i8042.reset=1 i8042.nomux=1 i8042.nopnp i8042.noloop atkbd.reset=1

    实际体验下来,键盘失效的问题已经一周多都没有复现了。

  • 外接显示器 EDID 损坏如何处理

    This entry is part 4 of 4 in the series 机械革命无界 15XPro

    上周五,我的外置显示器突然在一次热插拔后无法被笔记本电脑识别 4K 分辨率了,在排查了笔记本电脑、线材问题后,基本可以确定是显示器本身出了问题。

    从内核日志来看,系统无法读取显示器 EDID 信息:

    [  174.781913] EDID has corrupt header
    [  174.781923] amdgpu 0000:65:00.0: [drm] *ERROR* EDID checksum invalid.
    [  178.681809] EDID has corrupt header
    [  178.681819] amdgpu 0000:65:00.0: [drm] *ERROR* EDID checksum invalid.
    [  232.892047] EDID has corrupt header
    [  232.892057] amdgpu 0000:65:00.0: [drm] *ERROR* EDID checksum invalid.
    [  235.172080] EDID has corrupt header
    [  235.172091] amdgpu 0000:65:00.0: [drm] *ERROR* EDID checksum invalid.
    [  623.720346] EDID has corrupt header
    [  623.720359] amdgpu 0000:65:00.0: [drm] *ERROR* EDID checksum invalid.
    [  625.949958] EDID has corrupt header
    [  625.949969] amdgpu 0000:65:00.0: [drm] *ERROR* EDID checksum invalid.

    EDID 是一份显示器能力识别数据,包含生产厂商、支持的分辨率、刷新率等信息。EDID 一般存储在显示器的芯片内,如果显示器有多个输入端口,那么每个端口上的 EDID 通常会被分别存储在独立的芯片内。当电脑连接显示器时,会通过 DDC 读取显示器上存储的 EDID 信息,从而能够让电脑正确识别显示器的型号并输出显示器支持的视频信号。

    当 EDID 存储器损坏导致电脑无法读取时,我们可以主动向操作系统提供某个视频输出端口的 EDID 信息。这样以来,解决问题的思路就导向了寻找一份可用的 EDID 文件。

    幸好我的显示器有多个输入端口——一个 HDMI 2.0 以及 两个 HDMI 1.4 ,可以尝试读取 HDMI 1.4 端口的 EDID 文件,然后用 EDID 编辑器为其添加 4K@60Hz 的输出设置,作为 HDMI 2.0 接口的 EDID 文件。

    读取显示器上的 EDID 文件

    在 ArchLinux 上,可以使用 eedid-tool (AUR) 读取并保存 EDID 信息。

    # 扫描已连接的显示器 i2c bus
    $ eedid-tool -s
    Bus 11 has EDID, mfg BOE
    1 EDID(s) found.
    
    $ eedid-tool -r -b 11 > ./edid_hdmi1.4.bin

    由于 HDMI 1.4 不支持 4K 60Hz 的输入规格,所以需要手动尝试为其添加。

    修改 EDID 文件

    为了魔改刚刚导出的 EDID 文件,我使用了 AW EDID Editor,这款软件可以完美地通过 Bottles (Wine)运行,打开 AW EDID Editor 后,选择要修改 EDID 文件,稍等片刻后,你将看到这样的界面。

    点击 CEA Extension 下面的 Add new CEA Block,选择 Detailed Timing Descriptor。

    这时你会看到一个输入框全是 0 的配置界面。

    接着点击 Use predefined format,选择希望添加的分辨率规格即可,对于我的显示器来说,需要选择 3840×2160 60Hz。

    当配置界面被填充满各种数据后,就可以点击左上角的 File 菜单,保存修改后的 EDID 文件。

    设置自动加载 EDID 文件

    首先需要将修改后的 EDID 文件保存到 /usr/lib/firmware/edid/ 目录下,Linux 固件相关的二进制文件通常都放在这里。

    接着,我采用了下面的 systemd 文件来自动加载 EDID:

    [Unit]
    Description=Override HDMI EDID for Koios Monitor
    After=sys-kernel-debug.mount
    Requires=sys-kernel-debug.mount
    
    [Service]
    Type=oneshot
    # 关键:告诉 systemd 即使脚本跑完了,服务也被视为"active",这样才能执行 stop
    RemainAfterExit=yes
    
    # --- 启动时执行 (应用 EDID) ---
    # 1. 写入自定义 EDID
    ExecStart=/bin/sh -c 'cat /usr/lib/firmware/edid/koios_hdmi2.0.bin > /sys/kernel/debug/dri/1/HDMI-A-1/edid_override'
    # 2. 触发热插拔,让内核应用更改
    ExecStart=/bin/sh -c 'echo 1 > /sys/kernel/debug/dri/1/HDMI-A-1/trigger_hotplug'
    
    # --- 停止时执行 (撤销修改) ---
    # 1. 清空 override 文件
    ExecStop=/bin/sh -c 'echo -n reset > /sys/kernel/debug/dri/1/HDMI-A-1/edid_override'
    # 2. 再次触发热插拔,让内核读取显示器原本的真实 EDID
    ExecStop=/bin/sh -c 'echo 1 > /sys/kernel/debug/dri/1/HDMI-A-1/trigger_hotplug'
    
    [Install]
    WantedBy=multi-user.target

    由于我经常只会用到这一台显示器,所以还设置了自动启动服务,当需要连接其他显示器时,就可以通过停止这个服务,让操作系统直接读取该显示器提供的 EDID 。

    参考链接

    在解决这个问题的过程中,参考了 Gemini 3 Pro 生成的回复,不过其中有不少事实性错误,仍应参考 Arch Wiki 的文档:

    https://wiki.archlinux.org/title/Kernel_mode_setting#Forcing_modes_and_EDID

    另外,为了防止笔记本内置显示器的 EDID 在未来也发生了无法读取的情况,以及方便其他拥有跟我同型号显示器的人需要 EDID 文件,我将这些 EDID 上传到了 IPFS 网络: