Apple sperrte die Boot-Chain. Er baute in 30 Tagen einen Linux-GPU-Treiber für den M4.

Apple sperrte die Boot-Chain. Er baute in 30 Tagen einen Linux-GPU-Treiber für den M4.

LinuxApple SiliconGPUKI

Quellen:codyho.dev

212 FPS auf dem M4 erreichen

Wie lange dauert es, Minecraft mit 212 fps auf einem M4 Mac Mini zum Laufen zu bringen oder WebGL in einem Browser flüssig zu rendern? Das Schreiben von Linux-Treibern für Apple Silicon war früher ein zermürbender Marathon – der Kernel-Treiber der M1-Ära wurde von Asahi Lina in 12-Stunden-Schichten hart erarbeitet. Jetzt haben die Entwickler Cody Ho und Niklas diese jahrelange Entwicklungsarbeit auf einen einzigen Monat komprimiert und einen OpenGL ES 3.0-kompatiblen GPU-Treiber von Grund auf neu aufgebaut.

Hier gibt es keine geleakten Geschäftsgeheimnisse. Sie nutzten Clean-Room-Reverse-Engineering, schauten sich keine Apple-Binärdateien an und verließen sich ausschließlich auf ihre selbst geschriebenen Shader und Hardware-Ausführungstraces. In einem Blackbox-Ökosystem kann die Community eine Alternative bauen, solange man die echten Ausführungssignale abfangen kann.

Chrome und Firefox führen WebGL mit diesem Treiber aus Abbildung: Chrome und Firefox rendern normal mit diesem Treiber. Quelle: codyho.dev

Apple hat den Treiber in zwei Hälften geteilt

Das größte Hindernis beim Schreiben von Treibern auf modernem Apple Silicon ist Apples proprietäres Firmware-ABI (Application Binary Interface). Herkömmliche Kernel-Treiber kommunizieren direkt mit der Hardware, aber Apples Ansatz teilt den Treiber in zwei Hälften: Die eine Hälfte ist als Firmware in einem benutzerdefinierten Betriebssystem namens RTKit eingebettet, während die andere Hälfte über Datenstrukturen im gemeinsamen Speicher mit dem Host kommuniziert.

Bei den M4- und A18 Pro-Chips ist dieser Kommunikationsmechanismus noch komplexer als in der M1-Ära. Die Datenstrukturen sind um das 1,5-fache angewachsen, die Anzahl der Zeiger hat sich verdoppelt, und der Workflow zum Einreichen von Rendering-Jobs gleicht einem Labyrinth. Firmware-eigene Felder und hostgesteuerte Felder sind stark miteinander verflochten, was die Entschlüsselung unglaublich schwierig macht.

Der unkonventionelle Ansatz schlug das Lesen von Dokumentationen

Wie entschlüsselt man diesen Mechanismus? Cody Ho nutzte einen selbst entwickelten Hypervisor, um das tatsächliche Hardwareverhalten von macOS präzise aufzuzeichnen. Anschließend wurde ein Large Language Model (LLM) Agent eingesetzt, um Blindversuche durchzuführen.

Die Vorgehensweise des Agents war sehr direkt: Er wartete auf das Erscheinen des ersten für die Firmware sichtbaren Ereignisses und speicherte den gesamten GPU-Speicherzustand. Nach einem Neustart kopierte er den Zustand exakt zurück in den Host-Speicher, löste die Ausführung aus und beobachtete aufmerksam die Speicheränderungen in der Ausgabeseite.

Wenn es nicht funktionierte, wurden Zeiger und Felder angepasst und der Test erneut ausgeführt. Im Laufe der Experimente verringerte sich die Anzahl der Speicherseiten, die hart kopiert werden mussten, bis alles von Grund auf durch Code konstruiert werden konnte. Die GPU-Treiberentwicklung wandelte sich von zermürbenden logischen Schlussfolgerungen zu einer hochfrequenten Versuch-und-Irrtum-Schleife.

Minecraft erreicht 212fps auf einem M4 Mac Mini Abbildung: Minecraft erreicht 212fps auf einem M4 Mac Mini. Quelle: codyho.dev

Saubere Daten sind wichtiger als Rechenleistung

Dieser Versuch-und-Irrtum-Ansatz stieß jedoch beim Compute-Modul an eine Grenze. Unter einer grafischen Benutzeroberfläche reihen sich Compute-Jobs immer hinter einer riesigen Menge an Rendering-Aufgaben ein. Das führte zu aufgezeichneten Ausführungstraces von bis zu 336 MB, die voller irrelevanter Geräusche waren. Der Agent versuchte über eine Woche lang erfolglos, Objekte selbst zu konstruieren.

Die Lösung war eine Rückkehr zur technischen Intuition: Cody Ho schaltete die grafische Benutzeroberfläche aus, startete in den Single-User-Modus und führte in dem Moment, als die Grafik-Schnittstelle verfügbar wurde, ein winziges Programm aus. Dies erfasste einen minimalen, reinen Compute-Ausführungstrace. Diese sauberen Daten wurden innerhalb von Stunden analysiert, und das Compute-Modul lief innerhalb weniger Tage. Einem Agenten 300 MB an schmutzigen Daten zu füttern, ist weitaus schlechter, als ein paar Stunden damit zu verbringen, ein Gerüst aufzubauen, das deterministische Ergebnisse liefert.

Die Abschottung wurde zum Beschleuniger

Apple verschärfte die Boot-Chain und zwang die Open-Source-Community, eigene Treiber zu entwickeln, um Linux auf Macs auszuführen. Dieser scheinbar schwierigste Weg entpuppte sich, unterstützt durch Record-and-Replay-Mechanismen und automatisierte Tools, ironischerweise als Abkürzung.

Dass der Entwicklungsaufwand von Jahren auf einen Monat reduziert wurde, lag nicht daran, dass das Modell plötzlich ein tiefes Verständnis für die Hardware entwickelte. Es lag daran, dass die Entwickler einen Hypervisor nutzten, um die Blackbox eines komplexen Systems in ein experimentelles Testfeld zu verwandeln, das sich unendlich oft zurücksetzen ließ und sofortige Ergebnisse lieferte. Der Weg, geschlossene Firmware-Dokumentationen zu lesen, war versperrt, aber der Weg der Blindversuche durch ultraschnelle Feedbackschleifen stand weit offen.

Referenzen:

  • Cody Ho: Aufbau eines GPU-Treibers von Grund auf in einem Monat
  • Asahi Linux Projekt (Hintergrund zum M1/M2 Kernel-Treiber)