Changes

Jump to navigation Jump to search
3,726 bytes added ,  21:21, 18 October 2024
Add some """"low-hanging"""" SD driver error code bits
Line 1: Line 1: −
The bootloader is the binary code stored in the ARM9 and ARM11 boot ROMs and hence is ran when the 3DS is powered on. It's purpose is initializing hardware and loading the [[FIRM|system firmware]] from the internal [[Flash_Filesystem|NAND memory]].
+
The bootloader is the binary code stored in the ARM9 and ARM11 boot ROMs and hence is ran when the 3DS is powered on. Its purpose is initializing hardware and loading the [[FIRM|system firmware]] from the internal [[Flash_Filesystem|NAND memory]]..
   −
Besides NATIVE_FIRM, the bootloader is also capable of booting other firmwares (such as TWL_FIRM and AGB_FIRM). However, this will result either in a japanese error-screen or a system shutdown, directly after FIRM-Launching.
+
Besides NATIVE_FIRM, the bootloader is also capable of booting other firmwares (such as TWL_FIRM and AGB_FIRM). However, this will result either in a Japanese error screen or a system shutdown, directly after FIRM Launching.
    
== Boot ROM ==
 
== Boot ROM ==
Upon boot, parts of the ARM9 and ARM11 boot ROMs are protected by writing to [[CONFIG#CFG_SYSPROT9|CFG_SYSPROT9]] and [[CONFIG#CFG_SYSPROT11|CFG_SYSPROT11]], respectively. The ARM9 and ARM11 boot ROMs are identical for all Old 3DS, 2DS and New 3DS consoles.
+
Upon boot, parts of the ARM9 and ARM11 boot ROMs are protected by writing to [[CONFIG#CFG_SYSPROT9|CFG_SYSPROT9]] and [[CONFIG#CFG_SYSPROT11|CFG_SYSPROT11]], respectively. The ARM9 and ARM11 boot ROMs are identical for all 3DS consoles (3DS, 3DS XL, 2DS, New 3DS, New 3DS XL, New 2DS XL)
    
== NAND FIRM boot ==
 
== NAND FIRM boot ==
Boot9 is not hard-coded to only handle 2 FIRM partitions: it parses all 8 NCSD partitions for this. Boot9 will attempt to use every partition listed in the NCSD which is an actual FIRM partition, in the same order listed in the NCSD, until booting one of them succeeds. Among the not-yet-processed partitions, the FIRM which has the highest value at u32 firmhdr+4 will have a FIRM-boot attempted first. Since that value is normally 0x0, the order of FIRM-partition processing is normally identical to the order of the NCSD partitions.
+
Boot9 is not hardcoded to only handle 2 FIRM partitions: it parses all 8 NCSD partitions for this. Boot9 will attempt to use every partition listed in the NCSD which is an actual FIRM partition, in the same order listed in the NCSD, until booting one of them succeeds. Among the not-yet-processed partitions, the FIRM which has the highest value at u32 firmhdr+4 will have a FIRM-boot attempted first. Since that value is normally 0x0, the order of FIRM-partition processing is normally identical to the order of the NCSD partitions.
    
Boot9 is hard-coded for using [[AES_Registers|AES]] keyslot 0x6 for NAND crypto.
 
Boot9 is hard-coded for using [[AES_Registers|AES]] keyslot 0x6 for NAND crypto.
    
== Non-NAND FIRM boot ==
 
== Non-NAND FIRM boot ==
Boot9 can also boot from non-NAND. For this a different set of RSA pubks are used(separate pubks for retail/devunit like NAND). The spiflash FIRM image for this is also encrypted with AES-CBC using a normalkey stored in prot_boot9(separate for retail/devunit). This encryption is basically used instead of what is used for NAND-firm-partitions. This encryption is only used for the FIRM sections, the FIRM header is used raw. The AES keyslot for this is only overwritten afterwards when booting from non-NAND fails. AES keyslot 0x3F is used for this.
+
Boot9 can also boot from non-NAND. For this, a different set of RSA pubks are used(separate pubks for retail/devunit like NAND). The spiflash FIRM image for this is also encrypted with AES-CBC using a normal key stored in prot_boot9(separate for retail/devunit). This encryption is basically used instead of what is used for NAND-firm-partitions. This encryption is only used for the FIRM sections, the FIRM header is used raw. The AES keyslot for this is only overwritten afterwards when booting from non-NAND fails. AES keyslot 0x3F is used for this.
    
   CTR_word[0] = firmimageoffset;//FIRM section offset from FIRM header
 
   CTR_word[0] = firmimageoffset;//FIRM section offset from FIRM header
Line 21: Line 21:  
When booting from NAND fails, boot9 will then attempt to boot from Wifi SPI-flash(this only triggers when the wifi module hw is properly accessible/connected, which is normally the case). The base offset for spiflash FIRM is 0x400. Note that this region(all data prior to offset 0x1F300) is write-protected by the spiflash(not writable from 3DS-mode / DS-mode).
 
When booting from NAND fails, boot9 will then attempt to boot from Wifi SPI-flash(this only triggers when the wifi module hw is properly accessible/connected, which is normally the case). The base offset for spiflash FIRM is 0x400. Note that this region(all data prior to offset 0x1F300) is write-protected by the spiflash(not writable from 3DS-mode / DS-mode).
   −
Additionally, if the shell is closed and a special key combination (Start + Select + X) is held, boot9 will attempt to boot from an inserted NTR cartridge before bootring from NAND. Note: While normally on o3ds/2ds the console will not turn on if the shell is closed (or this is faked by holding a magnet to the console), when this special key combination is held holding down the power button will cause boot to occur anyway.
+
Additionally, if the shell is closed and a special key combination (Start + Select + X) is held, boot9 will attempt to boot from an inserted NTR cartridge before booting from NAND. Note: While normally on O3DS/2DS the console will not turn on if the shell is closed (or this is faked by holding a magnet to the console), when this special key combination is held holding down the power button will cause boot to occur anyway.
    
For non-NAND booting, NCSD / FIRM-backup is not used.
 
For non-NAND booting, NCSD / FIRM-backup is not used.
Line 27: Line 27:  
== SDMMC ==
 
== SDMMC ==
   −
Boot9 has code implemented for using SD(HC) cards, but the input deviceids used by boot9 for those functions are hard-coded for NAND. However, it is possible to use an SD(HC) card in place of the NAND if the NAND chip is first disconnected, and a SD card connected to the bus. Due to the CID being different, partitions will need to be re-encrypted and TWL mode will not work, due to the MBR being in the NCSD header. Using sighax, it may be possible to replace the NCSD header.
+
Boot9 has code implemented for using SD(HC) cards, but the input deviceids used by boot9 for those functions are hard-coded for NAND. However, it is possible to use an SD(HC) card in place of the NAND if the NAND chip is first disconnected, and an SD card connected to the bus. Due to the CID being different, partitions will need to be re-encrypted and TWL mode will not work, due to the MBR being in the NCSD header. Using sighax, it may be possible to replace the NCSD header.
    
== Boot9 RSA keyslots ==
 
== Boot9 RSA keyslots ==
Line 61: Line 61:  
* 0xffffd6e0(end-addr of the above area) size 0x40-bytes: This is the keydata used for crypting the entire OTP with keyslot 0x3f, used by main(). The first 0x20-bytes is for retail, the remaining 0x20-bytes starting at 0xffffd700 is for devunit. Chunk+0(retail=0xffffd6e0 devunit=0xffffd700) is the normalkey, chunk+0x10(retail=0xffffd6f0 devunit=0xffffd710) is the AES-IV.
 
* 0xffffd6e0(end-addr of the above area) size 0x40-bytes: This is the keydata used for crypting the entire OTP with keyslot 0x3f, used by main(). The first 0x20-bytes is for retail, the remaining 0x20-bytes starting at 0xffffd700 is for devunit. Chunk+0(retail=0xffffd6e0 devunit=0xffffd700) is the normalkey, chunk+0x10(retail=0xffffd6f0 devunit=0xffffd710) is the AES-IV.
 
* ...
 
* ...
* 0xffffd760: size 0x100-bytes: First 0x80-bytes is for retail, the remaining 0x80-bytes at 0xffffd7e0 is for devunit. This 0x80-byte block is copied to 0x07ffcd00 by a Boot9 function, however that code actually does the copy in two 0x40-bytes chunks.
+
* 0xffffd760: size 0x100-bytes: First 0x80-bytes is for retail, the remaining 0x80-bytes at 0xffffd7e0 is for devunit. This 0x80-byte block is copied to 0x07ffcd00 by a Boot9 function, however, that code actually does the copy in two 0x40-bytes chunks.
 
* 0xffffd860(end-addr of the above area) size 0x400-bytes: This is the bootrom_dataptr passed to the aes-keyinit function for retail. See the below Tools section for how this is processed.
 
* 0xffffd860(end-addr of the above area) size 0x400-bytes: This is the bootrom_dataptr passed to the aes-keyinit function for retail. See the below Tools section for how this is processed.
 
* 0xffffdc60(end-addr of the above area) size 0x400-bytes: This is the devunit version of the above the 0x400-byte chunk. This is very last chunk of data in the boot9 data-section key-area: end addr for this area is 0xffffe060.
 
* 0xffffdc60(end-addr of the above area) size 0x400-bytes: This is the devunit version of the above the 0x400-byte chunk. This is very last chunk of data in the boot9 data-section key-area: end addr for this area is 0xffffe060.
Line 83: Line 83:     
== Boot11 image data memory layout ==
 
== Boot11 image data memory layout ==
0x0001817c..0x000181f4 size 0x78-bytes: This seems to be the bootrom error screen font gfx data. This begins at the exact end-address of the crt0 code, the rest of the protected boot11 code begins at this end-address(0x000181f4).
+
* 0x0001817c..0x000181f4 size 0x78-bytes: This is the bootrom error screen font gfx data. This begins at the exact end-address of the crt0 code, the rest of the protected boot11 code begins at this end-address(0x000181f4). To extract the font gfx data from there, the 30 dwords at this address need to be converted to big endian. The correct resolution (when displayed as raw) is 32x30x1. The bootrom font looks very similar to [https://robey.lag.net/2010/01/23/tiny-monospace-font.html this font].
 
+
* 0x00019400 is the beginning of the boot11 data area, the first 8-bytes here are unknown.
0x00019400 is the beginning of the boot11 data area, the first 8-bytes here are unknown.
   
* 0x00019408..0x0001b498 size 0x2090-bytes: This is the blowfish keydata which gets copied to arm9itcm_twlkeydata+0x3e0 later.
 
* 0x00019408..0x0001b498 size 0x2090-bytes: This is the blowfish keydata which gets copied to arm9itcm_twlkeydata+0x3e0 later.
* ...
   
* 0x0001c498..0x0001c4f8 size 0x60-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x380.
 
* 0x0001c498..0x0001c4f8 size 0x60-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x380.
 
* 0x0001c4f8..0x0001c538 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x340.
 
* 0x0001c4f8..0x0001c538 size 0x40-bytes: This is the data which eventually gets copied to arm9itcm_twlkeydata+0x340.
Line 105: Line 103:     
== BootROM Errors ==
 
== BootROM Errors ==
 +
Here is the format of the numbers displayed on the error screen:
 +
  BOOTROM 8046
 +
  ERRCODE: ffWWGGNN
 +
  p3p2p1p0 p7p6p5p4
 +
  sd_softE sd_hardE
 +
 +
* <code>ff</code>: sleep switch state (2==MCU sleep switch closed, 1==GPIO sleep switch closed (very bad if this happens), 0==sleep switch open)
 +
* <code>WW</code>: NVRAM (WiFi Flash) FIRM load error code
 +
* <code>GG</code>: ntrboot FIRM load error code
 +
* <code>NN</code>: NAND header (NCSD) load error code
 +
* <code>p<N></code>: NAND FIRM partition load error code. Note the order of the partitions in the error code!
 +
* <code>sd_softE</code>: software error (SD driver status bits, see one section lower)
 +
* <code>sd_hardE</code>: hardware error (SD device status bits, see one section lower)
 +
 +
 
Sample error-screen(where firm0+firm1 RSA signatures were corrupted):
 
Sample error-screen(where firm0+firm1 RSA signatures were corrupted):
   Line 117: Line 130:  
* 4th line is: <code>print_string(..., "%08X %08X",*((unsigned int*)(0x1FFFE000+0x18))`, `*((unsigned int*)(0x1fffe000+0x1C)));//See below memory notes.</code>
 
* 4th line is: <code>print_string(..., "%08X %08X",*((unsigned int*)(0x1FFFE000+0x18))`, `*((unsigned int*)(0x1fffe000+0x1C)));//See below memory notes.</code>
   −
== 0x1FFFE000 memory ==
+
 
 +
=== 0x1FFFE000 memory ===
 
This memory is used by boot9 mainly for sending info to the arm11 for the error-screen. The data in this region is still stored in memory by the time the ARM9+ARM11 jumps to FIRM.
 
This memory is used by boot9 mainly for sending info to the arm11 for the error-screen. The data in this region is still stored in memory by the time the ARM9+ARM11 jumps to FIRM.
   Line 125: Line 139:  
* u32 0x1FFFE000+4: ARM11 MPCore "Count Register 0 (PMN0)".
 
* u32 0x1FFFE000+4: ARM11 MPCore "Count Register 0 (PMN0)".
 
* u32 0x1FFFE000+8: ARM11 MPCore "Count Register 1 (PMN0)".
 
* u32 0x1FFFE000+8: ARM11 MPCore "Count Register 1 (PMN0)".
* 8bit-entry-array 0x1FFFE000+0xC: 8bit status-codes initialized by boot9 main(), for the FIRM-boot devices. +0 is NAND and +2 is wifi-spiflash.
+
* s8[4] 0x1FFFE000+0xC: 8bit status-codes initialized by boot9 main(), for the FIRM-boot devices. +0 is NAND, +1 is NTRCARD and +2 is WiFi Flash, +3 is sleep sensor state.
* ...
+
* s8[8] 0x1FFFE000+0x10: Status-codes originally from nand_findfirmpartition_loadfirm(), for each of the 8 NCSD partitions.
* 8bit-entry-array 0x1FFFE000+0x10: Status-codes originally from nand_findfirmpartition_loadfirm(), for each of the 8 NCSD partitions.
+
* u32 0x1FFFE000+0x18: SD driver internal error bitfield
 +
* u32 0x1FFFE000+0x1C: R1 status bits received from the SD device, AND-ed with 0xFDFF0080 if eMMC (NAND), otherwise 0xFDF90008 if SD.
 +
 
 +
=== BootROM SD driver error bits ===
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Value
 +
!  Description
 +
|-
 +
| 0x1
 +
| STATUS2: received cmd field does not match what was sent
 +
|-
 +
| 0x2
 +
| STATUS2: received CRC does not match what was calculated
 +
|-
 +
| 0x4
 +
| STATUS2: framing error, stop bit was not encountered
 +
|-
 +
| 0x8
 +
| STATUS2: data was not received within the timeout period
 +
|-
 +
| 0x10
 +
| STATUS2: RX FIFO overflow
 +
|-
 +
| 0x20
 +
| STATUS2: TX FIFO overflow
 +
|-
 +
| 0x40
 +
| STATUS2 (bit31): illegal access error (???)
 +
|-
 +
| 0x80
 +
| At least one error bit was set in the command reply from the SD device, or other unexpected state is reported.
 +
|-
 +
| 0x100
 +
| An illegal command was received by the SD device (ILLEGAL_COMMAND bit set).
 +
|-
 +
| 0x200
 +
| Timer-based timeout while waiting for SD device operations to finish.
 +
|-
 +
| 0x400
 +
| Got a timer-based timeout during MMC initialization sequence.
 +
|-
 +
| 0x800
 +
| ??? some sort of timeout
 +
|-
 +
| 0x8000
 +
| Timeout while trying to perform AES operation on sector data
 +
|-
 +
| 0x80000
 +
| Tried to perform AES operation while another AES operation is taking place
 +
|}
 +
 
 +
=== BootROM SD device error bits ===
 +
These error codes are received directly from the device, and are in the same format as received in an R1 type reply.
 +
 
 +
See [https://www.sdcard.org/downloads/pls/ SD Specifications Part 1 Physical Layer Simplified Specification] for the error bit list.
   −
== BootROM Status Codes ==
+
=== BootROM Status Codes ===
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
 
|-
 
|-
Line 136: Line 205:  
|-
 
|-
 
| 0x00
 
| 0x00
| Success
+
| Device was not considered to be loaded.
 +
Can also indicate success, but not necessarily when seeing the blue bootrom error screen.
 
|-
 
|-
| 0xEE(~17)
+
| 0xFF(-1)
| NCSD header validation function failed: NCSD magicnum is invalid or RSA verification failed.
+
| Partition skipped due to it not being a FIRM partition (partition fs type isn't 0x3 and partition fs crypt-type isn't 0x2).
 
|-
 
|-
| 0xDE(~33)
+
| 0xFE(-2)
| FIRM header validation function failed: FIRM magicnum is invalid or RSA verification failed.
+
| Device initialization failed due to it missing or malfunctioning
 
|-
 
|-
| 0xDF(~32)
+
| 0xFD(-3)
| Failed to read sector data from the device.
+
| *unobtainable* SD driver initialization failed due to boot9 state not being initialized correctly (it's always initialized)
 
|-
 
|-
| 0xCF(~48)
+
| 0xF8(-8)
| FIRM section validation function failed: FIRM section is invalid.
+
| The FIRM header magic is not matching "FIRM".
 
|-
 
|-
| 0xF7(~8)
+
| 0xF7(-9)
| A NAND FIRM from another partition was already found with a priority(firmhdr+4) >= to the value for the current partition's FIRM priority.
+
| FIRM image loading got skipped due to already having found an equal or higher priority (firmhdr+4) FIRM to load.
 
|-
 
|-
| 0xF8(~7)
+
| 0xEF(-17)
| The FIRM magicnum(firmhdr+0) is invalid.
+
| Failed to load NCSD header from NAND
 
|-
 
|-
| 0xFF(~0)
+
| 0xEE(-18)
| Initial value for each entry in the 8-entry array of status-codes for the NAND NCSD partitions. Indicates that the partition is not a FIRM partition(partition fs type isn't 0x3 or partition fs crypt-type isn't 0x2).
+
| NCSD header magic is not "NCSD", or NCSD header RSA verification failed.
 +
|-
 +
| 0xDF(-33)
 +
| Failed to read FIRM header from device.
 +
|-
 +
| 0xDE(-34)
 +
| FIRM header magic is not "FIRM", or FIRM header RSA verification failed.
 +
|-
 +
| 0xCF(-49)
 +
| FIRM section loading failed for any of these reasons:
 +
* FIRM section load address blacklist got tripped
 +
* Failed to read FIRM section data into memory
 +
* FIRM section hash verification failed
 
|}
 
|}
   Line 192: Line 274:  
   ...
 
   ...
 
    
 
    
   NAND firm-boot code-block, is described below. Note that boot9 is basically hard-coded to use deviceid NAND, not SD.
+
   NAND firm-boot code-block is described below. Note that boot9 is basically hard-coded to use deviceid NAND, not SD.
 
   {
 
   {
 
   timer_updatestoredstate() is called, then the AES keyslot for NAND-FIRM is selected(0x6).
 
   timer_updatestoredstate() is called, then the AES keyslot for NAND-FIRM is selected(0x6).
Line 334: Line 416:  
| <tt>00F800FF F8F8FFFF FFFFFFFF 00000000 00000000</tt>
 
| <tt>00F800FF F8F8FFFF FFFFFFFF 00000000 00000000</tt>
 
| Both the firm0 and firm1 partitions are corrupt (failed signature checks).
 
| Both the firm0 and firm1 partitions are corrupt (failed signature checks).
 +
|-
 +
| <tt>00F800FF DEDEFFFF FFFFFFFF 00000000 00000000</tt>
 +
| Both the firm0 and firm1 partitions are corrupt (possibly related to certain flags missing?)
 +
|-
 +
| <tt>00F800FF CFCFFFFF FFFFFFFF 00000000 00000000</tt>
 +
| Both the firm0 and firm1 partitions are corrupt
 
|-
 
|-
 
| <tt>00F800EE FFFFFFFF FFFFFFFF 00000000 00000000</tt>
 
| <tt>00F800EE FFFFFFFF FFFFFFFF 00000000 00000000</tt>
 
| [[NCSD]] header in sector 0 is corrupt (failed signature check).
 
| [[NCSD]] header in sector 0 is corrupt (failed signature check).
 
|}
 
|}
 +
 +
== Hardware Failure indications ==
 +
When a hardware failure is detected, a LED indicator is shown.
 +
 +
If you replace a Nintendo 3ds console's screen with another Nintendo 3ds model's screen, the console powers on, the screens stays black, but after a minute, the wireless LED blinks four times, stays on for a second, then powers off. The blue led stays on, though.
 +
 +
We do not have much information about this as usually, when a hardware failure is detected, the console crashes or powers off immediately.
    
== Tools ==
 
== Tools ==
 
* [https://github.com/yellows8/boot9_tools boot9_tools]
 
* [https://github.com/yellows8/boot9_tools boot9_tools]
Trusted
225

edits

Navigation menu