👁 19

2020 年之后,N 卡在 Mac 上基本等于砖头 —— NVIDIA 和苹果闹翻,最后一版 macOS 驱动停在 Mojave,往后 Maxwell、Pascal、Turing 全都点不亮。这六年里社区试过各种 Hackintosh 方案,基本都是拿到驱动却跑不动加速。

前几天有个项目把这事往前推了一大步:N 卡真的能在 macOS 上跑 Metal 了。项目叫 NullMoth NVIDIA Driver for macOS,支持 Turing 及之后的卡 —— GTX 16、RTX 20/30/40/50、TITAN RTX、Quadro RTX 和 T 系列,系统是 macOS 15 Sequoia(也支持 26 Tahoe),Intel Mac 和 OpenCore PC 都能用。

它不是那种”编译过了但一跑就黑”的半成品:Metal 3 的 argument buffers tier 2、ray tracing、mesh shaders、MetalFX 路径都写着支持,OpenGL 走 Apple 自己的 GL-on-Metal,OpenCL、Core Image、Core ML 也一起带上。作者自己说主力测试机是 RTX 5060 + macOS 15.8.1。

我把它整个仓库翻了一遍 —— 1106 个文件、29 MB,318 个 Rust 文件、340 个头文件、40 个 LLVM IR、23 个 Swift。下面先讲它是怎么做到的,再讲现在卡在哪。

原理:三段接力,外加一次”偷渡”

一句话概括:它没有从零写驱动,而是把苹果的口子、Mesa 的开源驱动、NVIDIA 自己开源的内核模块串成一条链。

Metal app
  └► NVMTLDriver.bundle          Metal 驱动插件
       └► translator              Apple AIR → SPIR-V
            └► NVK + NAK         Mesa Vulkan 驱动 + shader 编译器
                 └► NVRM.kext    NVIDIA 开源内核模块 (r610) 移植到 XNU
                      └► GSP 固件 610.57.04 (NVIDIA 官方原版)

第一段:苹果留的那个口子

Metal.framework 本身允许加载第三方 GPU 驱动 bundle —— 这是苹果为 AMD 和 Intel 之外的方案留的机制。NVMTLDriver.bundle 装在 /Library/GPUBundles/,实现 Metal 的 device、queue、command buffer、encoder、argument buffer、ray tracing 和 mesh pipeline 这些接口,底下全部转成 Vulkan 调用。

第二段:shader 要换一种语言

Metal 的 shader 编译产物是 AIR(Apple 的 bitcode),NVIDIA 的驱动不认。所以中间必须翻译一层:AIR → SPIR-V。这一步由一个 Rust 写的 translator 完成,它也是整个仓库最大的模块(10.7 MB Rust + 285 KB LLVM IR),基于 metal2vulkan 改的。

SPIR-V 再交给 NVK —— Mesa 里的 NVIDIA 开源 Vulkan 驱动,配 NAK shader 编译器,由它把 SPIR-V 编译成真正的 NVIDIA 机器码和命令缓冲。NVK 这边不是重写,而是打了个 449 KB 的补丁(基于 Mesa 17ca6174),让它跑在 macOS 的 NVRM 上,而不是 Linux 的 DRM 接口。

第三段:内核这一层,靠的是 NVIDIA 自己

这是整个方案最巧的地方。NVIDIA 在 2022 年开源了 GPU kernel modules(原本是为了 WSL2 和 Linus 社区),也就是仓库里用的 r610 版本。这套代码里 Linux 相关的部分用一层 os-xnu*.cpp 顶掉,直接接到 XNU 内核上 —— 变成 NVRM.kext。

启动时它做四件事:认领 PCI 设备、映射 BAR 并把 BAR1 挪出固件控制台;占住 I/O registry 挡住 WindowServer 不让它在固件画面上起来;在自己的线程里从 /Users/Shared/nvfw/nvidia/610.57.04/ 加载 GSP 固件,用 rm_init_adapter() 把 GPU 引导起来;最后拉起 NVKMS 模式设置,显示就绪后放手。

显示和合成走另一条并行路径:

WindowServer ─► IOFramebuffer = NVRMFB.kext   (模式、vblank、显示头)
             ─► IOAccelerator = NVAccel.kext  (WindowServer 合成用的共享 surface)
             ─► AGDC policy   = NVRMAGDC.kext (显示策略应答)

所以完整的链条是:苹果的 Metal 接口 → 项目的翻译器 → Mesa 的开源 Vulkan → NVIDIA 自己的开源内核模块 → NVIDIA 官方固件。三方各出一块,项目负责把它们焊在一起。

现在面临的问题

原理很漂亮,但代价和限制同样清楚。

1. 必须把 macOS 的安全机制全关掉

