Arch Linux 在 ASUS Zenbook S 13 OLED (UM5302TA) 上的 patch

综述

笔者在 ASUS Zenbook S 13 OLED (UM5302TA) 上安装 Arch Linux 时, 发现仅使用 Arch Linux 官方提供的 linux 或 AUR 上的 linux-mainline 等系统 packages 无法修复一些影响使用体验的问题. 其中一些问题已经得到了有效的解决方法, 乃至被添加入 Linux 源码中; 一些问题的 patch 尚未被纳入 Linux 源码库; 还有一些问题仍无解决方案.

修复这些问题的主要方式是在 Linux 内核源码中添加 patch, 或者是使用其他的方式 (例如修改 Bootloader 的行为) 来 “动态” 添加部分系统功能. 这些问题的大部分 patch 已经有了更为自动化的解决方案.

值得注意的是, 本文提及的各种 patch 理论上可以应用于其他发行版.

存在的问题和 patch

GitHub 上的 um5302ta 仓库汇集了该机型安装 Linux 后存在的各种问题, 以及针对这些问题的 patch, 本文不再赘述. 撰写本文时, 该仓库的最后一个 commit 为 b40223a.

被纳入 Linux 源码的 patch 分散在不同的内核版本, 最早可追溯到 5.19, 最晚则到了 6.1. 目前 Arch Linux 官方提供的 linux 包已经更新到了 6.1.4.arch1, 本文也以此为例.

根据该仓库的 README.md, 目前尚未解决的问题为指纹, 若无特别提及, 后文提到的 “问题” “所有问题” 并不包含指纹相关的内容.

而尚未被添加到 Linux 源码库中的问题则是扬声器的 DSDT patch 和 S3 级别睡眠的 patch. 扬声器的 patch 有两个, 经笔者测试至少可以解决如下的问题:

S3 睡眠的 patch 未经过笔者测试.

同时对麦克风的 patch 存在已知的音量过小的问题. 本文不会涉及对此的讨论.

实际使用发现, 该机型仍然存在数字小键盘无法使用的问题并未在该仓库中提及. 该机型的数字小键盘和触控板合并, 需要通过触摸触控板某一位置开关. 由于该功能实用性有限, 且存在可能的操作上的困难, 本文也不会涉及到该问题.

主要的解决方案

linux-mainline-um5302ta AUR 包

Linux 分支 Linux 版本 是否需要编译系统包 是否需要手动添加 patch
主线 >= 5.19.rc4

在 Linux 最新的内核版本尚未达到 5.19 时, 所有问题可以通过这个 AUR 包修复. 该包会对 Linux 主线的 tagged version 源码添加必要的 patch, 并进行编译安装. 若系统中已经安装 yay 等 AUR helper, 可以在终端中运行

1
yay -S linux-mainline-um5302ta

安装. 这一命令同时会打包并安装 linux-mainline-um5302ta 和 linux-mainline-um5302ta-headers 两个包. 需要注意的是, 编译内核需要一定的时间.

因为 um5302ta 这一仓库的存在, 该 AUR 包的作者已经停止维护, 但是理论上通过修改该包的 PKGBUILD 文件仍然可以在未来的内核版本中实现相同的效果.

其他系统包配合 um5302ta 仓库的 patch

Linux 分支 Linux 版本 是否需要编译系统包 是否需要手动添加 patch
任意 >= 6.0.9 是/否

按照 um5302ta 仓库提供的方案, 理论上绝大部分符合版本的 Linux 分支或基于前者的分支皆可以修复问题.

值得注意的是, dsdt/spkr-dsd.patch 无需编译完整的 Linux 源码包即可应用, 且一大优点是不会在更新内核的时候被覆盖, 因此对于如下不同需求的读者, 可以按照如下的参考路径解决问题, 并选读本节不同的子章节:

应用适当的 patch

Arch Linux 官方提供的系统包或从这些包中分支出的 AUR 包可以自动应用 patch. 读者需要做的是将所需的 patch 放置在 PKGBUILD 文件 (会在后文提及) 的父目录中, 然后修改 PKGBUILD 文件的内容, 将 patch 的路径添加到其中的 source 变量中. 理论上仍然需要在 sha256sums 变量中添加对应 patch 的 SHA256, 但可以使用 'SKIP' 跳过校验.

