机械革命翼龙 15Pro 迁移 Linux 遇到的一些问题
买了高性价比非大众电脑带来的后果,就是完全没有对 linux 等做过硬件上的适配(也不准备支持)。用了一周解决了大概三个问题:内置键盘失灵、蓝牙模块无效、显卡驱动装不上、休眠立马唤醒的问题,简单记录一下。
键盘失灵
这个问题其实网上很多解,但是我的设备使用 DSDT 并不能解决。在最后,我通过 patch 内核的方式修复了这个问题。
这个问题的产生原因,简单来说就是 BIOS 里把键盘的高电平触发和低电平触发写反了,因此要用一个表来防止 ACPI override 它。具体可以看 patch 的内容。
From c33381bad489668de6f78f39bc9424e5de781964 Mon Sep 17 00:00:00 2001 From: MuelNova [email protected] Date: Sun, 26 May 2024 14:20:57 +0800 Subject: [PATCH] ACPI: resource: Do IRQ override on MECHREVO Yilong15 Series GM5HG0A
MECHREVO Yilong15 Serie has a DSDT table that describes IRQ 1 as ActiveLow while the kernel is overriding it to Edge_High. This prevents the internal keyboard from working. This patch prevents this issue by adding this laptop to the override table that prevents the kernel from overriding this IRQ
Signed-off-by: MuelNova [email protected]
---
drivers/acpi/resource.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index b5bf8b81a..fed3c5e1b 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -540,6 +540,12 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = {
* to have a working keyboard.
*/
static const struct dmi_system_id irq1_edge_low_force_override[] = {
+ {
+ /* MECHREVO Yilong15 Series GM5HG0A */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "GM5HG0A"),
+ },
+ },
{
/* XMG APEX 17 (M23) */
.matches = {
--
2.45.1
蓝牙
这个是因为网卡模块太新,没有被写入 btusb.c 里导致的。两周前已经被合并到 upstream,但是还没有更新到对应的软件源里。因此解决方法也就是拉最新的内核编译。
显卡
因为拉了最新的内核编译,所以显卡驱动安装失败了(笑)内核还没有到稳定版本,因此 nvidia 驱动还不准备做适配。带来的问题就是内核有一个破坏性变更,把 follow_pfn
这个函数删除了,导致 nvidia 编译失败。
补丁,根据 #642 如下
diff --git a/kernel-open/nvidia/os-mlock.c b/kernel-open/nvidia/os-mlock.c
index 46f99a1..b8f4100 100644
--- a/kernel-open/nvidia/os-mlock.c
+++ b/kernel-open/nvidia/os-mlock.c
@@ -30,11 +30,21 @@ static inline int nv_follow_pfn(struct vm_area_struct *vma,
unsigned long address,
unsigned long *pfn)
{
-#if defined(NV_UNSAFE_FOLLOW_PFN_PRESENT)
- return unsafe_follow_pfn(vma, address, pfn);
-#else
- return follow_pfn(vma, address, pfn);
-#endif
+ int status = 0;
+ spinlock_t *ptl;
+ pte_t *ptep;
+
+ if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)))
+ return status;
+
+ status = follow_pte(vma, address, &ptep, &ptl);
+ if (status)
+ return status;
+ *pfn = pte_pfn(ptep_get(ptep));
+
+ // The lock is acquired inside follow_pte()
+ pte_unmap_unlock(ptep, ptl);
+ return 0;
}
/*!
有了补丁之后,我的解决方法是安装 nvidia-open-dkms,然后在 /usr/src/nvidia-xxx.xx/
下修改 dkms.conf
,把 make 那里首先 apply patch
PACKAGE_NAME="nvidia"
PACKAGE_VERSION="550.78"
AUTOINSTALL="yes"
# By default, DKMS will add KERNELRELEASE to the make command line; however,
# this will cause the kernel module build to infer that it was invoked via
# Kbuild directly instead of DKMS. The dkms(8) manual page recommends quoting
# the 'make' command name to suppress this behavior.
# highligh-next-line
MAKE[0]="patch -p1 < /home/nova/nvidia.patch && 'make' -j`nproc` NV_EXCLUDE_BUILD_MODULES='' KERNEL_UNAME=${kernelver} modules"
# The list of kernel modules will be generated by nvidia-installer at runtime.
BUILT_MODULE_NAME[0]="nvidia"
BUILT_MODULE_LOCATION[0]="kernel-open"
DEST_MODULE_LOCATION[0]="/kernel/drivers/video"
BUILT_MODULE_NAME[1]="nvidia-uvm"
BUILT_MODULE_LOCATION[1]="kernel-open"
DEST_MODULE_LOCATION[1]="/kernel/drivers/video"
BUILT_MODULE_NAME[2]="nvidia-modeset"
BUILT_MODULE_LOCATION[2]="kernel-open"
DEST_MODULE_LOCATION[2]="/kernel/drivers/video"
BUILT_MODULE_NAME[3]="nvidia-drm"
BUILT_MODULE_LOCATION[3]="kernel-open"
DEST_MODULE_LOCATION[3]="/kernel/drivers/video"
BUILT_MODULE_NAME[4]="nvidia-peermem"
BUILT_MODULE_LOCATION[4]="kernel-open"
DEST_MODULE_LOCATION[4]="/kernel/drivers/video"
无法休眠
具体症状是休眠之后立马被唤醒的现象。
这个群里的老哥 和我有非常相似的经历。
这个 commit 解决了我的问题
首先查看被唤醒的时候是因为哪个中断
cat /sys/power/pm_wakeup_irq
cat /proc/interrupts
如果中断是 pinctrl_amd
,那么你很大概率遭遇到了同样的问题。在 root 下执行以下命令开启 DEBUG,然后再次休眠
alias ddcmd='echo $* > /proc/dynamic_debug/control'
ddcmd file "drivers/pinctrl/*" +p
echo 1 > /sys/power/pm_debug_messages
查看 dmesg,观察是否有 GPIO $N$ is active: 0xSOMEADDR
的情况
如果有, 那么在内核参数里添加如下参数屏蔽 gpio 接口
gpiolib_acpi.ignore_interrupt=AMDI0030:00@$N$ # 替换 $N$ 为你的 GPIO 接口号
重启,问题应该得到解决
总结
虽然看着很短,但是踩了无数的坑,编译了无数次内核,rollback 了无数次,熬了无数个接近通宵。喜欢用最新内核最新硬件的人是这样的。
参考资料太多,找不全了,不找了。