I’ve spent a great deal of the last month reverse-engineering everything around the Wii VC on the Wii U. My main goal was to make it possible to play Wii Games (and Homebrew) using the GamePad as the controller. Now, I’m gonna try to summarise what I know, so that maybe others can learn something of it and maybe this will help clear up some confusion.
DISCLAIMER: Everything you read in this article is what I personally believe is happening. Since reverse-engineering is basically guesswork at some points, I can be wrong about pretty much everything. If you do find some mistakes, please, tell me in the comments.
So let’s dive into it!
This is the least interesting part of the whole Wii VC. It just displays the fancy banner on boot and takes care of showing the manual. Note that this binary doesn’t even do the “This game supports the GamePad” prompt – the Wii U menu does that (based on the meta.xml), and just calls CMPTAcctSetDrcCtrlEnabled with the result, but more on that in nn_cmpt.rpl section. For all the rest, it calls the included nn_hai_user.rpl library.
Now first, let me make something clear. Hai is the most used codename around all the Wii Virtual Console stuff. Actually, it is used in so many places, that I will be differentiating between the various parts it consists of.
This library loads all the /vol/content/hif_XXXXXX.nfs files, merging them one after another. It also does some basic checks on them (like correct length and padding), and asks the MCP to store them to a Hai Companion File, which MCP stores at /vol/compat_slc/shared2/sys/hai/imginf.bin. So, after this library is done with its job, the imginf.bin should be the nfs files merged (needs confirmation). It then calls the first system library nn_hai.rpl.
This library also doesn’t do a hell lot work – basically it just makes sure your Wii VC games will be in the daily log. For the rest, it calls nn_cmpt.rpl, another system library.
This is the most important library of them all. It has all the exports that allow you to launch vWii mode. What’s interesting is that there are two ways of launching it – through ‘old’ calls and through ‘Ex’ calls. They are similiar in some ways, but different in others (needs more research, sorry). This one prepares a complete configuration file for the MCP – what video output should the vWii use, what it should it load when it starts (Menu/DataManagement/a custom title/a dol file?), what will its nickname and internet settings be etc. This is the library that is also called when you just launch Wii Menu from the Wii U Menu, while everything we had so far was Hai-specific.
Now let’s transfer from the PPC to ARM, and let’s go to MCP.
The MCP (a kernel module, /dev/mcp) takes care of all the steps remaining before the Wii U can be rebooted and become a Wii. It supports three different types of launching (defined at 0x050623C0), and loads files according to that:
- ‘Regular’ launch: Loads just OSv0’s c2w.img and font.bin
- ‘Dol’ launch: Loads OSv0’s c2w.img and font.bin and then a mystical fw.img, boot.bin and App.dol. This doesn’t seem used anywhere, and I haven’t played with it.
- ‘Hai’ launch: Loads OSv1‘s c2w.img and boot.bin, OSv0’s font.bin, and /vol/system_ram/es/fw.img.
Also, if it is in hai mode, it prepares so called “Hai params”, and stores them at 0x402000. These Hai params also contain a setting if the GamePad should be used. They also contain the key read from htk.bin and some other stuff. After everything is set in its proper place, it reboots the Wii U.
Now I’ve seen a lot of confusion about this (and also OSv0). This is just a bootloader. It doesn’t do any gamepad magic. There’s no “running games using OSv1”. OSv0 and OSv1 both just set up some hardware, move stuff a bit around in the memory, and then jump to code that was prepared by the MCP. What’s the difference between OSv0 and OSv1? The OSv1 checks 0x402000. If it finds the letters “Hai” there, it recognises the Hai params, and copies them to 0xFFFFF000, where the Hai IOS can later see it. It also sets up some hardware a bit differently (MCP_HWSetCompatMode).
Hai IOS (a.k.a. the fw.img)
Now this is the most integral part of everything. It is a full-blown IOS, just written for the Wii VC specifically. There are several versions included in various Wii VC releases (I know about three), but they are all universal. As in, there are just updates of the same thing. It consists of several modules, but there are two main interesting ones: OHCI1 and DI2SD.
OHCI1 emulates the WiiMote when gamepad controls are enabled. It reads data coming from the GamePad (over a special I2C bus), and converts them to simulated bluetooth messages. This code can be easily modified to emulate things different than the Classic Controller (Proof of Concept).
DI2SD is what it says: it emulates the disc interface. Even though it has “2SD” in its name, it seems it can load data from pretty much everywhere. This is where the EGGS header is parsed. This is where decryption takes place.
I hope this article helps to clear up some of the confusion around Hai! 🙂