苹果封死启动链,他用30天给M4写出Linux驱动

苹果封死启动链,他用30天给M4写出Linux驱动

LinuxApple SiliconGPUAI

数据源:codyho.dev

在 M4 上跑出 212 帧

在 M4 Mac Mini 上跑出 212fps 的 Minecraft,或者让浏览器流畅运行 WebGL,需要多久的底层开发?为苹果芯片写 Linux 驱动曾是一场漫长的马拉松——M1 时代的内核驱动是 Asahi Lina 每天工作 12 小时硬磕出来的。现在,开发者 Cody Ho 和 Niklas 把这段数年的工程压缩到了一个月,一套兼容 OpenGL ES 3.0 的 GPU 驱动便拔地而起。

这里没有商业机密的泄露。他们采用干净室反向工程,不看任何苹果的二进制文件,仅靠自己写的着色器和硬件运行轨迹来摸索。在黑盒生态里,只要能截获真实运行的信号,社区就能造出平替。

Chrome 和 Firefox 在这套驱动上跑 WebGL 图:Chrome 和 Firefox 在这套驱动上正常渲染。来源:codyho.dev

苹果把驱动劈成了两半

要在现代苹果芯片上写驱动,最大的阻碍是苹果独创的固件 ABI(应用程序二进制接口)。传统的内核驱动直接和硬件对话,但苹果的做法是把驱动切成两半:一半塞进名为 RTKit 的自定义操作系统里作为固件,另一半通过共享内存里的数据结构与主机通信。

在 M4 和 A18 Pro 芯片里,这种通信机制比 M1 时代更繁杂。数据结构数量多了 1.5 倍,指针数量翻番,提交渲染工作的流程如同迷宫。固件自有字段和主机控制字段交织在一起,要梳理清楚并不容易。

笨办法跑赢了阅读文档

怎样解开这套机制?Cody Ho 掏出的工具是一台自研的 hypervisor(虚拟机监视器),用来精准录制 macOS 的真实硬件行为。随后,一个大语言模型 Agent 被推上流水线,开始执行盲试。

Agent 的操作十分直接:等待第一个固件可见事件出现,把 GPU 内存状态全盘保存。重启后,把状态原封不动拷回主机内存,触发执行,然后死死盯着输出页的内存变化。

如果不对,就调整指针和字段,重新跑一次。随着实验推进,需要硬拷贝的内存页越来越少,直到一切都能用代码从零构造。GPU 驱动开发从烧脑的逻辑推理,变成了高频的试错循环。

Minecraft 在 M4 Mac Mini 上跑到 212fps 图:Minecraft 在 M4 Mac Mini 上跑到 212fps。来源:codyho.dev

纯净数据比算力更重要

但这种尝试在计算(Compute)模块撞上了墙。图形界面下,计算工作总是排在大量渲染任务之后,导致录制下来的运行轨迹高达 336MB,里面全是不相关的噪音,Agent 自己构造对象卡了一周多毫无进展。

解决办法回归了工程直觉:Cody Ho 关掉图形界面进入单用户模式,在图形接口刚可用的瞬间运行小程序,抓取出了一份极小、纯计算的运行轨迹。这套数据在几小时内就被解析,几天内计算模块便宣告跑通。给 Agent 喂 300MB 的脏数据,不如花几个小时为它搭建一个输出确定结果的脚手架。

封锁变成了加速器

苹果收紧启动链,迫使开源社区只能通过自研驱动来让 Linux 跑在 Mac 上。这个看似最难的选择,反而在录制回放机制和自动化工具的配合下,被走成了一条捷径。

把团队年级别的开发量压缩到一个月,并不是因为模型突然具备了底层的顿悟。它是因为开发者用虚拟机把复杂的系统黑盒,变成了一个可以无限重置、结果立现的试验场。阅读封闭固件文档的路被堵死了,但通过极速反馈回路盲试的路走通了。

参考链接:

  • Cody Ho:用一个月从零构建一块 GPU 驱动
  • Asahi Linux 项目(M1/M2 内核驱动背景)