The Mechanism for Boot1 to Choose Bootmii Instead of Boot2
May 26, 2009 02:18PM
I'm curious about the mechanism for boot1 to choose bootmii instead of boot2. I've compared my NAND images with and without bootmii/boot2 installed. In the first 8 unencrypted blocks, the only differences are in block3 & 4 which are originally empty block and now occupied by bootmii. Then how does boot1 know the existance of bootmii and load it? It search the (8-1) blocks to find the highest version of bootmii (or boot2) to run, or it decrypt the other encrypted area to find information/table to load bootmii (or boot2)?
Re: The Mechanism for Boot1 to Choose Bootmii Instead of Boot2
May 26, 2009 03:22PM
This is an excellent question with a complicated answer which deserves its own blog post. In the mean time, allow me to quote (and slightly edit for clarity) some discussion we had about this on IRC today:

17:50:54 <@bushing> TD-Linux: sure.   boot2 -- as with all versions of IOS -- is actually 2 parts
17:50:57 <@bushing> 1) an ELF file
17:51:02 <@bushing> 2) a small stub that loads that ELF file
17:51:16 <@bushing> we replace #2 and then write it into an unused area of flash
17:51:23 < WiiPower> and how does it do that? I thought it's boo1->BootMii->backed up boot2
17:51:32 < TD-Linux> yes
17:51:38 <@bushing> so we don't even overwrite either of the copies of boot2 that are stored in flash
17:51:56 < TD-Linux> they only change the boot2 loader so it loads their copy
17:52:00 <@bushing> however, we have a block map in our copy of boot2 that has a higher generation
                    number than the other two copies, so it takes priority and the system sees it first
17:52:01 < TD-Linux> maybe we should come up with a new term
17:52:04 < TD-Linux> boot2a and boot2b?
17:52:18 < TD-Linux> bushing, oh what wait?
17:52:19 <@bushing> eh, loader and payload?
17:52:31 < TD-Linux> you don't have to erase the stub part at all?
17:52:53 <@bushing> lol we pulled a clever
17:53:11 < WiiPower> ahh, so if you would get a boot2 update by nintendo, it would get added, and boot1
                    just starts the latest found version?
17:53:18 <@bushing> we make a copy of boot2 with our loader (stub) and their ELF file, and we write it to unused blocks
17:53:25 <@bushing> yes, more or less
17:53:56 < TD-Linux> bushing, so you used a loophole in their filesystem? but boot2 isn't stored in the filesystem, is it?
17:54:48 <@bushing> TD-Linux: er, not quite. let me explain
17:55:47 <@bushing> a block is 64 pages of 2K -- so, 128K.  the first 8 blocks are reserved for boot1 and boot2 (so, 1 megabyte)
17:56:12 <@bushing> the Wii can also have up to 80 bad blocks, so they have to account for that -- although the first block is never bad
17:56:23 <@bushing> so boot1 goes into the first block (block 0)
17:56:44 <@bushing> they then have 2 copies of boot2 in the remaining 7 blocks (blocks 1-7)
17:57:47 <@bushing> the first copy of boot2 starts at the "first valid block" in 1..7, and counts forward.  the second copy 
                    starts at the "last valid block" in 1..7, and counts backward
17:58:05 <@bushing> boot2 takes up two blocks
17:58:51 <@bushing> so if all seven blocks are good (the most common case), you have the first copy of boot2 in blocks 
                    1 and 2, and the second copy in 7 and 6
