Wii Linux on Kernel 4.4 SLTS, Part 1

Ah, the Wii. Officially now a retro console (the Wii is as old as the Super Nintendo was when the Wii came out), it’s time to dig it out of the closest and do something incredibly stupid with it. Because that’s just how I roll.

The Wii probably has the single greatest homebrew programming scene ever devised. A veritable buffet of extremely well-made homebrew applications have come out for the Wii since the heyday of Wii hacking back in the early 2010s. It is still a massively popular homebrew platform and has some of the most impressive homebrew ever still being made today. And it has probably the best emulator ever made. Impressive little thing for what is essentially an overclocked GameCube with more I/O!

However I, being the intensely boring person I am, decided simply to try and get a modern version of Linux running on the Wii. I’ve been fanagaling kernel patches for almost a decade at this point, so it can’t be too awful, right? Well, yes and no.

The Wii’s kernel patches are very crusty. Most of them are 2.6-era and quite a few don’t even compile. Fewer still actually work. However, someone already patched up the kernel to a booting state (with USB!) on 4.3 so patching up to 4.4 shouldn’t be the hardest thing in the world.

So let’s get started.

Getting the kernel up to date #

This was mostly git magic over a few days. In the end I used git diff to get all the changes between the patches made by neagix and the stock 4.3 kernel. Then I grabbed the latest CIP kernel and git applied them. I had to force it through and then manually edit some rejects, but overall it mostly just worked.

Then came the annoying part: getting a kernel config. Apparently everyone else who did this before me thought an appropriate way to handle all of this is to have a shell script in a repo that summons a config from a place I’m not sure exists and have that build the system. Trying to dig up a working config was an exercise in frustration until I found some fork that left their config in. It was for Kernel 3.7 but make olddefconfig mostly sorted that out. Then the Linux kernel was just a make away. Except for the fact that the Wii is PowerPC so I needed to grab a cross-compiler. And the latest binary version of crosstools-ng is broken. I just compiled crosstools from source, mildly irritated at this point, and then started compiling.

The cruft caught up though, the SD driver wouldn’t compile, so I had to disable it. A few functions were moved into different header files, easy fix. A function or two was deprecated, no problem. And within about three hours I had a fully working kernel on the Wii!

Booting up! #

And then I tried to load it under BootMii. And it died instantly. Turns out between 4.3 and 4.4 some breaking change happened which prevents the framebuffer from working under BootMii.

There is another way, to load the kernel from the homebrew channel, but that’s less desirable because of the Wii’s architecture. All code on the Wii runs on the PowerPC at ring0. There is absolutely zero control as to what a game can do on the PowerPC. However, the Wii has a pretty robust security model, so what gives? Time for a basic rundown of Wii security.

The Wii has a second second coprocessor built into the GPU. Old Wii hacker convention is to call it the “Starlet”, because it’s inside the Hollywood GPU. The Starlet handles all I/O that makes a Wii a Wii, including USB, NAND, Bluetooth, Wireless networking, and a bit more. Without the Starlet, the Wii is essentially a fast GameCube. Even the power buttons are routed through the Starlet!

So how does the PowerPC access any of the hardware? A small operating system called IOS resides on the Starlet. It’s entirely custom and exposes interfaces with a permissions system enforced in a small part of every application called the TMD. All TMDs have to be signed by Nintendo at install time. Or at least, they should be. The Starlet handles all I/O on the Wii (at least in normal cases).

Now there is a workaround. In 2009 Team Twiizers/fail0verflow found that a TMD access rights bit set correctly simply disables all access controls and allows the PowerPC to communicate with the hardware as if the Starlet wasn’t there. This would be fantastic news and make everything work all lovely, except the patches are six months older than this discovery.

Before this workaround was discovered, Team Twiizers/fail0verflow wrote a custom OS for the Starlet called MINI (MINI is not IOS). MINI has a different API and essentially just proxies requests to hardware for the PowerPC also with absolutely no restrictions.

When booting from BootMii, the Starlet is running MINI. Since, at the time these patches were written, MINI gave more granular control of the hardware, most of the more interesting hardware (WiFi, DVD drive, USB 2.0) only works under MINI! Meanwhile, the IOS SDCard driver is broken for several reasons, most of which being an API shift in the Linux kernel that broke the driver.

I decided to concede and get a booting kernel as opposed to no booting kernel, and recompiled the kernel for IOS support. I then loaded it under HBC and…

it worked! Loading Gentoo PPC off of USB 1.1 worked and I was then dropped to a terminal! uname

Fixing the drivers #

So far, the only driver that I’ve gotten the system to boot with enabled is the SD Card driver. The results are, well, rather unimpressive. As in the system immediately hangs when any operation is performed on it. The driver is designed to use IOS calls, but these are unnecessary now because of the previously mentioned TMD access rights bit. However this does mean one thing: the drivers will have to be rewritten. And I have no debugger.

Loading the kernel in the excellent Dolphin emulator does not work. Old Wii homebrew debuggers are expensive and use chips all currently out of stock.

However, I am working on building a debugger, using a Raspberry Pi Pico. May G-d have mercy on all of us from my soldering

To be continued…