Building a Linux GPU Driver for the M4 Mac Mini in One Month
Two developers, Niklas and the author, built a fully OpenGL ES 3.0 compliant GPU driver for the M4 Mac Mini and MacBook Neo in about a month, a process that normally takes years. They demonstrated Chrome and Firefox running WebGL on the M4 Mac Mini with working compositing, and the driver is fast enough to run Minecraft at 200fps. The code is not yet ready for end users, but they are looking to get it to users as soon as possible.
Building on the author's earlier hypervisor for reverse-engineering macOS, the project set out to do something useful with it by writing a GPU driver. The GPU is effectively a requirement for any modern system; otherwise everything must be CPU rendered, which is orders of magnitude slower and less power efficient. Their goal was to implement conformant OpenGL and soon Vulkan drivers for the M4 Mac Mini and MacBook Neo. Normally building a GPU driver takes years, and while their goal of doing it in days was overly optimistic, weeks is still a massive improvement.
In those weeks they reverse-engineered the M4, A18 Pro, and (mostly) M5 user space using only live probing, discovering hardware-supported features and instructions not emitted by Apple's driver. They built a fully working user-space driver, including a new custom IR/shader compiler, command stream builder, and many more components. They also reverse-engineered the full AGX firmware ABI from scratch using traces from the previously built hypervisor, and implemented a full Linux kernel driver for that firmware ABI.
Throughout the process they did not look at any Apple binaries, using only hardware traces and shaders they built themselves. For user-space graphics reverse engineering, they treated required Apple blobs as opaque objects; a friend wrote documentation on those blobs so they could write a clean-room implementation themselves, mostly by blindly trying things until they worked. They published all experiments in twin agx-re repositories so anyone can verify the provenance of their work. The blog post is split into user and kernel space, mirroring modern GPU driver architecture: the kernel interfaces with firmware, allocates buffers, and manages scheduling, while user space understands how the GPU works and fills those buffers. The kernel-space section begins by noting that on Apple Silicon the kernel driver does not interface directly with the hardware, but instead talks to the GPU firmware.