例如, 若需要应用 kernel/cs35l42-hda-no-acpi-dsd-csc3551.patch 这个 patch, 则只需要直接将该 patch 下载到对应的文件夹:

1
2
3
cd /path/to/package # 提前切换当前文件夹
wget https://github.com/latin-1/um5302ta/blob/b40223a5f9dd394f886c1ada50b46813f31e8444/patches/kernel/cs35l42-hda-no-acpi-dsd-csc3551.patch # 下载 patch
vim PKGBUILD

然后作出类似如下的修改, 将

1
2
3
4
source=(
"$_srcname::git+https://github.com/archlinux/linux?signed#tag=$_srctag"
config # the main kernel config file
)

改为

1
2
3
4
5
source=(
"$_srcname::git+https://github.com/archlinux/linux?signed#tag=$_srctag"
config # the main kernel config file
kernel/cs35l42-hda-no-acpi-dsd-csc3551.patch
)

然后将

1
2
sha256sums=('SKIP'
'0571ea17a2e38458096b679418197bbea8c414388f628d122517f3a1f3a31b3a')

改为

1
2
3
sha256sums=('SKIP'
'0571ea17a2e38458096b679418197bbea8c414388f628d122517f3a1f3a31b3a'
'SKIP')

添加多个 patch 的方法类似.

编译安装系统包

Arch Linux 官方 fork 了 Linux 社区的源码库, 并提供了编译, 打包, 安装的 “脚本” (交由 pacman 执行, 并不完全等同于 Shell 脚本). 本文以 linux 系统包为例.

与 AUR 包不同, Arch Linux 官方维护的包存储于 GitHub 的 svntogit-packages 仓库, 但所有的软件包的相关数据存储于各个分支中, 故直接克隆该仓库会产生大量的无用数据. 笔者选择直接 pull 需要的分支:

1
2
3
4
5
6
mkdir linux && cd linux
git init
git remote add origin https://github.com/archlinux/svntogit-packages.git
git pull origin packages/linux
git branch -M packages/linux # 可选
cd trunk

该文件夹的结构与 AUR 包相同, 可以看到其中存在 PKGBUILD 文件. 此时可以根据 “应用适当的 patch“ 章节的内容将 patch 的信息添加至 PKGBUILD 中. 随后, 在终端中执行

1
makepkg -si

编译, 打包并安装. 这会产生 linux, linux-docs, linux-headers 三个包.

编译 CPIO archive

重启应用新的内核后, 则需要应用 dsdt/spkr-dsd.patch. 对 DSDT 的介绍见. 大部分情况下, 读者只需要从 “Recompiling it yourself“ 小节开始阅读.

首先需要安装 acpica 这个软件包. 然后在终端中执行

1
2
3
4
5
sudo sh -c "cat /sys/firmware/acpi/tables/DSDT > dsdt.dat"
iasl -d dsdt.dat
wget https://github.com/latin-1/um5302ta/blob/b40223a5f9dd394f886c1ada50b46813f31e8444/patches/dsdt/spkr-dsd.patch
patch -Np1 < spkr-dsd.patch
iasl -tc dsdt.dsl

此时可以在当前目录找到 dsdt.aml. 再拉取 Linux 的源码, 切换当前目录到源码文件夹, 在终端中执行

1
2
3
4
mkdir -p kernel/firmware/acpi
cp /path/to/dsdt.aml kernel/firmware/acpi # 将 /path/to/dsdt.aml 更换为正确的路径
find kernel | cpio -H newc --create > acpi_override
sudo cp acpi_override /boot

acpi_override 是一个 CPIO archive 文件, 可以作为 initrd 被 boot loader 加载. 以 GRUB 为例, 修改 /etc/default/grub 文件, 在文件末尾添加:

1
2
# Load custom acpi_override
GRUB_EARLY_INITRD_LINUX_CUSTOM="acpi_override"

此时这个 CPIO archive 则会在 initramfs 前加载. 使用

1
sudo grub-mkconfig -o /boot/grub/grub.cfg

生成 grub 的配置文件. 可以检查该文件中是否已经写入 acpi_override, 例如:

1
initrd  /acpi_override /initramfs-linux.img

重启设备, 该 patch 即被应用.

[完]

Arch Linux 在 ASUS Zenbook S 13 OLED (UM5302TA) 上的 patch

https://blog.tamako.work/techdev/arch/um5302ta/

Posted on

2023-01-09

Updated on

2023-01-09

Licensed under

Comments