17:58:56 < TD-Linux> do blocks have physical significance on the nand like pages do? I assume you erase by pages
17:59:20 <@bushing> yes -- a block is defined as the minimum amount of data that can be erased at one time
17:59:25 <@bushing> so you have to erase an entire block at a time
17:59:36 < TD-Linux> oh okay, not a page
17:59:42 < TD-Linux> so what's the significance of a page then?
17:59:54 < Oliveira> 1 block = 128kbytes ?
17:59:59 < TD-Linux> do you read a page at a time or something?
18:00:04 < Oliveira> (I'm not considering ECC data)
18:00:16 <@bushing> Oliveira: yes.  TD-Linux: generally, yes
18:00:32 < Oliveira> that explains the malfunction on that wii lol
18:00:36 < TD-Linux> the only flash I've really used that low level before was NOR flash
18:00:39 < Oliveira> 1 bad command= boot1 erased
18:00:44 <@bushing> you can read parts of a page, and you can write parts of a page, but there are some limitations
                    (you can only write to one page in 4 separate accesses)
18:00:48 <@bushing> yup
18:00:53 <@bushing> aaaanyway
18:00:57 < TD-Linux> it had 16KB block sizes, and of course was read a byte at a time
18:01:08 <@bushing> here's how it knows what blocks out of those 1..7 to use:
18:01:34 <@bushing> there's a "bad block map" that is written at the end of a block  --- it has a magic value,
                    and then a generation number
18:02:13 < TD-Linux> I assume this takes away from the block's capacity right? it's not stored somewhere
                    separate and magical
18:02:35 <@bushing> yes, but it's not much
18:02:41 <@bushing> it looks like this:
18:02:41 <@bushing> 00627c0: 26f29a40 1ee684cf 00000002 01000000  &..@............
18:02:41 <@bushing> 00627d0: 00000000 01010101 01010101 01010101  ................
18:03:34 <@bushing> the first 8 bytes are the magic value (that's how it gets recognized)
18:03:47 <@bushing> 00000002 is the generation number (more on this in a bit)
18:04:27 <@bushing> the rest show which blocks are valid. one byte per block.  so this shows that block
                    0 is invalid, blocks 1,2,3,4,5,6,7 are valid, and then blocks 8... are invalid (01 = invalid, 00 = valid)
18:05:13 <@bushing> so boot1 scans the last page of each block in 1..7 to look for that magic marker, and
                    then picks the one with the highest generation number
18:05:38 <@bushing> this NAND image also has
18:05:39 <@bushing> 00e67c0: 26f29a40 1ee684cf 00000003 01000000  &..@............
18:05:40 <@bushing> 00e67d0: 00000000 01010101 01010101 01010101  ................
18:05:47 <@bushing> so it will use that one -- but they're both the same
18:06:07 <@bushing> so it will try to load boot2 from blocks 1 and 2, and if that fails, it will try loading from 7 and 6
18:06:21 <@bushing> this leaves blocks 3, 4 and 5 unused
18:06:34 <@bushing> so we write our bootmii stub + boot2 elf to blocks 3 and 4
18:06:44 <@bushing> and then write this blockmap:
18:07:10 <@bushing> 26f29a40 1ee684cf 00000004 01010100 00000000 01010101 01010101 01010101
18:07:18 <@bushing> to the end of block 4
18:07:50 <@bushing> who can tell me why that works? :)
18:08:01 < Cattlesna> 4 > 3?
18:08:09 < Daeken> ... wow.
18:08:14 <@bushing> right, but why will that load our copy of boot2 but not theirs?
18:08:20 < Daeken> that's simple and elegant :)
18:08:30 < Daeken> invalid marks on the other blocks :)
18:08:49 <@bushing> this delayed our release by a good month or two, but we had to do it because otherwise
                    we broke GameCube compatibility
18:08:51 < Cattlesna> one byte per block for a 0/1 value is quite wasteful
18:09:03 <@bushing> thanks Daeken :)  the nice part is that we can just erase those two blocks of flash and
                    it will go back to the way it was before
18:09:19 < Daeken> yea, that's pretty awesome
18:09:23 < Daeken> nice work
18:09:31 <@bushing> it was marcan or dhewg's idea
18:09:59 <@bushing> the problem with GameCube mode is that when it launches, it runs BC which runs boot2
                    which runs MIOS which runs the GC IPL which loads your game
