Notes from inside your Wii

HackMii header image 2

of TMDs and hardware

August 20th, 2009 by bushing · 29 Comments

Most of you probably remember our infamous attempt to open a line of communication with Nintendo. We chose that bug because a previous attempt at communication had failed — we had thought that them fixing the strncmp bug in the System Menu’s IOS could cause the system menu to brick when it tried to load the banner for the Homebrew Channel.   I emailed them about that in March, 2008 (right after IOS37 was released), and never got a response.   Thinking maybe I’d failed to find the right email address, we tried again with another bug.  We chose that bug because

  1. We could position it as a piracy-related concern, and Nintendo has some channels for reporting piracy
  2. We didn’t really care if they fixed the bug, since it wasn’t really that useful for legitimate homebrew
  3. There was probably not much they could do to fix it, anyway, since it was more of a design flaw

The bug (as we intended to report it) wasn’t so much that you could poke a register to enable DVD video mode:

 #define HW_DIFLAGS 0x0d800180

 set32(HW_DIFLAGS, 0x200000);

… it was that you could just set a bit in the TMD (in the “access rights” field) and it would let you send DVD video commands.  You didn’t even need to patch IOS!  If you set that bit in your TMD, when your title gets launched, ES reads the “access rights” field (offset 0x1d8) and checks a couple of bits.   If bit 1 is set, it opens /dev/di and calls ioctl 0x8E, which in turns calls syscall 0×50, which does the above register poke.  This seems to set some state in the DI controller chunk of the Starlet that allows DVD video commands to go through.  This is how DVDX works — that bit is set in the TMD for DVDX and that makes the magic happen.

All of this is more or less academic, because if you can forge a signature to modify the TMD, then you can just patch the content of IOS — and that’s what most people (everyone else) did.  We think our approach is cleaner, but oh well.

Looking through the IOS code, ES checks the TMD for two bits, not one — but we couldn’t really figure out what the other one did, so we ignored it and moved on to more pressing things.  I only discovered its purpose a year later when trying to work on a BootMii bug which prevented the front-panel buttons from working when we were booted from IOS instead of as boot2.

If you refer back to my Wii Hardware Architecture diagram, you’ll see that the PPC (where most code gets executed) has to communicate to all the peripherals through an I/O interface that’s built into the Starlet; this interface selectively bridges some address ranges to different peripherals on the AHB / APB busses.   (AHB and APB are two standard ways of connecting other devices to an ARM core — the first one is higher-performance and used for things like USB and NAND, and the latter is slower and used for things like buttons and joypads.)

Normally, you have to access peripherals on those busses by making calls to IOS, which always has access to everything.  I thought this acted as a “de facto” firewall — that there simply was no silicon pathway from the PPC to e.g. the NAND, but there was one for e.g. the EXI bus and gamepads.  I should have been suspicious, however, at the fact that shape of this firewall can change somewhat when MIOS runs.  In normal IOS, the PPC cannot talk to the optical drive interface (DI), but in GameCube mode it can — and it has to work this way in order for GameCube games to be run without patching the games on the fly.   (I wonder why Nintendo didn’t make MIOS trap those DI commands and then translate them into IOS ioctls — this may always be a mystery.)

Another reason I should have been suspicious was the wording of some of the tests we saw in the factory logs I scraped:

sdiIMemA "SDI IOP API MemRW (sort)" "use IOP API in this test. Need SDCd" 0x0B09 sdio_api_memrw.dol "-auto"
sdi0RegM "SDI Register Check for WP (manual)" 0x0B01 sdio_hcreg.dol "-sdiboth" sdi0MemS

NandChk "NandFlashTest" "NAND FLASH Phsycal layer test from BW access" 0xA088 NandManu.dol
NandIOS "NAND Flash Auto by IOS-API" "WAIKIKI output." 0x0CA2 NandIOS.dol

Note that all of this code is running on the PPC. Some of it specifically refers to talking to hardware via IOS (IOP API or IOS-API), and some of it specifically talks about accessing hardware directly from the PPC (“test from [Broadway] access”).

Well, we can now answer one of the mysteries from my factory 2 post. Towards the end of the manufacturing process, they insert a disk — 122E — into the Wii, which installs a “DataChk.wad” — title ID of 00010000-30303032 (“0002“), and then they run a bunch of DOLs from an SD card. This seems unnecessary — why can’t the disk just run stuff?

As it turns out, the TMD for “0002” has a different bit set in its TMD “access rights” field — bit 0. The code for this looks something like:

#define HW_MEMMIRR 0x0d800060
#define HW_AHBPROT 0x0d800064 // defaults to 0xFFFFFFFF on boot

