Apple a verrouillé la chaîne de démarrage. Il a écrit un pilote GPU Linux pour M4 en 30 jours.

Apple a verrouillé la chaîne de démarrage. Il a écrit un pilote GPU Linux pour M4 en 30 jours.

LinuxApple SiliconGPUIA

Sources:codyho.dev

Atteindre 212 FPS sur le M4

Combien de temps faut-il pour faire tourner Minecraft à 212 ips sur un Mac Mini M4, ou pour obtenir un rendu WebGL fluide dans un navigateur ? L’écriture de pilotes Linux pour Apple Silicon était autrefois un marathon épuisant : le pilote du noyau de l’ère M1 a été créé à la force du poignet par Asahi Lina, qui travaillait 12 heures par jour. Aujourd’hui, les développeurs Cody Ho et Niklas ont compressé cet exploit technique de plusieurs années en un seul mois, mettant sur pied un pilote GPU compatible OpenGL ES 3.0 à partir de zéro.

Il n’y a aucune fuite de secrets industriels ici. Ils ont utilisé la rétro-ingénierie en salle blanche, n’ont examiné aucun binaire Apple et se sont appuyés uniquement sur leurs propres shaders et sur les traces d’exécution du matériel. Dans un écosystème en boîte noire, tant que vous pouvez intercepter les signaux d’exécution réels, la communauté peut construire une alternative.

Chrome et Firefox exécutant WebGL avec ce pilote Figure : Chrome et Firefox avec un rendu normal sur ce pilote. Source : codyho.dev

Apple a scindé le pilote en deux

Le plus grand obstacle à l’écriture de pilotes sur le matériel Apple Silicon moderne est l’ABI (Interface Binaire d’Application) de firmware propriétaire d’Apple. Les pilotes de noyau traditionnels communiquent directement avec le matériel, mais l’approche d’Apple divise le pilote en deux : une moitié est intégrée en tant que firmware dans un système d’exploitation personnalisé appelé RTKit, tandis que l’autre moitié communique avec l’hôte via des structures de données dans la mémoire partagée.

Dans les puces M4 et A18 Pro, ce mécanisme de communication est encore plus complexe qu’à l’ère du M1. Les structures de données ont été multipliées par 1,5, les pointeurs ont doublé et le flux de travail pour soumettre des tâches de rendu ressemble à un labyrinthe. Les champs appartenant au firmware et les champs contrôlés par l’hôte sont étroitement liés, ce qui rend la situation incroyablement difficile à démêler.

L’approche empirique a supplanté la lecture de la documentation

Comment démêler ce mécanisme ? Cody Ho a utilisé un hyperviseur maison pour enregistrer avec précision le comportement matériel réel de macOS. Ensuite, un agent basé sur un grand modèle de langage (LLM) a été mis sur la chaîne de montage pour effectuer des tests en aveugle.

Le fonctionnement de l’Agent était très direct : attendre l’apparition du premier événement visible par le firmware, et sauvegarder l’état complet de la mémoire du GPU. Après un redémarrage, copier l’état exact dans la mémoire de l’hôte, déclencher l’exécution et observer attentivement les modifications de la mémoire dans la page de sortie.

En cas d’échec, il ajustait les pointeurs et les champs, et relançait l’exécution. Au fur et à mesure que les expériences progressaient, le nombre de pages mémoire nécessitant des copies exactes a diminué, jusqu’à ce que tout puisse être construit à partir de zéro à l’aide de code. Le développement de pilotes GPU est passé de déductions logiques épuisantes à une boucle d’essais et d’erreurs à haute fréquence.

Minecraft atteignant 212 ips sur un Mac Mini M4 Figure : Minecraft atteignant 212 ips sur un Mac Mini M4. Source : codyho.dev

Des données propres valent mieux qu’une grande puissance de calcul

Cependant, cette approche par essais et erreurs a heurté un mur dans le module de Calcul (Compute). Sous une interface graphique, les tâches de calcul sont toujours mises en attente derrière une quantité massive de tâches de rendu, ce qui donne des traces d’exécution enregistrées atteignant 336 Mo, entièrement remplies de bruit non pertinent. L’Agent a passé plus d’une semaine à essayer de construire des objets par lui-même, sans aucun progrès.

La solution s’est résumée à l’intuition de l’ingénieur : Cody Ho a désactivé l’interface graphique, a démarré en mode mono-utilisateur et a exécuté un tout petit programme à l’instant même où l’interface graphique est devenue disponible. Cela a permis de capturer une trace d’exécution minimale et purement dédiée au calcul. Ces données propres ont été analysées en quelques heures et le module de calcul a fonctionné avec succès en quelques jours. Nourrir un Agent avec 300 Mo de données sales est bien pire que de passer quelques heures à construire un échafaudage qui produit des résultats déterministes.

Le verrouillage est devenu un accélérateur

Apple a resserré la chaîne de démarrage, forgeant la communauté open source à créer des pilotes personnalisés pour faire tourner Linux sur des Mac. Ce chemin, qui semblait le plus difficile, s’est ironiquement transformé en raccourci grâce aux mécanismes d’enregistrement et de lecture et aux outils automatisés.

Si le travail de développement de plusieurs années d’une équipe a pu être compressé en un mois, ce n’est pas parce que le modèle a soudainement eu une révélation de bas niveau. C’est parce que les développeurs ont utilisé un hyperviseur pour transformer la boîte noire d’un système complexe en un terrain de jeu expérimental qui pouvait être réinitialisé à l’infini avec des résultats immédiats. La voie de la lecture de la documentation fermée du firmware était bloquée, mais celle des tests en aveugle grâce à des boucles de rétroaction ultra-rapides était grande ouverte.

Références :

  • Cody Ho : Construire un pilote GPU de zéro en un mois
  • Projet Asahi Linux (Contexte du pilote du noyau M1/M2)