Hacker News 中文摘要

RSS订阅

M4上Linux:CPU健忘 -- The Forgetful CPU (Linux on M4)

2024 年 11 月,作者买下一台 M4 Mac mini,赌它与 M1-M3 苹果芯片(Apple Silicon)机器相似,能很快在朝日 Linux(Asahi Linux)上获得支持。M4 在桌上放了几个月后,关于这颗 SoC 的更多细节浮出水面。2025 年 4 月,斯文·彼得(Sven Peter)发帖称,M4 的 Asahi Linux 支持会相当痛苦。原来 M4 是首代强制要求 SPTM(Secure Page Table Monitor)的苹果芯片,用于强化 macOS 的 XNU 内核抵御漏洞;前几代 Linux 移植则...

正文

我在 M4 Mac mini 上首次启动 Linux 的详细过程如下。首先感谢 Asahi Linux 团队此前的工作和一路上的帮助。

起点

2024 年 11 月,我买了一台 M4 Mac mini,赌它和 M1–M3 的 Apple Silicon 机器类似,能较快在 Asahi Linux 中得到支持。机器在桌上放了几个月,关于这颗 SoC 的更多细节开始浮现。

Mastodon 帖子截图,Sven Peter 2025 年 4 月写道:“看起来 M4 的 Asahi Linux 支持会相当痛苦……”

结果确实更难:M4 是第一代强制要求 SPTM(Secure Page Table Monitor)的 Apple Silicon,它为 macOS 的 XNU 内核提供针对漏洞的加固。此前几代做 Linux bringup 时,主要靠 m1n1 hypervisor 捕获的 MMIO 跟踪,来分析 macOS 原厂驱动与硬件的交互。有了 SPTM,要让 macOS 在 hypervisor 下运行需要对 m1n1 做重大改动,这远超我这个新手的水平。

不过这也不是完全没戏。在推进 hypervisor 工作的同时,我开始尝试在 M4 上启动 Linux:关闭严格启动安全,通过 macOS 恢复模式把 m1n1 安装为自定义启动对象,并获取串口控制台来查看日志。

被锁定的寄存器

起初 m1n1 只能在 BRINGUP 模式下启动,一旦尝试初始化 GXF 就会立刻崩溃。GXF 在这类 M4+ SoC 的原始启动模式中是禁用/锁定的,所以正确做法是把它的初始化改成条件执行,在这些机器上跳过。除 GXF 外还有 RVBAR(Reset Vector Base Address Register):每个 CPU 核在内存中有一段地址,决定核心上电后从哪里开始执行。m1n1 在启动内核或链式加载另一个 m1n1 时,会把入口地址写进每个核的 RVBAR。M4 上写这个寄存器也会崩溃,但简而言之,它已经包含了正确的值,所以跳过写入即可。

“2024-12-01 17:37 可以确认这个状态给出了可用的 USB proxy,lsusb 里出现了 ‘Generic m1n1 uartproxy v1.4.17-61-ga24ff77’,而且我能打开 shell :)”

debug_putc

终端截图,显示跨性别配色的 hyfetch NixOS 横幅。Host: Apple Mac Mini (M4, 2024),CPU: 1;还显示了 ip a 输出(除 loopback 外无接口)、lsblk(除从 loop0 挂载的 Nix store 外无块设备),以及只有一个核心的 cpuinfo

此后很长时间我没碰这台 Mac mini。2025 年底的 Chaos Communication Congress 让我重新有了动力。我拼出一个极简设备树,只包含 CPU 核和 AIC 中断控制器,用 m1n1 的 linux.py 加上 earlycon 参数加载 Linux 内核,但“Vectoring to next stage”之后看不到任何输出。既然内核不给有用输出,就只能瞎猜哪里出了问题。我决定用蛮力:老办法 println 调试。我把 m1n1 里的 debug_putc 汇编例程改成打印一个字符 ‘a’,插进内核启动极早期的代码,果然在“Vectoring to next stage”之后拿到了 ‘a’。基本上就是对 Linux 启动代码做二分,最后落在 MMU 初始化代码上(仍然非常早,还在 arch/arm64/kernel/head.S 的汇编里)。是 MMU 初始化让 CPU 崩了?并不完全是:UART 是通过内存映射 I/O 访问的。MMU 一旦启用,所有内存访问都走虚拟地址,再由页表映射到对应物理地址。m1n1 创建的映射把 MMIO 地址空间暴露在同地址上,Linux 不这么做,所以 MMU 启用后访问的是未映射空间,而不是 UART。我修改初始页表,为 MMIO 空间加上 1:1 映射,debug_putc 于是能工作到启动流程更靠后的位置。再次二分,打印一直工作到中断控制器初始化中的某处!我把它缩小到对实现特定 CPU 寄存器 SYS_IMP_APL_VM_TMR_FIQ_ENA_EL2 的一次写入,它触发了新的崩溃。注释掉这次写入后,内核启动到了 shell。后来这个与虚拟化相关的寄存器在新版 iBoot 中已解锁,不再需要注释掉。

现在我知道 Linux 代码确实在执行了,于是又回头看:为什么之前加了 earlycon 启动参数,串口控制台上却没有 printk 输出?