18:10:20 <@bushing> BC is very similar to boot1, and in recent updates they fixed the fakesign bug there
18:10:30 <@bushing> (which was foreshadowing that they had fixed it in boot1, too)
18:10:50 < TD-Linux> but then why does BC not load bootmii?
18:10:58 <@bushing> because it has an invalid signature :)
18:11:08 <@bushing> so it falls back on the second copy
18:11:12 < TD-Linux> wow that's kinda silly
18:11:13 <@bushing> which is the original boot2
18:11:27 < TD-Linux> so does that mean on old wiis with non-updated BC, gamecube games fail?
18:11:32 < Oliveira> so it relies on updated BC ?
18:11:45 < Daeken> TD-Linux: don't see why, the signatures would match
18:11:55 <@bushing> no, because bootmii can detect GC mode and pass it through correctly
18:12:03 <@bushing> the problem was that BC was not detecting ANY valid boot2s
18:12:11 < TD-Linux> oh OK
18:12:11 <@bushing> (new BC)
18:12:34 < TD-Linux> why not just patch BC?
18:12:48 <@bushing> we argued about that for *weeks*
18:12:59 < Oliveira> would be inelegant ? XD
18:12:59 <@bushing> and that's what I originally wanted to do
18:13:10 <@bushing> but yeah ... there were several reasons
18:13:17 <@bushing> 1) what Oliveira said
18:13:21 < WiiPower> ok, now i see why the release took so long, but i also see that it's worth it, as it seems
                    to be a very very nice solution
18:13:39 < Daeken> Oliveira: simpler is nearly always better, when you can manage it
18:13:54 <@bushing> 2) if nintendo updated BC again, then we'd have to go and repatch it. this avoids that
18:14:17 < Oliveira> PSP devs were promissing their own OS back in 2007  we're in 2009 and nothing ever 
                    happened ... look what the wii scene have now ... lol
18:14:39 <@bushing> 3) before, in order to uninstall boot2 (legally) we had to write a backup copy of the original
                    boot2 stub/loader to SD, and you needed to provide that.  with this, we just erase two flash blocks and it's uninstalled
18:14:40 < TD-Linux> we don't really have our own OS yet
18:14:45 < TD-Linux> mini begins that
18:15:22 < Oliveira> the framework is being built... onm the PSP it didn't even get started. that's what I meant
18:15:41 <@bushing> the thing is, this only works if you start with a valid, unpatched boot2 ... everyone that tested bootmii for us 
                    (10 people?) before we switched installation methods had to go back and use a WAD (*gasp) in order to get this to work
18:15:42 < Oliveira> even thought the hackers had control over the boot chain
18:15:47 < Daeken> man, i really need to get a wii so i can contribute in some way :P
18:15:53 <@bushing> that's why we couldn't release a beta before we got this working
18:16:14 <@bushing> because we didn't want half the people to have to completely uninstall in order to update to the next beta
18:16:42 <@bushing> TD-Linux: so even though this was harder than patching BC, it had some advantages
18:17:05 < PhxTank> more short term work for long term benefit.
18:17:21 < PhxTank> makes sense
18:17:31 <@bushing> the final straw was when I was doing some testing, and had ES_ImportBoot write a version of 
                    boot2 to flash without writing the ECC data.  (if boot1 sees uncorrectable ECC errors, which it would, it just
                    ignores the ECC data and tries to load it anyway)
