kukui改造计划 —— 彻头彻尾失败的折腾
Chromebook Duet(kukui / MT8183)
-1.前记
我于 2026 年 3 月 12 日购入了一台 Lenovo IdeaPad Chromebook Duet 10.9(初代),赞叹于其无与伦比的虚拟机数量 折腾潜力,诟病与其糟糕的性能。到手后惊奇地发现,卖家已经帮我关闭了操作系统验证(并且在启动界面上有“进入 Legacy Bios 和从 USB 启动的选项”),因此我早已开始痴心妄想 EFI 引导的开放性优势能为 kukui 小小的机身带来什么潜力。2026 年 4 月,受够了内置虚拟机的垃圾性能和 flatpak 少得可怜的支持 arm 的二进制包,我决定彻底抹掉 ChromeOS。
0.目标
- 机器:Chromebook Duet
- SoC:MT8183
- 代号:kukui
- 目标:把 Linux 装到 eMMC,基本抹掉 ChromeOS
- 发行版目标:Arch Linux ARM
省流:
-
先用 Cadmium 官方 Debian release 建立可启动的 Chromebook 内核/引导链
-
再把 eMMC 上的
IntRoot根分区替换成 Arch Linux ARM 的 rootfs -
短期继续使用 Cadmium 的内核
-
Arch 只接管用户态,不接管内核分区
-
Episode I - 借用 velvet-os 的 KERN 分区,牛头人 ArchLinuxARM
1.如梦初醒
“完蛋了,这并不是 EFI。” Chromebook 的启动链是:
- Coreboot(Google 定制)
- depthcharge(验证启动)
- 设备专用 kernel / DTB
我们没有办法把它刷成通用 UEFI 启动。
通过搜索找到 Arm的Chromebook手动切换AB分区 cgpt使用教程 Ubuntu双系统共存 改温度墙,她的办法是:
- 用
cgpt切换 ChromeOS 的 A/B 启动分区 - 在 不破坏 ChromeOS 前 12 个分区 的前提下,缩小
ROOT-B或调整 stateful 分区,给 Ubuntu 额外腾分区做双系统 - 仍然依赖 Chromebook 的原生启动方式和特定分区布局来启动另一个系统
腾出空间太小,而且双系统不是我想要的,我要抹掉 ChromeOS。
那我能不能找到一个现成的 KERN + rootfs 呢?
2.初见端倪
https://github.com/velvet-os/imagebuilder/blob/main/systems/chromebook_kukui/readme.md
Running Debian on arm64 chromebooks, consoles, tv boxes and other stuff.
我操,好几把炫酷。我操,它支援我的 kukui!遂把镜像烧录到 u 盘中,顺利进入 velvet-os。
那我岂不是可以在这根 USB 上保留 velvet 的 KERN,把 rootfs 替换成 Arch Linux ARM?
3.梦游 velvet-os
cat /proc/cmdline
root=LABEL=rootpart当时我是这么认为的,我可以新建一块分区用来存放 Archlinuxarm 的 rootfs,并把 LABEL 改为 rootpart 就可以无痛切换到 Arch 了!
创建新分区,配一下 DNS,wget -O - http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz | sudo tar -xzpf - -C /mnt/arch,chroot 进去做最小初始化,改 LABEL,重启!
arch 的 tty 的键盘驱动/按键映射出了很大问题…键盘难以触发,成功键入后不显示文本(就像在输密码),内置键盘和外接键盘如出一辙。
我明白了。我当时复用的那套 velvet/stb 内核(6.12.50-stb-cbm),不是 Arch 自己更通用的 Chromebook 内核,那很像键盘驱动 + keymap 双重问题。
那不用这垃圾内核了吧,pacman -S --disable-sandbox linux-aarch64-chromebook。
A new kernel version needs to be flashed onto /dev/sda5.
这意味着什么?/dev/sda5 是我的 Arch 根分区。这几把直接把 28MiB 的数据直接写到了我的分区开头。
为什么会这样?因为 linux-aarch64-chromebook 这个包的安装脚本会把 Chromebook kernel blob 写到一个块设备上。
而我当前 chroot 里 /boot 没有被正确指向“合适的启动目标”,它最终把目标识别成了 /dev/sda5。
我操。
我在 ArchLinuxARM 中找到了一个支持 kukui 设备的主线内核,它是 linux-aarch64-chromebook 内核。
我下载了一个 ArchLinuxARM RootFS。然后我在 U 盘上创建了两个分区:一个用于内核,一个用于根目录,并格式化为 ext4。之后,我将 RootFS 复制到了根分区。接着,我 chroot 到 Chromebook 目录,并使用命令“sudo pacman -S linux-aarch64-chromebook”安装了内核。然后,我通过下载你仓库中 kukui 的额外文件文件夹并复制,修复了蓝牙错误信息和声音问题。之后,我创建了 /etc/modprobe.d/blacklist.conf 文件,并添加内容“install bluetooth /bin/false”,再次修复了蓝牙错误信息。然后,我使用命令“sudo mkinitcpio -P”更新了 initramfs。之后,我创建了两个分区,并生成了一个 fstab 文件。最后,我从 Arch U 盘启动,使用 nmtui 连接到互联网,并使用命令“sudo pacman -S gnome”安装了 gnome。我也用 EndeavourOS 做过类似的操作,但需要一些额外的步骤。我目前使用的是 EndeavourOS。
我操不早说。
这条路最终还是搁置了,感兴趣的可以试试(?或许这才是最正确的答案
4. so, stb-cbm kernel, FUCK YOU!
所有 AI,帮我在 velvet 里生成一个新的、适合 kukui/krane 的 Chromebook KERN 分区镜像,再把它刷到 USB 的 KERN 分区。
sudo env NO_FLASH=1 CUSTOM_ROOT_PARAMETER=‘root=LABEL=archnew rootwait rw’ vtbuild “(uname -r)”
sudo dd if=/boot/vmlinux.kpart-initrd-6.12.50-stb-cbm+-archnew of=/dev/sda2 bs=4M status=progress conv=fsyncsync
sudo cgpt add -i 2 -P 10 -S 1 -T 2 /dev/sdasudo cgpt add -i 1 -P 1 -S 0 -T 0 /dev/sdasudo cgpt show /dev/sda
syncsudo reboot你猜怎么着,键盘问题依旧。
- Episode II - 用 Cadmium 引导,把 eMMC 上的 rootfs 换成 Arch Linux ARM
注意到,Cadmium 这个项目被反复提及。
A Linux
distroinstaller for some RISC laptops
WTF, thats what im looking for
1. 第一条路:直接让 Cadmium 构建 Arch 镜像
一开始走的是 Cadmium 的源码构建路线,修改 config 之后直接 build-all。
1.1 改过的 config
ROOTFS=arch1.2 构建命令
./build-all cadmium-kukui-arch.img 8G1.3 遇到的问题:Cadmium 的补丁逻辑有坑
构建过程中出现的致命问题:它开始打一些不属于 kukui 的内核补丁,例如:
x1e80100.uart14.patchx1e80100.slim7x-bt.patch
这两个明显是给 Snapdragon X Elite / Yoga Slim 7x 用的,不是 MT8183 kukui。
报错形态: Applying …/x1e80100.uart14.patch can’t find file to patch at input line 19 File to patch:
检查 kernel/build 发现根因:
case $KTREE in
mainline)
PATCHSUFFIX=“patch”
…
然后它会直接遍历: for x in CADMIUMROOT/kernel/patches/*.x done
也就是说,在 mainline 下它把 kernel/patches/ 里所有 .patch 全部打了。
1.4 即便手工挪走无关补丁,还是会继续炸
把无关补丁先挪走: mv kernel/patches/x1e80100.uart14.patch ../cadmium-patches-disabled/ mv kernel/patches/x1e80100.slim7x-bt.patch ../cadmium-patches-disabled/
再清缓存重跑: rm -rf tmp/linux-aarch64 ./build-all cadmium-kukui-arch.img 8G
但后面又陆续遇到这些问题:
gru.0002-drm-rockchip-Only-wait-for-panel-ACK-on-PSR-entry.patchkukui.unbreak-bluetooth.patch
都报类似: Reversed (or previously applied) patch detected! Skipping patch.
这说明这些补丁对当前 mainline 内核已经过时,或相应改动已经上游化,但 Cadmium 脚本没有跳过已应用补丁的逻辑。
得出结论:源码构建 Arch 镜像这条线,不稳定、不可复现、产物不可靠。
1.5 放弃直接 build Arch
2. 第二条路:改走官方 Debian release
源码构建不靠谱,改用 Cadmium 官方 release 的 Debian 镜像作为基线。这步的意义是拿到一套已在 kukui 上验证可启动的 Cadmium 内核 + Chromebook 引导链。
2.1 实机测试
官方 Debian release 的 USB 镜像能在这台 Duet 上正常启动。这步给后面的折腾提供了可启动基线。
2.2 把 Debian 安到 eMMC
在官方 release 上跑 ./install。
ntpdate 在 sid 里已经没了
Error: Package ‘ntpdate’ has no installation candidate
这步之后,Debian 基础系统安装基本完成。
2.3. eMMC 分区布局确认
安装后 eMMC 上形成这几个关键分区:
IntKernelAIntKernelBIntRoot
USB 启动盘上是:
ExtKernelAExtKernelBExtRoot
这就是后来整个方案的基础:USB 上那套是已知可启动的 Cadmium,eMMC 上那套是目标系统。
2.4. 开始把 rootfs 换成 Arch
不再让 Cadmium 直接生成 Arch 镜像,而是手工把 eMMC 的 IntRoot 替换成 Arch Linux ARM rootfs。
2.5 不重新格式化,尽量保留分区
尽量保留 IntRoot 分区本身,只替换里面内容。内核命令行往往会引用 root 分区,保留分区可让 UUID/PARTUUID 保持一致,减少”内核能起但找不到 root”这类问题。
2.6 把 IntRoot 挂到 /mnt
eMMC 的 root 分区是 /dev/mmcblk0p3,PARTLABEL 是 IntRoot:
mount /dev/disk/by-partlabel/IntRoot /mnt
2.7 解压 Arch rootfs 前
坑 1:bsdtar 不存在
bsdtar: command not found
apt update
apt install libarchive-tools
坑 2:resolv.conf 是 symlink
往 /mnt/etc/resolv.conf 写 DNS 时出现:
cp: not writing through symlink /mnt/etc/resolv.conf
rm -f /mnt/etc/resolv.conf
printf ‘nameserver 1.1.1.1\nnameserver 8.8.8.8\n’ > /mnt/etc/resolv.conf
2.8 解包 Arch Linux ARM rootfs
最后走 Arch Linux ARM 的 tarball 解包路线:
cd /tmp
wget <ArchLinuxARM 的 tarball>
bsdtar -xpf
然后补基础配置:
/mnt/etc/hostname/mnt/etc/fstab/mnt/etc/resolv.conf
再 bind mount 进 chroot: mount —bind /dev /mnt/dev mount —bind /proc /mnt/proc mount —bind /sys /mnt/sys mount —bind /run /mnt/run chroot /mnt /bin/bash
2.9. 在 chroot 里的 Arch 初始化
换镜像源,初始化 keyring,升级系统…熟悉得不能再熟悉的步骤。
2.10 不要让 Arch 刷自己的内核
升级过程中,linux-aarch64-chromebook 之类的包会问是否把新内核刷到设备上。当时还没搞清楚刷写逻辑,机器启动链已依赖 Cadmium,且吃过键盘故障的亏,所以先保住 Cadmium 可启动内核。
2.11. 第一次从 eMMC 启动 Arch:掉回 Chrome 恢复界面
重启后第一次从 eMMC 启动,没进 Linux,而是卡在类似:
系统正在进行一个关键更新,请勿关闭系统
这说明不是 Arch 卡住,而是 ChromeOS 固件没有成功从 eMMC 上的内核分区起机。rootfs 换 Arch 不是最大问题,真正问题出在 IntKernelA/B 启动链。
2.12. 排查 eMMC 启动失败
用 cgpt show /dev/mmcblk0 检查 eMMC 分区状态:
IntKernelA存在- 类型是
ChromeOS kernel - 属性正常:priority=10, tries=2, successful=1
结论:不是 GPT 标志位损坏,而是 IntKernelA 里的内核内容不对。
2.13 修复启动:把 eMMC 的内核分区恢复成和 USB 一样的 Cadmium 内核
核心思路:
- USB 上的
ExtKernelA是已知可启动的 - eMMC 上的
IntKernelA是怀疑对象 - 只要让 eMMC 上也有那套 Cadmium 内核,就能继续用 Arch rootfs
方法:把 eMMC 上的内部内核分区恢复成与 USB 那套一致的 Cadmium kernel。无论是用 install-kernel 还是直接把 USB 的 ExtKernelA 重刷回 IntKernelA,本质都是这件事。
结果:终于从 eMMC 顺利进入了 Arch。
2.14 内核和 /lib/modules 严重不匹配
进入 Arch 以后:系统能起,但键盘没反应
后来在 live 环境里一看,live 系统里: uname -r # 6.12.0-cadmium
而 eMMC 上的 Arch rootfs 里只有: /lib/modules/6.9.10-1-aarch64-ARCH
也就是说,当前真正运行的是 Cadmium 的 6.12.0-cadmium 内核,但 rootfs 里只有 Arch 自己的 6.9.10-1-aarch64-ARCH 模块。于是很多驱动模块都对不上。结果:
- USB 控制器能起来
- 设备能枚举
- 但 HID / 输入驱动没有正确加载
- 所以看起来像”键盘失灵”
2.15 修复驱动:把 Cadmium 内核对应模块拷回 Arch rootfs
关键。从 live 环境把与当前 Cadmium 内核对应的模块复制进 Arch: mkdir -p /mnt/lib/modules cp -a /lib/modules/6.12.0-cadmium /mnt/lib/modules/ mkdir -p /mnt/lib/firmware cp -a /lib/firmware/. /mnt/lib/firmware/ sync
然后进 chroot 跑: depmod -a 6.12.0-cadmium
重启之后,USB HID 设备在 dmesg 里也能看到正常的 input: 节点
这步之后,系统才真正可用。
2.16 图形界面:先装 sway,再修花屏
后面装了基础的 Wayland 环境: sudo pacman -S sway foot waybar wofi xorg-xwayland network-manager-applet
但直接运行 sway会出现闪屏、花屏、图形异常。这是一个不好的征兆。
2.17 修花屏:强制软件渲染 + 禁用硬件光标
WLR_RENDERER=pixman WLR_NO_HARDWARE_CURSORS=1 swayWLR_RENDERER=pixman:改用软件渲染WLR_NO_HARDWARE_CURSORS=1:禁用硬件光标
这样之后,sway 可以稳定进入。
Super + Enter,打开 foot 终端,享受自己造的这坨屎吧。
- Episode III 验证阶段!
网络:无 GUI 下靠 NetworkManager / nmcli
在还没完全进入图形之前,联网主要靠 NetworkManager 和 nmcli。
sudo pacman -S networkmanager
sudo systemctl enable —now NetworkManager
在无 GUI 下用 nmcli 连 Wi-Fi 是完全可行的。
蓝牙:正常
蓝牙这条线基本是通的。
装包并启动服务: sudo pacman -S bluez bluez-utils sudo systemctl enable —now bluetooth
然后通过 bluetoothctl:
power onagent ondefault-agentscan on
后续能正常看到控制器和设备,说明这块基本没问题。蓝牙可用。
声音:仍未打通,但是驱动有,ALSA 有
一开始 PipeWire 只有 Dummy Output
最早的状态是 Built-in Audio [alsa] 能看到,但 PipeWire 只有 Dummy Output。这说明不是整张声卡消失,而是用户态没给它正确的 profile / sink。
ALSA 层其实有设备
后来看: aplay -l arecord -l
都能看到这张卡:mt8183_mt6358_ts3a227_max98357
这说明内核声音驱动已经起来了,ALSA 设备也存在,问题更像是路由 / profile / mixer / UCM。
pactl list cards 发现 profile 居然是 off
声卡卡片存在,但 Active Profile: off。于是手动切到:
pactl set-card-profile alsa_card.platform-mt8183-sound pro-audio
这样之后,PipeWire 里终于不再只是 Dummy Output,而是出现了多个真实 sink / source。
但最终还是没真正出声
即便 profile 切到了 pro-audio,也还是 sink 能看到,pw-play 不报明显错误,但就是没有听见声音。
所以到目前为止,声音的结论是:驱动不是完全没起来,但音频路由/输出路径还没有彻底打通。
总结
已经可用的部分
- 从 eMMC 启动
- Arch Linux ARM rootfs
- Cadmium 6.12.0-cadmium 内核
- 内建键盘
- 外接键盘
- USB HID
- Wi-Fi
- 蓝牙
- TTY 正常
- sway 可进入
- 图形基本可用(在软件渲染模式下)
还没彻底解决的部分
- 声音
- 可能还有:更优的图形加速、完全摆脱 Cadmium 内核、更完整的桌面体验
- 经验
经验 1:不要一上来就硬啃 Cadmium 的 Arch build
对 kukui 来说,当前更靠谱的路线不是”Cadmium 直接 build 出 Arch 镜像”,而是:
- 先用官方 Debian release 建立可启动链
- 再手工替换 rootfs
经验 2:Cadmium 当前 mainline 构建的 patch 逻辑太粗
PATCHSUFFIX="patch" 会导致所有 .patch 全打,不属于本机的补丁也会被卷进去,过时补丁也会继续尝试打。这就是 x1e80100.uart14.patch、gru...patch、kukui.unbreak-bluetooth.patch 一路炸的根本原因。
经验 3:混合”Cadmium 内核 + Arch rootfs”时,/lib/modules 一定要匹配
这是最关键的一条。只换 rootfs,不换内核时,Arch 里的 /lib/modules 默认不会和 Cadmium 内核对上。所以必须手工把 /lib/modules/6.12.0-cadmium 复制到 Arch rootfs里。否则系统就会出现能启动,但输入设备像死了一样。
经验 4:短期内不要急着让 Arch 接管内核分区
在这台机器上,最稳的策略是 Cadmium 内核 + Arch 用户态,而不是马上去搞 linux-aarch64、linux-aarch64-chromebook、自己重封装 ChromeOS kernel partition。至少在机器已经稳定可用之前,不值得提前切这条线。
最终形态: Boot firmware: ChromeOS stock firmware Boot chain: Cadmium / depthcharge-compatible kernel partition Kernel: 6.12.0-cadmium Rootfs: Arch Linux ARM Storage: eMMC GUI: sway (pixman + no hardware cursors) Working: boot, keyboard, Wi-Fi, Bluetooth, TTY, basic GUI Broken / incomplete: audio
部分信息可能已经过时