这不是可选项,是硬要求。OpenCore 里必须这么配:

项目 值 后果
csr-active-config 0x0A43 关掉 SIP(系统完整性保护)
amfi_get_out_of_my_way 0x1 关掉 AMFI 签名校验
amfi 0x80 同上,允许 WindowServer 加载驱动 bundle
SecureBootModel Disabled 关掉安全启动
依赖 Lilu.kext + AMFIPass.kext Hackintosh 破解基础设施
ipc_control_port_options 0 放宽 IPC 检查

加载任何第三方未签名 kext 都得这么干,这不是这个项目的毛病 —— 但你得知道自己在换什么:装完之后,这台机器的内核层面不再设防,任何扩展都能跑。

2. Apple Silicon 完全没戏

只支持 x86_64。Intel Mac 苹果 2020 年就停产了,所以真实的用户群体只剩黑苹果 PC。M 系列芯片想要 NVIDIA 显卡,这条路是死的 —— 而这恰恰是现在 Mac 用户的绝对主力。

3. 测试面窄得惊人

README 自己写得很直白:”Most testing is done on an RTX 5060, so other cards may have problems that haven’t been found yet” —— 主力测试就一台机。50 系之外的卡,出了问题只能自己撞。

4. 团队匿名,且有商业意图

“NullMoth Systems”,没有实名信息,靠 buymeacoffee 求赞助,配了个叫 1401 的独立安装 app 和 Discord 群。NVIDIA 和苹果都没参与这个项目,所以法律和授权层面是灰色地带 —— 尤其它还要分发 NVIDIA 的固件和 NVVM 编译库。

5. 驱动本身还是新的

文档里自己也写着 “The driver is new”,首启可能在 “PCI configuration end” 停上接近一分钟等 GPU 起来。真出问题,恢复路径是 boot-args 加 -nvoff 让 NVRM 绕开这张卡,或者用 1401 装出来的 “Remove NVIDIA driver” 启动项一键卸载。

6. 内核代码不是它写的

真正跟硬件打交道的那层是 NVIDIA 自己的开源模块,项目只改了 OS 抽象层。这意味着两件事:一是稳定性受制于 NVIDIA 的开源版本节奏;二是万一 NVIDIA 收回开源授权,后续更新就断了。

顺带一提:它明确拒绝 AI 代写贡献

仓库根目录有份 AGENTS.md,标题就是 “Notes for AI assistants”,要求 AI 不要代写 PR、issue 和 review 评论:”AI-written ones are closed without review”。CONTRIBUTING.md 里还专门有一节叫 “No AI-written contributions”,并且要求每个 PR 必须写清楚测了什么卡、什么 macOS 版本、怎么验的 —— "Builds" is not tested。我只做了本地阅读,没提任何东西。

安装前该检查的三件事

一是你的卡在不在 Turing 及之后,Pascal 及更早的没戏;二是你是不是 x86_64 环境,不是就不用往下看了;三是你能不能接受关掉 SIP 和 AMFI —— 这条是分水岭。

真要装,值得先跑它的干跑模式:CHECK=1 会走完整个安装流程但什么都不改,直接输出 CHECK PASS (nothing changed),你可以先看清楚它到底会动哪些文件。我扫了它 338 行的 install.sh:没有 curl/wget/nc/eval,没有任何外发,固件从共享目录加载前会先 shasum -a 256 -c SHA256SUMS 全量校验,装完 chmod -R a+rX 只给读不给写,而且带完整备份回滚。从脚本质量看,作者是知道自己在做什么的。

结论

  1. 技术上是真做到了:不是轮子,是把苹果的 Metal 插件机制、Mesa 的 NVK、NVIDIA 2022 年开源的内核模块三者焊接起来,自己那部分(翻译器)10.7 MB Rust,是实打实的工程量。
  2. 最大的功臣是 NVIDIA 自己的开源:没有那套 r610 内核模块,这项目根本无从下手 —— 这大概也算”开源改变世界”的一个意外注脚。
  3. 代价是安全边界归零:SIP、AMFI、SecureBootModel 全关,换成别人签名不了的内核代码。
  4. 适用面很窄:x86_64 + Turing 之后的卡 + 主力只测了 RTX 5060,Apple Silicon 用户可以划走了。

对折腾黑苹果的人来说,这是六年里最有分量的一次进展;对普通 Mac 用户,它暂时和你无关。

顺带一提,类似的”把别人的生态接到自己机器上”的事我也干过 —— 比如在 Linux 上用 Podman 跑了 48 天 Windows 11,删盘前顺手记了记它和虚拟机差在哪,还有研究NUC 类小主机的 UEFI 分区布局。折腾的本质都一样:先搞清楚它原本怎么工作,再决定要不要动它。