Mac OS X 10.0 (Cheetah) erfolgreich auf der Nintendo Wii ausgeführt
(bryankeller.github.io)- Ein Portierungsprojekt wurde abgeschlossen, das Mac OS X 10.0 (Cheetah) nativ auf der PowerPC-basierten Hardware der Wii ausführt
- Der Darwin/XNU-Kernel wurde an die Wii angepasst, und Bootloader, Device Tree und Treiber wurden direkt geschrieben, wodurch sogar der Start bis in die GUI-Umgebung gelang
- Durch die Implementierung angepasster IOKit-Treiber mit Unterstützung für SD-Karte, Framebuffer und USB-Eingabegeräte wurde ein vollständig funktionierendes System erreicht
- Berücksichtigt wurden auch Wii-spezifische Strukturen wie die Behebung von BAT-Konflikten, der Aufbau einer Treiberschicht für das Hollywood-SoC sowie ein RGB→YUV-konvertierender Framebuffer
- Nach über zehn Jahren an Versuchen wurde auf der Wii ein vollständiger Start und die Bedienung von Mac OS X realisiert und damit der Wert eines scheinbar unmöglichen Projekts bewiesen
Überblick über das Projekt, Mac OS X auf der Wii auszuführen
- Es wurde ein Portierungsprojekt durchgeführt, um Mac OS X 10.0 (Cheetah) nativ auf der Nintendo Wii auszuführen
- Für die Wii gab es bereits Portierungen von Betriebssystemen wie Linux, NetBSD und Windows NT; nun kommt Mac OS X hinzu
- Unter Nutzung der PowerPC-basierten Hardware der Wii wurde der Darwin/XNU-Kernel zum Laufen gebracht, während die nötigen Treiber und der Bootloader direkt selbst geschrieben wurden
- Das Ergebnis: ein vollständiger Start der Mac-OS-X-GUI-Umgebung auf der Wii, inklusive Unterstützung für Tastatur- und Mauseingaben
Untersuchung der Machbarkeit
- Die PowerPC-750CL-CPU der Wii ist der Nachfolger des PowerPC 750CXe, der in G3-iMacs und -iBooks verwendet wurde, daher bestehen keine CPU-Kompatibilitätsprobleme
- Die 88 MB RAM der Wii (MEM1 24 MB + MEM2 64 MB) liegen zwar unter den offiziellen Anforderungen von 128 MB, aber QEMU-Tests bestätigten, dass ein Start auch mit 64 MB möglich ist
- Unterstützte Hardware umfasst USB Gecko (serielles Debugging), SD-Karte, Interrupt-Controller, Framebuffer-Videoausgabe und USB-Ports
- Wird der Open-Source-Kern von Mac OS X, Darwin (XNU-Kernel, IOKit), an die Wii angepasst, kann auch die darüberliegende GUI-Schicht funktionieren
- Die Wii eignet sich für Portierungsexperimente, da sie über Homebrew Channel und BootMii die Ausführung eigenen Codes erlaubt
Portierungsansatz
- Auswahl zwischen drei Boot-Strategien:
- Open-Firmware-Portierung
- BootX-Portierung
- Direktes Schreiben eines eigenen Bootloaders
- Es wurde ein neuer Wii-spezifischer Bootloader geschrieben, der Hardware initialisiert, den Kernel lädt, den Device Tree erzeugt und die Kontrolle an den Kernel übergibt
- Nach dem Start des Kernels wurde der Bootloader-Code überflüssig; die weiteren Arbeiten konzentrierten sich dann auf Kernel-Patches und das Schreiben von Treibern
Schreiben des Bootloaders
- Auf Basis des Beispielcodes ppcskel wurden Wii-Initialisierung sowie Funktionen für SD-Karte, Framebuffer und USB-Debugging implementiert
- Der XNU-Kernel im Mach-O-Format wurde in den Speicher geladen und durch Sprung zum angegebenen Entry Point ausgeführt
- Um die Kernel-Ausführung zu prüfen, wurde ein LED-Blink-Patch eingefügt, um den Eintritt in den Kernel nachzuverfolgen
- Durch Rückverfolgung des Kernel-Ausführungspfads wurde festgestellt, dass in der Phase device_tree.c eine 300-Ausnahme auftrat → daraus wurde die Notwendigkeit der Übergabe eines Device Tree erkannt
-
Erzeugung und Übergabe des Device Tree
- Auf Basis der festen Hardware-Struktur der Wii wurde ein hartkodierter Minimalbaum mit (
/cpus,/memory) aufgebaut - In die Struktur
boot_argswurde ein Zeiger auf den Device Tree aufgenommen und an den Kernel übergeben - Danach erkannte der Kernel den Baum korrekt und der Bootvorgang lief weiter
- Auf Basis der festen Hardware-Struktur der Wii wurde ein hartkodierter Minimalbaum mit (
Kernel-Patches
- Die BAT-(Block Address Translation)-Einstellungen von XNU kollidierten mit dem Speicherlayout der Wii, weshalb Änderungen am Kernel-Quellcode nötig waren
- In einer Mac-OS-X-Cheetah-Gastumgebung (QEMU) wurde ein Build-System für den Kernel eingerichtet
- Durch BAT-Anpassungen und eine Umleitung der Konsolenausgabe auf USB Gecko wurde Debugging möglich
- Danach wurden virtueller Speicher, IOKit und das BSD-Subsystem korrekt initialisiert
- Im Boot-Log erschien die Meldung „Still waiting for root device“ → damit war klar, dass ein SD-Karten-Treiber benötigt wird
Schreiben der Treiber
-
Verständnis der IOKit-Struktur
- IOKit ist ein C++-basiertes Framework für Kernel-Erweiterungen, das Hardware-Schichten über eine Treiber-Nub-Struktur darstellt
- Beispiel:
IOPCIBridge→IOPCIDevice→SomeEthernetCard→IOEthernetInterface - Da die Wii keinen PCI-Bus, sondern eine SoC-Struktur (Hollywood) nutzt, war ein eigener Treiber als Ersatz für IOPCIFamily nötig
-
Hollywood-Treiber
- Der Treiber
NintendoWiiHollywoodwurde geschrieben und mit dem „hollywood“-Knoten im Device Tree abgeglichen - Er erstellt und registriert das Nub
NintendoWiiHollywoodDevice, das die untergeordnete Hardware repräsentiert - Dadurch können Treiber für untergeordnete Geräte wie die SD-Karte angebunden werden
- Der Treiber
-
SD-Karten-Treiber
- Durch Ableitung von
IOBlockStorageDevicewurde der Zugriff auf die Wii-SD-Karte implementiert - Die Kommunikation mit der SD-Karte erfolgt über IPC-Befehle (
IPC_SDMMC_SIZE,READ,WRITE) von MINI (dem Starlet-Coprozessor) - Zur Behebung von Problemen mit gecachtem Speicher wurden nicht gecachte Speicherpuffer verwendet
- Erfolgreich wurde ein
IOMedia-Nub erzeugt, wodurch das Root-Dateisystem erkannt und ein vollständiger Boot möglich wurde - Im Boot-Log wurde
BSD root: disk0s4bestätigt
- Durch Ableitung von
-
Framebuffer-Treiber
- Durch Ableitung von
IOFramebufferwurde der MEM1-Bereich (0x01700000) der Wii als Framebuffer festgelegt - Für den Wechsel zwischen anfänglicher Textkonsole und GUI gibt
isConsoleDevice()den Werttruezurück - Da die Video-Hardware der Wii das YUV-Format nutzt, wurde ein doppelter Framebuffer zur RGB→YUV-Konvertierung implementiert
- Über eine Konvertierungsschleife wurde die Farbumwandlung mit 60 Hz durchgeführt → korrekte GUI-Ausgabe in den richtigen Farben gelang
- Durch Ableitung von
-
USB-Eingabeunterstützung
- Um den OHCI-USB-1.1-Controller der Wii anzusteuern, wurde der Einsatz von
AppleUSBOHCIversucht - Problem 1: fehlender IOUSBFamily-Quellcode, daher war Debugging zunächst unmöglich
- Problem 2: Abhängigkeit von
IOPCIDevice, daher wurde für die Wii ein PlatzhalterNintendoWiiHollywoodPCIDevicegeschrieben - Problem 3: Endianness-Konflikt (die Wii nutzt reversed-little-endian), daher musste das softwareseitige Byte-Swapping entfernt werden
- Über IRC wurde schließlich der IOUSBFamily-Quellcode für Mac OS X Cheetah beschafft; danach gelangen Anpassung und Build
- Im Ergebnis funktionierten USB-Tastatur und -Maus, wodurch die Wii als vollständiges Mac-OS-X-System nutzbar wurde
- Um den OHCI-USB-1.1-Controller der Wii anzusteuern, wurde der Einsatz von
Verbesserungen an Bootloader und Kernel
-
Verbesserungen am Bootloader
- Suche nach SD-Karten-Partitionen und ein Boot-Menü wurden ergänzt, ebenso die Implementierung des Apple Partition Map (APM)-Parsings
- Kernel-Erweiterungen (kexts) wurden im Bootloader geladen und im Knoten
/chosen/memory-mapregistriert - Dadurch wurde der Start mit einem unveränderten Mac-OS-X-Installations-Image möglich
-
Vereinfachung des Kernels
- Die Wii-spezifischen Kernel-Anpassungen wurden auf ein Minimum reduziert:
- Anpassung der BAT-Einstellungen
- Erkennung von I/O-Adressen auf Basis des „hollywood“-Knotens
- Behebung der Cache-Konsistenz des Framebuffers
- Durch die Auslagerung der Treiber aus dem Kernel verbesserten sich Build-Effizienz und Wartbarkeit
Abschluss
- Ein Projekt, das während der Studienzeit 2013 konzipiert wurde, wurde nach über zehn Jahren vollendet
- Die Herausforderung war von einem Windows-NT-Port auf die Wii inspiriert
- Am Ende wurde ein vollständiger Start von Mac OS X 10.0 samt GUI-Bedienung auf der Wii erreicht
- Hervorgehoben wird die Lehre: Je unmöglicher ein Projekt erscheint, desto lohnender ist es, es anzugehen
3 Kommentare
Ein köstlicher Beitrag und ein großartiger Autor dazu….
Von Verrückten unter den Verrückten sind es wohl die westlichen Nerds..
Hacker-News-Kommentare
Dieses Projekt war wirklich erstaunliche Arbeit. Auch der Artikel selbst war so fesselnd, dass ich bis zum Ende drangeblieben bin
Besonders der Teil „WindowServer hat sich beschwert, und um das zu beheben, musste ich den Framebuffer-Treiber selbst schreiben“ ist mir im Gedächtnis geblieben
Ich war überrascht zu sehen, dass die I/O-Kit-Abstraktionsschicht von MacOS tatsächlich genau das tut, was sie soll. Applaus für die NeXT-Entwickler
Ich habe keine Erfahrung mit Treiberentwicklung auf anderen Plattformen, daher fällt mir ein Vergleich schwer, aber strukturell wirkte es ziemlich attraktiv
Früher haben NetBSD-Entwickler PPC Darwin auf einer Mach/IOKit-Kompatibilitätsschicht zum Laufen gebracht und sogar Xquartz gestartet. Dass NetBSD die IOKit-Aufrufe übersetzt hat, finde ich spannend
Ich kann immer noch kaum glauben, wie viele Betriebssysteme auf der Wii laufen
Eigentlich hängt der Unterschied zwischen guter und schlechter Abstraktion davon ab, wie gut sie erklärt wird
Die Ingenieursleistung an sich ist schon beeindruckend, aber dass der Autor in der Economy Class entwickelt hat, war wirklich bemerkenswert
(Nach erneutem Hinsehen war das erste Foto ein Bus, das zweite ein Flugzeug)
Als Autor des NetBSD-Ports für Wii und Wii U gratuliere ich von Herzen zu diesem Projekt
Ich freue mich darauf zu sehen, welche Probleme als Nächstes wie gelöst werden
Früher war ich selbst ein Hardcore-Mac-Fan und habe per Reverse Engineering sogar frühe inoffizielle „iOS-Apps“ gebaut
Aber dieses Projekt übertrifft das alles. Schon MacOS auf einer Wii laufen zu lassen ist erstaunlich, aber der Artikel selbst ist auch noch so präzise und spannend
Heute habe ich zum ersten Mal erfahren, dass die Wii nur 88 MB RAM hat. Zum Glück bestehen Spiele nicht aus Elektronen
Die Mindestanforderung von Vista lag bei 512 MB, aber die meisten PCs hatten weniger Speicher als das
Wenn man sieht, dass heute 8 GB verschwinden und 16 GB zum Standard werden, merkt man, wie sehr sich die Welt verändert hat
Bevor ich mit dem Projekt angefangen habe, wollte ich erst prüfen: „Ist das überhaupt möglich?“ Dann fand ich einen Reddit-Kommentar von 2021, der von „0 % Wahrscheinlichkeit“ sprach
Das hat mich eher motiviert. Also habe ich angefangen, die Hardware der Wii zu analysieren. Wirklich urkomisch
Menschen erklären Dinge, die nur fast unmöglich sind, kurzerhand für völlig ausgeschlossen und halten sich dabei für prinzipientreue Skeptiker
Da dachte ich: „Wirklich?“ und habe den UART-Port umkonfiguriert und ein ESP32 angeschlossen
Das Problem ist, dass es als Konzept keinen Platz für ahnungslosen Zynismus zu geben scheint
Beim Debuggen eines Kernel Panic auf der Wii in der Economy Class eines Flugzeugs zu sitzen – dieses Niveau an Konzentration kann ich mir kaum vorstellen
Die meisten schaffen es im Flugzeug kaum, ein einziges Buch zu lesen
Wirklich ein großartiges Projekt. Es erinnert an das frühere goldene Zeitalter der Low-Level-Entwicklung
Damals war es leicht, VGA zu initialisieren und Pixel zu setzen, und auch Chips wie der 6502 waren gut zugänglich
Heute sind Systeme aber so komplex geworden, dass die Einstiegshürde hoch ist
Dazu kommt, dass KI so tut, als würde sie Entwicklung vereinfachen, dabei aber die Zugänglichkeit weiter verringert
Ich versuche ebenfalls, Mac OS 9 auf die Wii U zu portieren
Dieses Projekt hat mich tief beeindruckt, und immer wenn ich denke, „das ist unmöglich“, gibt es mir neuen Mut
Der Artikel war großartig, aber die Einbindung des
.mov-Videos per<video>-Tag hat ein Problem mit der Browser-KompatibilitätIn Chrome oder Firefox wird es nicht abgespielt