Changes

Jump to navigation Jump to search
872 bytes added ,  12:33, 6 January 2021
add a couple new bootrom error codes observed when firm0 and firm1 were corrupt
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 20: Line 20:     
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 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 25: 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.
+
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 59: 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 81: 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 123: Line 123:  
* 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.
+
* 8bit-entry-array 0x1FFFE000+0xC: 8bit status-codes initialized by boot9 main(), for the FIRM-boot devices. +0 is NAND, +1 is NTRCARD and +2 is wifi-spiflash.
 
* ...
 
* ...
 
* 8bit-entry-array 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.
Line 144: Line 144:  
| 0xDF(~32)
 
| 0xDF(~32)
 
| Failed to read sector data from the device.
 
| Failed to read sector data from the device.
 +
|-
 +
| 0xCF(~48)
 +
| FIRM section validation function failed: FIRM section is invalid.
 
|-
 
|-
 
| 0xF7(~8)
 
| 0xF7(~8)
Line 187: Line 190:  
   ...
 
   ...
 
    
 
    
   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 265: Line 268:     
* 0 seconds - unit is powered on. The ARM9 and ARM11 [[Memory_layout|bootroms]] begin execution.
 
* 0 seconds - unit is powered on. The ARM9 and ARM11 [[Memory_layout|bootroms]] begin execution.
 
+
* <= ~1 second - BootROMs fully run, load FIRM, etc. The loaded FIRM begins running.
* 2 seconds - ARM9 bootrom attempts to initialize the NAND.
+
**The ARM11 sysmodules included with FIRM are launched by ARM11-kernel, etc.
**If the NAND is successfully initialized:
+
**The [[Process_Manager_Services|PM]] module launches [[NS]].
***the ARM9 bootrom loads the [[FIRM|firmware]] stored in the NAND [[FIRM]] partition which handles booting the rest of the system (if verification for NAND firm0 fails, the ARM9 bootrom will attempt to use firm1 instead).
  −
***The ARM11 kernel loaded from FIRM then launches the [[NCCH#CXI|CXI]] ARM11 system modules loaded from FIRM (i.e. sm, fs, pm, loader, and pxi). (Note that the ARM11 kernel does not handle any encryption/RSA verification, this is handled by the [[FIRM|ARM9]].)
  −
**If the NAND cannot be initialized (i.e. the NAND chip is not connected/damaged/etc), a [[Bootloader#Error_Codes|blue error screen]] appears.
  −
 
  −
* 3 seconds - all essential hardware is active.
  −
**The [[Process_Manager_Services|PM]] module launches [[NS]]
   
**If [[Home_Menu#Auto-Boot_Function|auto-booting]] is needed, NS will [[NS#Auto-boot|auto-boot]] titles.
 
**If [[Home_Menu#Auto-Boot_Function|auto-booting]] is needed, NS will [[NS#Auto-boot|auto-boot]] titles.
 
**Otherwise, NS will instead launch [[ErrDisp]] and the [[Configuration Memory#ACTIVEMENUTID|current active menu]] via the PM module. For retail units, this menu is usually the [[Home Menu]]. Note that the PM module first launches the module dependencies when launching a process, prior to actually launching the process.
 
**Otherwise, NS will instead launch [[ErrDisp]] and the [[Configuration Memory#ACTIVEMENUTID|current active menu]] via the PM module. For retail units, this menu is usually the [[Home Menu]]. Note that the PM module first launches the module dependencies when launching a process, prior to actually launching the process.
**The further Home Menu startup process is described [[Home_Menu#Home_Menu_startup|here]].
+
**The further Home Menu startup process is described [[Home_Menu#Home_Menu_startup|here]]. This includes Home Menu manually launching various sysmodules.
    
* 4 seconds - the LCD screens are initialized.
 
* 4 seconds - the LCD screens are initialized.
Line 335: Line 332:  
| <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>

Navigation menu