18:17:53 <@bushing> I don't know why it did that and I can't reliably reproduce it
18:18:11 <@bushing> but some people in the field have seen it -- I've gotten dumps from people which had that, too
18:18:27 <@bushing> but that convinced me that we had tested OUR code at least as well as Nintendo did, so ....
18:18:49 < TD-Linux> hah maybe they won't be updating boot2 in the near future
18:19:12 <@bushing> yeah, I don't know if they will or not. I look forward to seeing if they try ...
18:19:27 <@bushing> and it still booted, etc, because it just ignored the missing ECC data
18:19:38 <@bushing> you wouldn't know unless you bothered to look at the flash dump with a hex editor etc
18:21:03 <@bushing> but yeah, when we did that, we really just rewrote the whole installer :/
18:21:14 <@bushing> (and included support for HBC and DVDX)
18:21:35 <@bushing> the fact that they blocked /dev/flash in new IOSes slowed us down, too
18:21:47 <@bushing> so we then had to reboot into MINI, dump flash to RAM, then go back into IOS
18:22:01 <@bushing> (for some Wiis)
18:22:24 <@bushing> and repeat that to write it out, of course
18:27:23 < WiiPower> Hmm, the patched BC seeing and skipping the trucha signed BootMii
18:27:54 < WiiPower> shoudln't that think that the other boot2s are inside broken blocks?
18:28:25 < WiiPower> so nintendo is nice that they try to start them
18:28:29 < Daeken> WiiPower: no, because it will ignore the block containing the block map.
18:28:47 < Daeken> that's why the redundancy of the block map is so important for it to work properly
18:28:48 < WiiPower> does the block contain the signature?
18:29:21 < Daeken> sounds like it to me
18:29:27 *** AlexLH ~alexlh@ip68-98-113-91.ph.ph.cox.net has quit [Quit: BootMii is teh awsum]
18:29:28 < Daeken> bushing: is that correct?
18:30:29 <@bushing> hm?   i'm not sure I understand
18:30:35 <@bushing> we mark the original first copy of boot2 as bad
18:30:42 <@bushing> and leave the original second copy of boot2 as good
18:30:47 < Daeken> ahh... i see
18:30:56 < WiiPower> ?
18:31:01 < WiiPower> now i'm confused
18:31:15 < Daeken> so it sees the bad signature on your boot2 replacement and goes to the original that's aftr it
18:31:28 <@bushing> no, the block map is just at the end of the block (any block)
18:31:30 < WiiPower> but i'm tired, which is most likely why i don't understand
18:31:47 < WiiPower> ahh
18:31:53 < WiiPower> no
18:32:20 <@bushing> Daeken: right.  so we found a behavior difference between boot1 and BC and exploited
                    it for the sake of compatibility
18:32:43 <@bushing> (sort of -- if they behaved the same, there would be no need to do this workaround)
18:32:59 < Daeken> got it
18:35:16 < WiiPower> so to summarize if the question comes up in the future, BootMii is installed as boot2, leaves
                    the original boot2 where it is, but tricks the wii to think it's in bad blocks which is why BootMii gets started
18:35:19 < WiiPower> ?
18:39:12 < WiiPower> BootMii is installed additional to boot2, leaves the original boot2 where it is, tricks the wii to think
                    the real boot2 is in bad blocks, which is why the wii starts the backup copy of boot2 which is BootMii then*
18:40:00 < WiiPower> even if that should not be 100% truth, i think it's closer as BootMii overwrites boot2
18:42:03 < kennyboy> so in conclusion.. bootmii tricks boot2 xD..
18:42:54 < SquidMan> bootmii pwnd boot2
18:43:25 < kennyboy> indeed
18:45:11 <@bushing> WiiPower: yes, although bootmii is only a modified version of boot2
18:45:32 <@bushing> technically, we could make bootmii load one of the other copies of boot2 from flash and run it
                    instead of concatenating the two together, but meh
18:46:01 < TD-Linux> bootmii tricks boot1, not boot2 ;)
18:46:16 < WiiPower> "only"...
18:46:35 <@bushing> well, I just wanted to be clear that bootmii doesn't really modify the behavior of the rest of the system
18:46:48 <@bushing> the bootmii stub, the part that's in flash
18:46:55 <@bushing> not to be confused with the thing that's on the SD
18:47:43 < TD-Linux> the thing on SD should be given a different name
18:47:46 < WiiPower> BootMii would work if the other blocks were really ALL bad?
18:47:54 < TD-Linux> or the modified boot2 should be given a different name
18:48:31 < Oliveira> if I understood well, the stuff on SD are MINI and Bootmii-PPC
18:49:05 < kennyboy> stub (loader) is standing in some kind of fork on the road.. then boot1 comes up to it and asks
                    where it needs to go.. and the stub decides (bootmii left, wii right.. )
