When Bryan Keller posted about porting Mac OS X to the Nintendo Wii, the Hacker News thread it spawned filled quickly with variations of “wait, that should not work.” The instinct makes sense: the Wii is a game console from 2006 with 88 MB of RAM and no graphics stack recognizable to macOS. But the instinct misses a crucial historical coincidence. From roughly 1994 to 2006, Apple’s computers ran on PowerPC processors. The Wii, released in the final months of that same era, also runs on a PowerPC processor. The intersection of those two timelines is what makes this project coherent rather than absurd.
The Broadway Chip and Its Ancestors
The Wii’s CPU is the IBM Broadway, running at 729 MHz. It is not a novel design. Broadway is a die-shrunk, slightly modified version of the GameCube’s Gekko processor, which itself is a customized IBM 750CL, which is a G3-class chip. The IBM 750 was the processor in the original iMac, the iBook, and the early PowerBook G3 machines. When Apple shipped Mac OS X 10.0 on a first-generation iMac in 2001, the processor executing that kernel was architecturally the same family as the one inside every Wii sold through 2013.
The differences matter but they are manageable. Gekko and Broadway add a non-standard floating point extension called “paired singles” (PS), which packs two 32-bit floats into a single 64-bit register and operates on both simultaneously. This is not part of the PowerPC ISA that Apple’s compilers or Darwin’s kernel targeted. It is a Nintendo-specific addition used in game and graphics code. For an OS port, paired-singles are irrelevant as long as the kernel avoids them, which it will, because it was never compiled to use them.
Broadway is a 32-bit, big-endian, in-order PowerPC core. The Mac OS X PowerPC kernel was compiled for a 32-bit, big-endian, in-order PowerPC architecture. The instruction sets are compatible. Binary code compiled for a G3 will execute on Broadway without modification.
Darwin: The Publicly Available Starting Point
Mac OS X is not entirely proprietary. Apple has released Darwin, the open-source foundation of the OS, since 2000. Darwin includes XNU (the kernel), the BSD userland utilities, libdispatch, launchd, and the core POSIX layer. What it does not include are the proprietary frameworks (AppKit, CoreGraphics, Metal, and similar), the graphics drivers, and much of the system software that makes macOS recognizable as macOS.
For the purpose of a hardware port, Darwin is exactly the right starting point. XNU itself is the object of interest. Its source is available on Apple’s open source portal, and the PowerPC build path was maintained through Darwin 9.x, which corresponds to Mac OS X 10.5 Leopard. That is the last Mac OS X release that officially ran on PowerPC hardware, and its kernel compiles cleanly for PPC targets with the right toolchain.
XNU uses a microkernel-influenced design layered on top of Mach. The kernel proper handles process management, virtual memory, IPC, and scheduling. IOKit, the device driver framework, sits on top and provides the hardware abstraction layer. Platform-specific code lives in osfmk/ppc/ for the PowerPC architecture. That code covers context switching, exception handling, interrupt delivery, and the low-level startup sequence that prepares the CPU before main() is reached.
The early boot sequence on PowerPC Darwin follows this path: the bootloader loads the kernel image, sets up a minimal page table, and jumps to _start in osfmk/ppc/start.s. From there the kernel initializes the Mach virtual memory system, scans the Open Firmware device tree to discover hardware, and eventually calls machine_startup() which hands off to the Mach scheduler.
The Memory Problem
The Wii has 24 MB of MEM1 (GameCube-compatible, accessible to the GPU) and 64 MB of MEM2 (Wii-specific, higher latency for the CPU), for a total of 88 MB. The minimum RAM requirement for Mac OS X 10.4 Tiger is 256 MB. Leopard requires the same. Running a full macOS userland on 88 MB is not possible in any practical sense.
What is possible is booting the kernel and running a minimal environment. XNU’s memory footprint at boot, before any userland processes start, is measured in single-digit megabytes. The kernel image itself for a stripped-down PPC build sits around 4 to 6 MB. Adding the RAM disk (the compressed filesystem image used for early boot), the kernel’s heap, and the page tables, you can reach a kernel prompt with 20 to 30 MB consumed. That fits.
The constraint forces the same decisions that embedded Linux ports routinely make: no swap, no graphics compositor, no Aqua, no GUI services. What you can get is the XNU kernel running, a BSD userland from Darwin’s shell utilities, and a command prompt over a serial connection or a framebuffer terminal. For a project whose goal is demonstrating that the kernel boots on foreign hardware, that is sufficient.
IOKit and the Hardware Abstraction Gap
The harder problem is not the CPU. The harder problem is everything attached to the CPU. Mac OS X discovers hardware through a combination of Open Firmware device trees (on PPC) and IOKit driver matching. The Wii does not have Open Firmware. It has IOS, Nintendo’s proprietary firmware running on a separate ARM processor called the Starlet (an ARM926EJ-S), which handles I/O including USB, SD card, Wi-Fi, and the disc drive. The Broadway CPU sees the Starlet through a shared memory region and an interrupt line.
The Wii’s GPU, called Hollywood, is a custom design with no public documentation and no IOKit driver. It is not OpenGL. It is not anything Apple’s graphics stack would recognize. The homebrew community documented its GX API through reverse engineering over years of effort, primarily in the libogc library, which provides a C interface to the hardware. Nothing in that API resembles what CoreGraphics or WindowServer would expect.
A port that gets XNU booting needs to solve these problems in order:
- Replace the Open Firmware device tree with a hand-crafted property list that describes the Wii’s actual hardware to the kernel.
- Write a minimal Platform Expert, the IOKit class that bootstraps hardware discovery, for the Wii.
- Stub or replace drivers for hardware that does not exist on the Wii (ATA controllers, USB-PCI bridges, AGP buses).
- Write at minimum a console driver that can output text, either to a framebuffer or a serial port.
The Wii does have a serial port on its EXI (external interface) bus, the same bus the GameCube used for its memory cards and the broadband adapter. Homebrew developers have been using EXI-based serial output for debugging since the GameCube era. A framebuffer console is also possible because the Hollywood GPU, despite its complexity, can be put into a simple mode that outputs a raw pixel buffer to the component video output. Libogc handles this, and a Darwin platform driver borrowing that technique could give the kernel a display without implementing GX.
Prior Art in the Wii Homebrew Ecosystem
This kind of work has precedent. Marcan (Héctor Martín) ported Linux to the Wii in the late 2000s, culminating in a working Debian environment with Wi-Fi support. That port required solving almost all of the same problems: no Open Firmware, IOS-mediated I/O, the Hollywood framebuffer, and the memory split between MEM1 and MEM2. The Linux port worked around the IOS problem by running alongside IOS rather than replacing it, using IOS’s own IPC mechanisms to reach the hardware the Starlet controlled.
NetBSD ran on the GameCube through a similar effort. The GameCube port of NetBSD bootstrapped from a clean kernel with a minimal machine-dependent layer targeting the Flipper GPU (Hollywood’s predecessor) and the Gekko CPU. The port demonstrated that getting a BSD-derived kernel running on Nintendo hardware is a tractable project for a determined engineer, even without Nintendo’s cooperation or documentation.
Darwin itself has been ported to unusual hardware before. Before Apple announced the Intel transition in 2005, Darwin for x86 had been available for years as an open-source curiosity. That port served as the foundation for early Hackintosh work, though the user-facing Mac OS X frameworks were never part of Darwin’s open-source releases.
What the Bootloader Looks Like
On stock Wii hardware running homebrew, the execution environment is provided by the Homebrew Channel, which loads ELF binaries from an SD card. The homebrew loader sets up a minimal C runtime, initializes MEM1 and MEM2, and jumps to the loaded binary’s entry point. It does not provide anything resembling Open Firmware or a standard PPC boot environment.
A Darwin port on this hardware needs a thin shim between what the Homebrew Channel provides and what XNU expects. XNU’s PPC startup code assumes certain machine registers contain specific values, assumes a page table is set up in a particular way, and assumes the boot arguments structure (a boot_args_legacy on older XNU) is located at a known address with valid fields.
That shim would look roughly like this:
/* Minimal Wii Darwin boot shim */
void wii_darwin_start(void) {
/* Initialize MEM2 - XNU will want the full address space */
SYS_Init();
/* Build a synthetic boot_args structure */
boot_args_legacy args = {
.Revision = kBootArgsVersion,
.machineType = 0, /* placeholder */
.memSize = 88 * 1024 * 1024,
.topOfKernelData = (uint32_t)kernel_end,
.Video = {
.v_baseAddr = (uint32_t)framebuffer,
.v_rowBytes = 640 * 4,
.v_width = 640,
.v_height = 480,
.v_depth = 32,
},
};
/* Disable interrupts, set up BAT registers, jump to XNU */
_xnu_entry(&args);
}
The actual implementation will be more involved because XNU’s PPC startup code is careful about which BAT (Block Address Translation) registers are configured and which regions of memory are mapped before the virtual memory system initializes. Getting those wrong produces a machine check exception immediately, and machine check exceptions before the exception handlers are installed are fatal.
Why This Is Interesting Beyond the Novelty
Projects like this are frequently dismissed as pointless, and in a strict practical sense they are. Nobody is going to run Mac OS X on their Wii as a daily computing environment. But the value of a port like this is architectural: it reveals, precisely, what makes an OS specific to its native hardware.
Every assumption Darwin makes about its runtime environment becomes visible the moment those assumptions are violated. The Open Firmware requirement, the memory layout, the IOKit driver model, the specific exception vectors the kernel registers, the way the bootloader negotiates with firmware: all of these are documented most clearly by an engineer who had to replace each one.
The Wii port also serves as a time capsule. The last PPC Macs shipped in 2006. The last PPC-capable Mac OS X shipped in 2007. Darwin’s PPC build paths have not been a priority for Apple since then, and they have bitrotted accordingly. Getting the XNU PPC port to compile and boot on any hardware in 2026, even the Wii, is a preservation effort for a codebase that is otherwise sliding toward unmaintainability.
There is a lineage worth tracing here: the PowerPC 750 in the original iMac G3, the Gekko derivative in the GameCube, the Broadway refinement in the Wii, and the Mac OS X kernel that ran on that same processor family for the first six years of its life. The Wii is not a Mac. But it is close enough to one, in the narrow sense that matters for kernel bringup, that the port is possible. That is the interesting part.