2024 年 11 月,开发者 Yureka Lilian 购买了一台 M4 Mac mini,期望它能像 M1 到 M3 的 Apple Silicon 机器一样运行,并能在 Asahi Linux 中快速获得支持。然而事实并非如此。M4 是第一代强制要求启用安全页面表监控(SPTM)的 Apple Silicon 一代,这加固了 macOS 中 XNU 内核以抵御漏洞。早期的 Linux 移植依赖于通过 m1n1 捕获的内存映射 I/O 痕迹;而在 M4 上,若不对 m1n1 进行重大修改,这些痕迹无法被捕获。单独解决这一问题对该领域的新手来说超出了能力范围,于是 Lilian 转而并行推进 Linux 启动的工作。
初始启动尝试立即遇到寄存器被锁定的问题。GXF(Guarded Exception Levels)在 M4 级芯片的原始启动模式下被禁用,因此尝试初始化它会导致崩溃;正确的做法是将该初始化设为条件执行并跳过它。写入 RVBAR(重置向量基地址寄存器,用于告诉每个 CPU 核心从何处开始执行)也会导致崩溃,尽管该寄存器已经包含正确的值,因此必须省略该写入操作。即使使用了 earlycon 启动参数,串行输出也在数月内保持为空。设备树 缺少 stdout-path = "serial0";一旦添加该条目,Linux 在早期崩溃时便能打印出完整的寄存器转储和堆栈追踪。
此后,这些串行输出使得暴力调试方法成为可能。Lilian 插入了一个最小的 debug_putc 例程,用于打印单个字符 "a",并通过二分法检查启动序列。打印点在 MMU 被启用时停止,因为 UART 是内存映射 I/O,而在 MMU 打开后,内存访问需要经过页表转换为虚拟地址,而 Linux 并未将其一对一映射到 MMIO 空间。在初始页表中添加该 1:1 MMIO 映射后,可用的打印点被推得更远,直至故障转移到对一个特定于实现的寄存器 SYS_IMP_APL_VM_TMR_FIQ_ENA_EL2 的写入操作,该寄存器与虚拟化相关。注释掉该写入后,内核能够达到 shell;该寄存器在较新的 iBoot 版本中已被解锁,因此此变通办法不再必要。
真正的障碍在于第二个 CPU 核心以及 WFI(wait-for-interrupt)指令。在 M1 到 M3 上,一个名为 ARM64_REG_CYC_OVRD_ok2pwrdn_force_mask 的供应商控制位会导致 WFI 清零所有通用寄存器;XNU 在该指令前后会保存并恢复这些寄存器,而 m1n1 则禁用了此特性,使得 CPU 表现得像一个标准的 arm64 处理器。Asahi Linux 后来重新启用了该行为,以让核心进入更深的睡眠状态并节省功耗。在 M4 上,该位似乎被锁定或移除,因而默认行为违反了 ARM64 规范:如果 WFI 完成,则不应导致架构状态的丢失。2026 年 4 月,Lilian 通过将内核中的每一条 WFI 和 WFIT 指令替换为 NOP(无操作)指令,实现了在 M4 上启用所有核心引导 Linux。

该截图展示了 M4 Mac mini 已启动进入 NixOS,但 cpuinfo 报告仅有一个核心,这说明了 M4 芯片上 WFI 指令特性导致第二个核心无法启动。
与其在早期启动期间直接在内存中为硅补丁打补丁——这是一种处理硅错误的标准方法——作者认为这种做法不可靠,因为检测出所有应将 WFI 替换为 NOP 的情况并不可靠:在 macOS 高管程序下运行的虚拟机会触发相同的代码路径,但此时的 WFI 会被高管程序捕获以高效调度来宾。Will Deacon 提出了另一种解决方案:为内核提供一个新的 idle bootarg,形式为 idle=<wfi|yield|nop>,并让 m1n1 在已知存在 WFI 故障的裸机硬件上有条件地注入相应的参数。Lilian 报告称,此防止 Linux 在 WFI 和 WFIT 指令下崩溃的机制已被合并进主线 Linux 和 m1n1,因而最新版本的两者均可在 M4 Mac 上原生启动并启用次要核心。同样的变通办法同样适用于 M4 Pro、M4 Max 和 M5 芯片。
该工作直接提交给上游项目,而非保留在私人分支中,因此人人皆可使用它。在 M4 上对外围设备——摄像头、显示控制器和 GPU 初始化——的逆向工程进展较慢,后续工作预计将依赖于 m1n1 能否在该设备上启动并追踪 macOS。Lilian 还指出,来自资金充足的上游项目关于他们如何利用此类上游进展的更透明报告将不胜感激,并欢迎通过 LiberaPay 或 GitHub Sponsors 为该工作提供支持,亦可向 Asahi Open Collective 捐款。