void check_tmd(struct TMD *tmd) {
    // stuff ...
    enable_dvd_video_mode(tmd.access & 2);
    syscall_54(tmd.access & 1);
    // more stuff ...

void syscall_54(int factory_mode) {
    if (factory_mode) {
        set32(HW_MEMMIRR, 8); // this probably enables access to Hollywood regs from PPC
        set32(HW_AHBPROT, 0x80000DFE); // re-enable PPC access to disabled hardware devices
        write16(0x0d8b4202, 0); // dunno what this does
     } else {
        clear32(HW_MEMMIRR, 8); // this probably disables to Hollywood regs from PPC
        clear32(HW_AHBPROT, 0x80000DFE); // disable access to some hardware devices from PPC
        write16(0x0d8b4200, 0x18); // dunno what this does

At normal boot, boot2 will read the System Menu (1-2)’s TMD, find a zero, and call syscall_54(0). Once it reloads into this “0002” title, IOS will call syscall_54(1), which — get this — enables access to every single fucking piece of hardware, directly from the PPC. This lets their factory tests access all of the hardware in the simplest way possible — you can access NAND, the SD card, WiFi, everything from a DOL running on the PPC. This makes the tests much easier to write — many of them would have required IOS modifications, otherwise — and probably saved them a lot of time — also, it suggests that originally there was no restriction and that they went in and placed that artificial restriction towards the end of the Wii’s development cycle.

When I wrote the code to read the front panel buttons for BootMii, I did all of my testing using BootMii/boot2. This meant that — although I didn’t realize it — I had full access to the normally-guarded hardware, including the GPIO pins that are connected to the front panel buttons. If I had tested more with BootMii/IOS, I would have realized that the real boot2 and IOS both lock down those registers, which is why buttons didn’t work in BootMii/IOS. That’s how I discovered the HW_AHBPROT register, and it reminded me of the above syscall_54(), and here we are today.

So you’ve read this far — what does this all mean? Sadly, not too much. We wrote MINI to act as a proxy so we could talk to hardware from the PPC which was normally locked out. We still need it to boot up the PPC and start code executing there, but in theory the rest is redundant. The simplest fix for the button problem was to just make MINI set that HW_AHBPROT register to 0xFFFFFFFF — it’s probably one bit per device — but there’s no real point in rewriting the rest of BootMii.

(Before anyone asks — no, this doesn’t really make it easier to access USB / Bluetooth from BootMii, because it just means that you could write your USB stack for PPC instead of for the ARM chip.)

The major winner here is gc-linux, which can now reuse most of the normal MMIO Linux drivers to talk to hardware instead of proxying through MINI. It’s not a functionality improvement, but more of a performance boost. Nevertheless, I hope you found this interesting.

Tags: Wii

29 responses so far ↓

  • 1 SquidMan // Aug 20, 2009 at 4:30 pm

    Wow, nice write-up bushing :D
    Man, I’ve missed these awesome tech-posts of yours. Also, lol, Nintendo-fail.

    And, first again? Man, I feel like a nerd or something :|

  • 2 ifish // Aug 20, 2009 at 5:18 pm

    hey thanks for all the work bushing i really appricate it and thanks for the new ppc for bootmii to make it work thanks guys lots of love and respect

  • 3 mcbarron // Aug 20, 2009 at 5:48 pm

    I’ve been lurking for a while, and admittedly don’t always understand all of the low level technical bits, but you always make it interesting. Makes sense for the devs to have a way to get “root” on the system hardware, just surprised that it is so easy to activate.


  • 4 Risugami // Aug 20, 2009 at 6:14 pm

    I love these technical stories bushing. Btw, is “NandManu.dol” a misspelling of “NandMenu.dol”? If so, I find that kinda funny.

  • 5 Risugami // Aug 20, 2009 at 6:16 pm

    oh and I didn’t even notice “Phsycal”

  • 6 me.yahoo.com/nande_kudas… // Aug 20, 2009 at 6:23 pm

    truly intresting :)

  • 7 Slowking // Aug 20, 2009 at 9:51 pm

    If the PPC has direct access to the NAND, doesn’t that mean that Nintendo can patch IOSs all they want, we can just install the HBC directly from now on? If so: *rofl*

  • 8 someguy_12345 // Aug 20, 2009 at 10:22 pm


    I assume that this won’t help my hopes of getting wifi on gc-linux.

    (People say it’s because Wii uses an odd motherboard layout and it would take a long time to write a wifi driver for Wii linux) Gah. :(

    Even though I understand very little, I still enjoy these kinds of posts :-) Cheers.

  • 9 leonardo2204 // Aug 20, 2009 at 11:02 pm

    Great post !
    I really appreciate for all the efforts so far that you have had !

    []‘s !

  • 10 pentolino // Aug 20, 2009 at 11:54 pm

    Thanks bushing for your explanation; I finally understand why that HW_AHBPROT stuff caused such a great result for gc-linux.
    Once I get a 2GB (or more) card which works with bootmii (mine doesn’t) nothing will stop me from turning the wii into a fully functional linux home server when needed (two of the worst issue – usb 2.0 and “reboot in linux mode” have been resolved by MIKE).

  • 11 tech3475 // Aug 21, 2009 at 12:58 am

    Thanks Bushing for another interesting article.

    But thanks should also go to Nintendo for their arrogance, under assuming the capabilities of the consumer and finally for having such a flawed design (which shouldn’t have happened on paper).

    Thinking about it. the wii is truly last gen stuff….judging by the number of security holes that is.

  • 12 adr990 // Aug 21, 2009 at 6:05 am

    Hehe, reading your posts is always nice!
    Great job.

    Very interesting.

    I wonder what more you guys are able to access and hack.

    Something awesome would be making BootMii not brick the Wii if you install it on a so called ‘LU64+’ Wii.
    (I mean, if there even is one possible way to do it later, or ever..)

  • 13 lewurm // Aug 21, 2009 at 7:15 am

    Very interesting post bushing, thanks alot!

    However, I wondered if there is an performance issue when accessing AHB devices via PPC.
    I made up some primitiv read/write tests: http://pastebin.com/f1acba98c
    great performance, but it isn’t complete clear to me how this is (technically) possible and furthermore why Nintendo need IOS? It is just security by obscurity?

  • 14 funkamatic // Aug 21, 2009 at 7:15 am

    I’m really ashamed but I didn’t follow very well until you got to the “what does this all mean?” part.

    Cool, stuff. Can’t wait for the next DSi update!

  • 15 Wack0 // Aug 21, 2009 at 11:41 am

    omfg omfg omfg
    if we can access nand directly from the ppc, does this mean one could “install” titles by manually writing to nand, without going through ES ?

  • 16 cactusjack901 // Aug 21, 2009 at 2:23 pm

    Very nice post Bushing. I love knowing these little details about how the Wii works =)

    @adr990 It’s not that Bootmii/boot2 would brick the LU64+ Wiis, if we could get it into the boot2 slot and have it pass sigchecking it’d run just fine. The problem is that the fakesigning bug was present in the old versions of boot1, but in LU64+ wiis, it was fixed. Now, from a purely technical point of view, we could extract the key Nintendo uses to sign things from the wii, and use that to sign Bootmii, and that would allow Bootmii to be installed on any and every Wii, however, this would be illegal, and would also go against the very spirit of the community.

  • 17 Segher // Aug 21, 2009 at 2:25 pm


    Yes, you can — and natural selection will promptly take care of people who do (or, sadly, of their systems only).

  • 18 cactusjack901 // Aug 21, 2009 at 2:38 pm


    Console-Based Darwinism?

  • 19 Segher // Aug 21, 2009 at 2:38 pm


    You can factor 1024-bit RSA moduli? Please tell us how!

  • 20 cactusjack901 // Aug 21, 2009 at 2:43 pm


    …oh yeah, kinda forgot about that little bit *blush* well, doesn’t really matter, it’s a moot point as using the extracted key would be illegal (and either way, I was speaking metaphorically)

  • 21 cactusjack901 // Aug 21, 2009 at 2:43 pm

    …I meant Theoretically *facepalm*

  • 22 marcan // Aug 21, 2009 at 6:56 pm

    WiFi on Linux is almost working last I checked. Isobel’s working hard on it. It does use this hack, but it doesn’t directly require it (it should also work via mini proxy, just more slowly). This trick doesn’t really let you do anything that you couldn’t via bootmii/mini, it just removes all of the IPC overhead so you can get faster drivers.

  • 23 ifish // Aug 22, 2009 at 4:43 am

    will you guys ever have the pointing in bootmii? and wow marcan posted? i thought he dosnt help here havnt herd from him anymore

  • 24 wiisixtyfour // Aug 22, 2009 at 3:09 pm

    as you can see, marcan is still around

  • 25 panzeroceania // Aug 22, 2009 at 6:47 pm

    what can you do with GC Linux? could you run debian with lxde? firefox?

  • 26 ChuckBartowski // Aug 22, 2009 at 9:43 pm

    no marcan still hangs around, he just doesnt do wii dev (as far as we know). Hes still there to help and answer questions.

  • 27 HyperHacker // Aug 23, 2009 at 10:21 am

    Neat find. This could have some interesting implications for game hacking. Ocarina codes being able to access the SD without any IOS hacking?

    BTW what’s up with the comment system? It tells me I need to be logged in (even though I told it to remember me last time), so I log in, and it takes me back to the comments page saying I need to be logged in. Then the next day, I am logged in. O.o

    @panzeroceania: Read around at http://www.gc-linux.org/wiki/Main_Page

  • 28 ifish // Aug 25, 2009 at 4:11 am

    oh ok so marcan still hangs around just dosnt program for wii anymore now he dose iphone anddo you guys have any future projects or you gonna release not a beta version of bootmii

  • 29 HackMii Installer v0.7 // Jul 26, 2010 at 1:15 pm

    [...] now has the HW_AHBPROT flags set for direct hardware access, thus replacing [...]

You must log in to post a comment.