· 6 min read ·

The PowerPC Thread That Connects Mac OS X and a Nintendo Wii

Source: hackernews

When Bryan Keller published his writeup of porting Mac OS X to the Nintendo Wii, the Hacker News thread filled with the usual mix of disbelief and nostalgia. The project sounds like a joke until you look at the hardware, at which point it becomes a genuinely interesting systems engineering problem with a surprisingly clean starting point.

The starting point is PowerPC.

Why the ISA Match Matters

Mac OS X ran on PowerPC from version 10.0 (Cheetah, 2001) through 10.5 (Leopard, 2007). Every release in that span compiled to big-endian 32-bit PowerPC machine code. The Nintendo Wii shipped in 2006 with a CPU called Broadway, an IBM PowerPC 750CL running at 729 MHz. The 750CL is a direct descendant of the G3 line. It runs the same ISA.

This means the Mac OS X kernel binary, compiled for PowerPC, can execute instructions on Broadway without a recompilation step. The same applies to most of the userland. When people port Linux to exotic hardware, they often start by cross-compiling the kernel for the target architecture. Here, the architecture is already correct. The kernel binary that ships on a PowerPC Mac installation DVD is, at the instruction level, valid code for a Wii.

That is where the easy part ends.

What Mac OS X’s PowerPC Layer Actually Assumes

XNU, the kernel underlying Mac OS X, is a hybrid of Mach and BSD. Its portability story is real but narrow. The architecture-independent core handles scheduling, virtual memory, and syscall dispatch. Everything touching hardware goes through IOKit, Apple’s object-oriented driver framework, and through what Apple called the Platform Expert: a set of kernel extensions that enumerate hardware and tell the rest of the system what exists.

On PowerPC Macs, the Platform Expert relied on Open Firmware, the IEEE 1275 standard that Apple used on every PowerPC machine. Open Firmware runs before the OS and builds a device tree describing the hardware. XNU reads that tree and loads drivers accordingly. The Platform Expert for PowerPC Macs (AppleMacRISC2PE for G4 machines, AppleMacRISC4PE for G5) is written explicitly for Apple’s hardware enumeration scheme.

The Wii has no Open Firmware. It has a layered proprietary boot chain: a mask ROM (boot0) hands off to boot1 in NAND flash, which verifies and launches boot2, which loads one of Nintendo’s IOS firmware images, which finally brings up the System Menu. None of this is Open Firmware. None of it produces a device tree XNU can consume. Before the OS can even begin to enumerate hardware, someone has to write a shim that either generates a synthetic device tree or replaces the Platform Expert entirely.

This is the first real obstacle, and it is substantial.

The Starlet Problem

Wii hardware has a second CPU that most people forget about. Nintendo embedded an ARM926EJ-S core running at 243 MHz, called Starlet, as a security and I/O coprocessor. Starlet controls essentially every peripheral: the SD card slot, USB ports, Bluetooth (and therefore the Wiimotes), the NAND flash, the DVD drive, the AES and SHA engines, and the GPIO pins. The main Broadway CPU cannot directly address most of these peripherals. It communicates with Starlet through an IPC mechanism using a pair of mailbox registers and a shared memory region.

This architecture was Nintendo’s way of isolating the security-sensitive firmware from game code running on the main CPU. It worked well enough for its intended purpose. For an OS port, it means that every driver you write for conventional hardware is actually a driver that speaks Nintendo’s IPC protocol to Starlet, which then touches the real hardware. There is no direct memory-mapped register access to the SD controller or the USB host. The HAL layer has an extra indirection that does not exist on any Mac Apple ever shipped.

The WiiBrew community documented the IPC protocol thoroughly over years of reverse engineering, so the information exists. Implementing it inside IOKit drivers is a different matter.

Memory Is the Other Wall

The Wii ships with 24 MB of fast 1T-SRAM (MEM1) and 64 MB of GDDR3 (MEM2), totaling 88 MB. The GPU has access to MEM1 for display lists; the main CPU primarily uses MEM2 for general work, though both regions are addressable from software.

Mac OS X 10.3 Panther officially required 128 MB. Tiger required 256 MB recommended, though it would limp along with 128 MB. Leopard required 512 MB for a comfortable experience. Running the full Aqua desktop on 88 MB is not viable. Running the XNU kernel and a minimal BSD userland is a different question. The kernel itself has run in constrained environments; the question is how much of the OS stack you strip before the result is still recognizably Mac OS X rather than a headless Darwin build.

For comparison, Wii Linux exists and has run reasonably well since around 2008. Linux’s memory footprint in a stripped configuration is more flexible than XNU’s, partly because IOKit carries more overhead than a conventional Linux driver model and partly because Mach’s virtual memory machinery has non-trivial baseline costs. The Wii Linux project also had the advantage of the Linux kernel’s existing PowerPC support tree, including drivers written for embedded PowerPC boards that share some characteristics with Broadway.

The Boot Path the Community Already Opened

The Wii homebrew ecosystem provided the tooling that makes any of this approachable. BootMii installs as boot2, giving the ability to boot arbitrary code before Nintendo’s IOS loads. The MINI bootloader is a small open-source replacement for IOS that initializes hardware directly rather than going through Nintendo’s firmware. It speaks to Starlet through a reimplemented IPC layer and exposes a cleaner environment for custom kernels.

Running XNU via MINI means MINI handles early hardware init, Starlet communication, and memory setup, then transfers control to the XNU entry point with whatever minimal device tree the port synthesizes. This is the same general pattern Wii Linux uses. The devkitPPC toolchain, which the Wii homebrew community built for compiling PowerPC code targeting the Wii’s runtime environment, provides the cross-compilation infrastructure.

What This Port Joins

Ports like this one sit in a tradition of running operating systems on hardware their designers never intended. The PureDarwin project spent years trying to build a bootable Darwin system from Apple’s open-source releases, establishing much of the knowledge base about what XNU needs to start on non-Apple hardware. Running Darwin on non-Apple PowerPC machines was an active area of experimentation in the early 2000s, when Apple’s open-source drops were more complete.

The Wii port is different in that the target hardware is a consumer games console with a mature homebrew community, a well-documented memory map, and a known-good path to booting custom code. That changes the feasibility calculation substantially. The ISA match removes the cross-architecture porting work entirely. The homebrew toolchain provides the build infrastructure. The WiiBrew documentation covers the hardware. What remains is the Platform Expert rewrite, the Starlet IPC driver layer, and the memory pressure problem.

None of those are small problems. But they are defined problems, which is what separates an ambitious weekend project from an open-ended research effort. Keller’s writeup is worth reading for the specific decisions made at each layer, and the Hacker News thread surfaces a number of edge cases around the Hollywood GPU (an ATI-derived custom chip with no Mac OS X driver) and the practical limits of the display subsystem.

The result probably does not run Leopard’s Aqua desktop at a usable frame rate on 88 MB of RAM. It probably does not need to. Getting XNU to boot, mount a filesystem, and reach a shell on hardware this constrained is the kind of project that teaches you more about operating system structure than any textbook, because every assumption the OS makes becomes a concrete engineering problem the moment the hardware stops sharing those assumptions.

Was this interesting?