Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Pixelbook Go 开荒

机器基本信息如下:

进系统没有任何问题,直接 UEFI 启动,并使用 setup-alpine 配置重启完成。

补齐 Super 键

原本 Super 键也就是 Win 键的位置现在是 Google/Assistant 键,而且按下毫无反应。 使用 evtest 监听发现 Google 键无值,不过内核日志 dmesg 里已经给了解法:

atkbd serio0: Unknown key pressed (translated set 2, code 0xd8 ...)
Use 'setkeycodes e058 <keycode>' to make it known.

因此这里映射到 KEY_LEFTMETA 也就是 125 即可。使用 udev 规则持久化:

# /etc/udev/rules.d/98-keyboard-map.rules
ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="AT Translated Set 2 keyboard", RUN+="/usr/bin/setkeycodes e058 125"

数值来自内核:

$ grep KEY_LEFTMETA /usr/include/linux/input-event-codes.h
#define KEY_LEFTMETA            125

修正 Caps 键

Caps 位置的按键在 ChromeOS 里默认搜索,但凡 Linux 上这里是 Esc 甚至 Ctrl 我就认了,不过居然是 Super。 在 evtest 里查到 MSC_SCAN 对应的 value,然后和 Google 键相同,写规则改成 KEY_CAPSLOCK:

# /etc/udev/rules.d/98-keyboard-map.rules
ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="AT Translated Set 2 keyboard", RUN+="/usr/bin/setkeycodes db 58"

调整电源按键

电源键在右上角,删除的时候很容易误操作按到,机器直接开始关机啊!我用的 WM 没有锁屏键所以希望这里是按下休眠待机。 首先需要看下机器休眠的支持情况:

$ cat /sys/power/state
freeze mem disk
$ cat /sys/power/mem_sleep
s2idle [deep]

第一个文件表示系统支持 Suspend-to-Idle、Suspend-to-RAM、Suspend-to-Disk,后两者也被称为 S3 和 S4; 第二个文件表示当前的 mem 是哪种实现,选中的 deep 表示硬件真实的 S3 ACPI 状态(现代机器应该都是这样)。

Alpine Linux 上没有 systemd-logind,电源按键策略全靠 busybox 的 acpid。 检查日志 /var/log/acpid.log 可以看到电源键对应的事件名 PWRF 和通知值,类似:

acpid: XXX/00000080: No such file or directory

于是创建对应的脚本 /etc/acpi/PWRF/00000080,把字符串直接写入:

#!/bin/sh
echo mem > /sys/power/state

唤醒似乎不走这里,键盘上任意键按下都能拉起,所以不做调整;长按电源键关机是硬件行为,与这里无关。

支持合盖休眠

与前文相同,创建对应的文件 /etc/acpi/LID/00000080 并写个脚本:

#!/bin/sh
grep -q closed /proc/acpi/button/lid/LID0/state 2>/dev/null \
    && echo mem > /sys/power/state

OpenRC 用户服务

Warning

这一节与 Pixelbook 无关,且存在错误:OpenRC User Service 内部服务依赖会再拉起 DBus 会话,与 dbus-run-session 冲突。推荐参考 https://wiki.alpinelinux.org/wiki/OpenRC_User_Services

我用的自研 WM,会话环境完全由 start-lafa 脚本建立:

TTY 登录
  └─ start-lafa
    ├─ 创建 XDG_RUNTIME_DIR(/run/user/$UID,失败回退 /tmp/lafa-runtime-$UID)
    ├─ export XDG_CURRENT_DESKTOP=lafa、XKB_DEFAULT_OPTIONS
    └─ exec dbus-run-session lafa
      └─ lafa.exec("openrc -U default")   用户 runlevel 在此拉起

至此刚好在用户服务启动时,DBUS_SESSION_BUS_ADDRESS、XDG_RUNTIME_DIR、WAYLAND_DISPLAY 三者就位。 等桌面关闭时走再去把服务 down 掉。

function on_exec()
    lafa.spawn("openrc -U shutdown")
end

修复音频无声

声卡识别正常(aplay -l 能看到 MAX98373 扬声器 / DA7219 耳机 / HDMI / DMIC), 而 PipeWire 运行正常,播放不报错,但没有声音,问题是上游内核与用户空间配置的断层:

  1. 2025 年内核合并了 Intel AVS 驱动的声卡改名补丁,改为通用的 AVS I2S MAX98373,且不设置 DMI longname
  2. ALSA UCM 靠 longname 匹配配置,发行版打包的旧配置只有 Google-Atlas-1.0.conf,匹配失败
  3. UCM 没加载、未执行初始化序列、功放开关 Spk Switch 默认关闭、主音量 DSP Volume = 0、音频流播放但无声
  4. 配套修复 https://github.com/alsa-project/alsa-ucm-conf/pull/571 长期未合并,很多 AVS 设备中招

此外 UCM 写死 PlaybackPCM "hw:${CardId},1",而新内核里在device 0,不匹配 PipeWire 直接忽略。

alsa-lib 不支持 per-user 的 UCM 默认路径,所以方法是 ALSA_CONFIG_UCM2 环境变量, 再准备整棵 ucm2 树,搭一个最小树去包含我们的修改:

~/.config/alsa/ucm2/
├── ucm.conf -> /usr/share/alsa/ucm2/ucm.conf
├── lib -> /usr/share/alsa/ucm2/lib
├── conf.d/avs_max98373/
│   └── avs_max98373.conf -> ../../Intel/avs/avs_max98373/Google-Atlas-1.0.conf
└── Intel/avs/avs_max98373/
    ├── Google-Atlas-1.0.conf -> /usr/share/alsa/ucm2/.../Google-Atlas-1.0.conf
    └── Google-Atlas-1.0-HiFi.conf    唯一被修改的文件

Google-Atlas-1.0-HiFi.conf 是系统文件的副本,只改一行:

- PlaybackPCM "hw:${CardId},1"
+ PlaybackPCM "hw:${CardId},0"

UCM 是 PipeWire 进程(SPA alsa 插件)打开的,WirePlumber 只选 profile 所以环境变量是注入 PipeWire。 我们用的 OpenRC 所以写到 ~/.config/rc/conf.d/pipewire 里:

export ALSA_CONFIG_UCM2=$HOME/.config/alsa/ucm2

然后重启服务:

rc-service --user pipewire restart

增加 F1-F12

默认最上面一排多媒体按键是 F1 到 F10 非常坑爹:我们最常用的 F11 全屏和 F12 开发者没有,而且它也没印任何数字提示。 我希望用这排数字键额外加上 -/+ 两个键去等效到 F1 至 F12,而将右 ALT 键视作 Fn 键来长按激活此 Level。

之前在扫描码层解决了 Super 键和 Caps 键的问题,针对这种带修饰键的问题使用 XKB 的方法规避。 lafa 用 xkb_keymap_new_from_names(NULL) 加载键盘映射,遵循 libxkbcommon 默认行为, 而规则/选项取自 XKB_DEFAULT_* 环境变量,且家目录优先,因此 ~/.config/xkb 放两个文件即可:

# ~/.config/xkb/symbols/pixelbook
partial alphanumeric_keys modifier_keys
xkb_symbols "ralt_fn" {

    replace key <RALT> { [ ISO_Level3_Shift ] };
    modifier_map Mod5 { <RALT> };

    replace key <AE01> { [ 1,     exclam,       F1  ] };
    replace key <AE02> { [ 2,     at,           F2  ] };
    replace key <AE03> { [ 3,     numbersign,   F3  ] };
    replace key <AE04> { [ 4,     dollar,       F4  ] };
    replace key <AE05> { [ 5,     percent,      F5  ] };
    replace key <AE06> { [ 6,     asciicircum,  F6  ] };
    replace key <AE07> { [ 7,     ampersand,    F7  ] };
    replace key <AE08> { [ 8,     asterisk,     F8  ] };
    replace key <AE09> { [ 9,     parenleft,    F9  ] };
    replace key <AE10> { [ 0,     parenright,   F10 ] };
    replace key <AE11> { [ minus, underscore,   F11 ] };
    replace key <AE12> { [ equal, plus,         F12 ] };
};

还原多媒体键

XKB 里已经存了一份 ChromeBook 适用的配置,我们在 rules 里启用,同时连带上 Fn 的修改:

# ~/.config/xkb/rules/evdev
! include %S/evdev

! option	= symbols
  pixelbook:ralt	= +pixelbook(ralt_fn)
  pixelbook:media	= +inet(chromebook)

最后在启动脚本 start-lafa 里导出环境变量指向这里新增的配置:

export XKB_DEFAULT_OPTIONS="pixelbook:ralt,pixelbook:media"

这种修改只在进了桌面的 XKB 层生效,TTY 里仍是 F1–F10。 要全场景生效需要替换换 udev 里的 hwdb 或用第三方改键工具如 keyd 等。

Firefox 视频周期性卡顿

Note

事后发现是我自己 Lafa 合成器的 Bug,责任全在 GPT 防御性编程!

播放视频时画面每隔一段时间卡住几秒后自行恢复,alt-tab 也能立刻恢复;卡住期间音频正常。

第一次以为是缺 VA-API 硬解驱动,装上 intel-media-driver 后症状仍在; 第二次以为是 AV1 软解,在火狐里 about:config、media.av1.enabled 关掉后仍不行; 最后发现可能是 i915 的 PSR2(Panel Self Refresh)问题。

确认方法:

cat /sys/module/i915/parameters/enable_psr      # -1(默认启用)
cat /sys/kernel/debug/dri/*/i915_edp_psr_status # PSR2 enabled / SU_STANDBY

修复:

# /etc/default/grub 的 GRUB_CMDLINE_LINUX_DEFAULT 追加 i915.enable_psr=0
keyi grub-mkconfig -o /boot/grub/grub.cfg
# 重启后 cat /sys/module/i915/parameters/enable_psr 应为 0

操作后在哔哩哔哩看视频屏幕基本正常,但是终端 foot 里开 pi 的时候偶尔还是卡住,因为复现概率低还没想到怎么修。

备注

Kimi K3 重度参与,均已人工验证。后续将会用 Fedora 等别的发行版来做对比。