“2026-01-23 12:35 在 bootargs 里加了 earlycon=s5l,0x3ad200000 2026-01-23 12:36 现在崩溃发生前终于能拿到有用输出了!”

果然,设备树只是缺了 stdout-path = "serial0",加上之后,早期崩溃时就能从 Linux 得到完整的寄存器转储和栈回溯。

次要核心与 WFI

Linux 在 M4 上启用多核启动后的截图

此前 m1n1 不启动次要核心,是因为缺少 smp_start_offset(m1n1 里硬编码的偏移,没有它就会跳过 smp_init)。我试了基础款 M1–M3 用的偏移,成功启动了次要核。再次尝试加载 Linux,又遇到一次神秘崩溃。

此前几代 Apple Silicon CPU 对 WFI 指令已有已知怪癖。取决于 XNU 开源代码中名为 ARM64_REG_CYC_OVRD_ok2pwrdn_force_mask 的 chicken bit(寄存器中的一位,让厂商可以禁用某些 CPU 优化或特性,或者“临阵退缩”)的状态,WFI 指令会导致 x0–x31 寄存器被清零。XNU 会在 WFI 前把这些寄存器保存到栈上,之后再恢复。在 M1–M3 上,m1n1 禁用这一行为,让 CPU 表现得像其他 arm64 处理器。Asahi 内核后来特意重新启用它,好让 CPU 核进入更深睡眠状态省电;当簇内其他核都处于这种更深的 WFI 睡眠时,也让某一个核能提升到更高频率。

M4 上这个 chicken bit 似乎被锁定或移除了,默认行为不符合 ARM64 规范(具体说:“如果系统配置使得 WFI 指令可以完成,那么 WFI 指令不得导致架构状态丢失”)。2026 年 4 月,我把内核里所有 WFI 和 WFIT(带超时的等待中断)指令都替换成 NOP,成功在 M4 上启动 Linux 并启用全部核心。

随之而来的是为 WFI 问题寻找上游方案的漫长过程。起初我研究 errata(硅片异常行为)通常怎么处理——Linux 有一整套框架,允许内核在早期启动时在内存中给自己打补丁。但这个方案被放弃了,因为很难准确检测哪些情况该把 WFI 变成 NOP:在 macOS hypervisor 下运行的虚拟机也会触发 erratum 逻辑,而 WFI 会被 macOS hypervisor 捕获,用来高效调度不同 guest。检测虚拟化(尤其是启用嵌套虚拟化时)也很复杂。于是 Will Deacon 提出替代方案:内核增加一个新 bootarg 来禁用 WFI idle,然后 m1n1 在已知 WFI 有问题的裸机上条件地加上相应 bootargs。之后再加一套机制,让 Linux 能把核心置入睡眠状态。目前可以用下游的 cpuidle-apple 驱动,而 Sven 在 PSCI EFI conduit 上的工作对未来上游方案很有前景。

好消息是,防止 Linux 在 WFI 和 WFIT 指令上崩溃的机制已经合并进主线 Linux 和 m1n1,所以这些项目的最新版本已经能在 M4 Mac 上原生启动并使用次要核心。

下一步

这项工作迄今发现并解决了一个根本问题:在 M4 及之后的 Apple Silicon 芯片上运行 Linux。现在 Linux 能启动到 shell,所有核心都可用(同样的 WFI 变通也被发现适用于 M4 Pro、M4 Max 和 M5 芯片)。外设的逆向工程进展缓慢但稳定,这里不展开细节。Sven 不知疲倦地让 m1n1 hypervisor 能在这些设备上启动并跟踪 macOS,这对处理内置摄像头、显示控制器、GPU 初始化等更复杂的组件会非常有用。大部分工作我都直接提交到相应的上游项目,让所有人都能受益。有时我会希望,某些拿到大量资金的项目能更透明地说明自己如何从上游项目的进展中获益。

评论

社区认可苹果硬件优势却批评其生态封闭,少数人质疑在敌视开放的硬件上运行开源软件的逻辑,也有人设想开放硬件后的潜力,另有声音试探人工智能能否解决适配难题。

认为在封闭硬件上运行开源软件显得违和

  • 苹果对开放事物怀有敌意,在其设备上跑开源项目显得矛盾且奇怪。(少数人) > 在一家对开放事物怀有敌意的公司生产的机器上运行开放软件,这很奇怪。(@PunchyHamster)

认可苹果硬件实力但批评其封闭与臃肿

  • 虽然 macOS 被指臃肿且未拥抱开放硬件,但其硬件质量远超同类且有护城河,若转向开放将具统治力。(少数人) > 尽管 macOS 过于臃肿令人反感,但苹果硬件实在优于其他产品,且在此领域有护城河,若拥抱开放硬件前景不可限量。(@sscaryterry)

试探人工智能能否完成适配工作

  • 有读者提问,是否可借助人工智能来完成让开源软件适配苹果硬件所需的技术工作。(少数人) > 不知人工智能能否促成此事,是否有人尝试用人工智能完成所需的工作?(@polishdude20)