18:49:51 <@bushing> TD-Linux: yes, that's why the ppc code on the SD is called "ceiling cat"
18:49:58 < TD-Linux> and armboot.bin (which is mini + PPC loader right)
18:50:11 <@bushing> because we asked segher what we should name it and that's the name he chose because he
                    picks the best names evar
18:50:23 <@bushing> WiiPower: which other blocks?
18:50:35 < WiiPower> 1,2,5,6,7
18:50:41 <@bushing> TD-Linux: armboot.bin is MINI, straight up
18:50:45 <@bushing> yes, it would work
18:50:51 < TD-Linux> how does it know to load Bootmii-PPC then?
18:50:55 < WiiPower> ok, now i understand more
18:51:32 <@bushing> [gitweb.bootmii.org]
18:52:13 < WiiPower> that's mini's main, right?
18:52:30 < TD-Linux>         return vector;
18:52:32 < WiiPower> it loads the ppc.elf and then "does its stuff"?
18:52:36 < TD-Linux> what kind of hackery is going on there?
18:53:38 < TD-Linux> bushing, so there is currently no way to reload mini without reloading ppcboot.elf?
18:55:45 <@bushing> TD-Linux: correct
18:56:04 < TD-Linux> I hope it has decent ways to reset itself then... I haven't looked at most of that code
18:56:17 <@bushing> reset itself?
18:56:30 < TD-Linux> like if you load a different PPC binary
18:56:46 <@bushing> here, look at [gitweb.bootmii.org]
18:56:52 <@bushing> the bottom, boot2_ipc


That's still not too clean, but should give you something to chew on. Maybe I'l try to make some sweet diagrams in OmniGraffle to explain, but in the mean time, I'd be happy to field any questions (but take no credit ;) )



Edited 1 time(s). Last edit at 05/26/2009 03:27PM by bushing.
Re: The Mechanism for Boot1 to Choose Bootmii Instead of Boot2
May 26, 2009 05:25PM
OT: will log.hackmii.com be updatedt more regulary in the future?
Re: The Mechanism for Boot1 to Choose Bootmii Instead of Boot2
May 27, 2009 02:12AM
Excellent explanations.

I have done some on-console NAND erase/program test through old IOS or cIOS. Now trying to develop my own RealWnW (Real Wii NAND Writer -- a on-console NAND writer/programmer) so that I can revert to my old NAND dumps which are prohibited by bootmii NAND restore function.

Now I know it's simple to unstall bootmii by just erasing block3/4. I like to use bootmii but the SD driver of current bootmii loader hangs up if I plug my favorite high capacity Transcend 16GB SDHC (not just drive LED flasg but hang). I think I should not release some kind of bootmii uninstaller program for others with similar problems till I know more about bootmii signatures, because in rare case it might not be in block 3/4 due to different block map, right? It will need more signature check to make sure where bootmii is located.

BTW, the "bad block map" in unencrypted area contains only 0x80 entries. So it seems to be using by boot process only?
Re: The Mechanism for Boot1 to Choose Bootmii Instead of Boot2
May 27, 2009 10:46AM
Please do not release an app which wipes critical NAND blocks, that is highly dangerous. Oh, and hardcoding block #3 and #4 is like the worst idea ever :P
Our installer already has an uninstall procedure for BootMii/boot2, and it does a shitload of checks before erasing anything. It will be part of the beta2 release, a little patience please.

Thanks
Re: The Mechanism for Boot1 to Choose Bootmii Instead of Boot2
May 27, 2009 03:31PM
Quote
dhewg
Please do not release an app which wipes critical NAND blocks, that is highly dangerous. Oh, and hardcoding block #3 and #4 is like the worst idea ever :P
Our installer already has an uninstall procedure for BootMii/boot2, and it does a shitload of checks before erasing anything. It will be part of the beta2 release, a little patience please.

Thanks

OK. Got it!! I'll never release such app. Only RealWnW might be released after development, and probably only binary without source code to prevent improper use.
Sorry, only registered users may post in this forum.

Click here to login