https://www.3dbrew.org/w/api.php?action=feedcontributions&user=Nicholatian&feedformat=atom3dbrew - User contributions [en]2024-03-28T23:04:02ZUser contributionsMediaWiki 1.35.8https://www.3dbrew.org/w/index.php?title=Memory_layout&diff=17558Memory layout2016-06-23T10:27:16Z<p>Nicholatian: More code tags</p>
<hr />
<div>= Physical Memory =<br />
<br />
== ARM11 ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Old 3DS<br />
! Address<br />
! Size<br />
! Description<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x00000000</code><br />
| <code>0x10000</code><br />
| Boot ROM (super secret code/data @ 0x8000)<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x10000</code><br />
| <code>0x10000</code><br />
| Boot ROM mirror<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x10000000</code><br />
| ''Unknown''<br />
| [[IO]] memory<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x17E00000</code><br />
| <code>0x2000</code><br />
| MPCore private memory region<br />
<br />
|-<br />
| style="background: red" | No<br />
| <code>0x17E10000</code><br />
| <code>0x1000</code><br />
| L2C-310 Level 2 Cache Controller (2MB)<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x18000000</code><br />
| <code>0x600000</code><br />
| VRAM (divided in two banks, VRAM and VRAMB)<br />
|-<br />
| style="background: red" | No<br />
| <code>0x1F000000</code><br />
| <code>0x400000</code><br />
| [[New 3DS]] additional memory<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x1FF00000</code><br />
| <code>0x80000</code><br />
| DSP memory<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x1FF80000</code><br />
| <code>0x80000</code><br />
| AXI WRAM<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x20000000</code><br />
| <code>0x8000000</code><br />
| FCRAM<br />
|-<br />
| style="background: red" | No<br />
| <code>0x28000000</code><br />
| <code>0x8000000</code><br />
| [[New 3DS]] FCRAM extension<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0xFFFF0000</code><br />
| <code>0x10000</code><br />
| Boot ROM mirror<br />
|}<br />
<br />
===0x17E10000===<br />
The 32-bit register at <code>0x17E10000</code>+<code>0x100</code> only has bit 0 set when, on New 3DS, [[PTMSYSM:ConfigureNew3DSCPU]] was used with bit 1 set for the input value (the L2 cache flag). All other bits in this register are normally all-zero. Therefore, bit 0 set = new cache hardware enabled, bit 0 clear = new cache hardware disabled. This bit is how the ARM11 kernel checks whether the additional cache hardware is enabled).<br />
<br />
To enable the additional cache hardware, the following is used by the ARM11 kernel:<br />
* Sets bit 0 in 32-bit register <code>0x17E10000</code>+<code>0x100</code>.<br />
<br />
To disable the additional cache hardware, the following is used by the ARM11 kernel:<br />
* Writes value <code>0xFFFF</code> to 32-bit register <code>0x17E10000</code>+<code>0x77C</code>.<br />
* Waits for bit 0 in 32-bit register <code>0x17E10000</code>+<code>0x730</code> to become clear.<br />
* Writes value <code>0x0<code> to 32-bit register <code>0x17E10000</code>+<code>0x0</code>.<br />
* Clears bit 0 in 32-bit register <code>0x17E10000</code>+<code>0x100</code>.<br />
<br />
=== <code>0x1F000000</code> ([[New 3DS]] only) ===<br />
This area is used by [[QTM Services]],starting at offset <code>0x200000</code>, size <code>0x180000</code>. This area is not accessible to the GPU on the old 3DS. The old 3DS and New 3DS GSP module has <code>vaddr-&gt;physaddr</code> conversion code for this entire region. On the New 3DS, only the first <code>0x200000</code> bytes (half of this memory) are accessible to the GPU.<br />
<br />
== ARM9 ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Old 3DS<br />
! Address<br />
! Size<br />
! Description<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x00000000</code><br />
| <code>0x8000000</code><br />
| Instruction TCM, repeating each <code>0x8000</code> bytes.<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x01FF8000</code><br />
| <code>0x8000</code><br />
| Instruction TCM (Accessed by the kernel and process by this address)<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x07FF8000</code><br />
| <code>0x8000</code><br />
| Instruction TCM (Accessed by bootrom by this address)<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x08000000</code><br />
| <code>0x100000</code><br />
| ARM9-only internal memory (ARM7's internal regions are mapped here as well)<br />
|-<br />
| style="background: red" | No<br />
| <code>0x08100000</code><br />
| <code>0x80000</code><br />
| [[New 3DS]] ARM9-only extension, only enabled when a certain [[CONFIG_Registers|CONFIG]] register is set.<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x10000000</code><br />
| <code>0x8000000</code><br />
| [[IO]] memory<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x18000000</code><br />
| <code>0x600000</code><br />
| VRAM (divided in two banks, VRAM and VRAMB) <br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x1FF00000</code><br />
| <code>0x80000</code><br />
| DSP memory<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x1FF80000</code><br />
| <code>0x80000</code><br />
| AXI WRAM<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0x20000000</code><br />
| <code>0x8000000</code><br />
| FCRAM<br />
|-<br />
| style="background: red" | No<br />
| <code>0x28000000</code><br />
| <code>0x8000000</code><br />
| [[New 3DS]] FCRAM extension<br />
|-<br />
| style="background: gre</code>en" | Yes<br />
| <code>0xFFF00000</code><br />
| <code>0x4000</code><br />
| Data TCM (Mapped during boot ROM)<br />
|-<br />
| style="background: green" | Yes<br />
| <code>0xFFFF0000</code><br />
| <code>0x10000</code><br />
| Boot ROM, the main region is at +<code>0x8000</code>, which is disabled during system boot.<br />
|}<br />
<br />
==ARM9 MPU Regions==<br />
For the below instruction permissions: RO = memory is executable, while None = not-executable.<br />
<br />
===NATIVE_FIRM/SAFE_MODE_FIRM ARM9 kernel===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 1MB/0x100000. >=[[8.0.0-18|8.0.0-X]]: 2MB/0x200000.<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 128KB/0x20000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 4<br />
| 0x10100000<br />
| 512KB/0x80000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 5<br />
| 0x20000000<br />
| 128MB/0x8000000. >=[[8.0.0-18|8.0.0-X]]: 256MB/0x10000000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 6<br />
| 0x08000000<br />
| 128KB/0x20000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 7<br />
| 0x08020000<br />
| <[[3.0.0-5]]: 64KB/0x10000. >=[[3.0.0-5]]: 32KB/0x8000.<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|}<br />
<br />
The above is the MPU region settings setup by the ARM9-kernel in the crt0.<br />
<br />
The New3DS ARM9-kernel MPU region settings are the same as the Old3DS MPU region settings for >=[[8.0.0-18|8.0.0-X]].<br />
<br />
At the start of the Process9 function executed in kernel-mode via svc7b during firm-launching, it changes some MPU region settings. At the end of that function, before it uses the ARM9/ARM11 entrypoint fields, it disables MPU.<br />
<br />
===New3DS [[FIRM|ARM9-loader]]===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 2MB/0x200000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 128KB/0x20000<br />
| RW<br />
| None<br />
| None<br />
| None<br />
|}<br />
<br />
MPU regions 4-7 are disabled. Note that the entire ARM9-loader runs in SVC-mode.<br />
<br />
===TWL_FIRM/AGB_FIRM ARM9 kernel===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Region<br />
! Address<br />
! Size<br />
! Privileged-mode data permissions<br />
! User-mode data permissions<br />
! Privileged-mode instruction permissions<br />
! User-mode instruction permissions<br />
|-<br />
| 0<br />
| 0xFFFF0000<br />
| 32KB/0x8000<br />
| RO<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 1<br />
| 0x01FF8000<br />
| 32KB/0x8000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 2<br />
| 0x08000000<br />
| 1MB/0x100000. New3DS: 2MB/0x200000.<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|-<br />
| 3<br />
| 0x10000000<br />
| 2MB/0x200000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 4<br />
| 0x1FF00000<br />
| 512KB/0x80000<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 5<br />
| 0x20000000<br />
| 128MB/0x8000000. New3DS: 256MB/0x10000000.<br />
| RW<br />
| RW<br />
| None<br />
| None<br />
|-<br />
| 6<br />
| 0x08000000<br />
| <[[3.0.0-5|3.0.0-X]]: 256KB/0x40000. >=[[3.0.0-5|3.0.0-X]]: 128KB/0x20000<br />
| RW<br />
| None<br />
| RO<br />
| None<br />
|-<br />
| 7<br />
| 0x08080000<br />
| 128KB/0x20000<br />
| RW<br />
| RW<br />
| RO<br />
| RO<br />
|}<br />
<br />
==ARM9 ITCM==<br />
{| class="wikitable" border="1"<br />
|-<br />
! ITCM mirror address<br />
! ITCM bootrom mirror address<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x01FF8000<br />
| <br />
| 0x0<br />
| 0x3700<br />
| Uninitialized memory.<br />
|-<br />
| 0x01FFB700<br />
| 0x07FFB700<br />
| 0x3700<br />
| 0x100<br />
| The unprotected ARM9-bootrom code copies code from unprotected bootrom to 0x07FFB700(ITCM mirror) size 0x100, then calls the code at 0x07FFB700. The code located here is the code used for disabling access to the bootroms.<br />
|-<br />
| 0x01FFB800<br />
| <br />
| 0x3800<br />
| 0x4<br />
| This is always 0xDEADB00F.<br />
|-<br />
| 0x01FFB804<br />
| <br />
| 0x3804<br />
| 0x4<br />
| This is the u32 DeviceId.<br />
|-<br />
| 0x01FFB808<br />
| <br />
| 0x3808<br />
| 0x10<br />
| This is the fall-back keyY used for movable.sed keyY when movable.sed doesn't exist in NAND(the last two words here are used on retail for generating console-unique TWL keydata/etc). This is also used for "LocalFriendCodeSeed", etc.<br />
|-<br />
| 0x01FFB818<br />
| <br />
| 0x3818<br />
| 0x1<br />
| ?<br />
|-<br />
| 0x01FFB819<br />
| <br />
| 0x3819<br />
| 0x1<br />
| This is the [[CTCert]] issuer type: 0 = retail "Nintendo CA - G3_NintendoCTR2prod", non-zero = dev "Nintendo CA - G3_NintendoCTR2dev".<br />
|-<br />
| 0x01FFB81A<br />
| <br />
| 0x381A<br />
| 0x6<br />
| ?<br />
|-<br />
| 0x01FFB820<br />
| <br />
| 0x3820<br />
| 0x4<br />
| This is the CTCert ECDSA exponent, this is byte-swapped when *((u8*)(0x01FFB800+0x18)) is >=5.<br />
|-<br />
| 0x01FFB824<br />
| <br />
| 0x3824<br />
| 0x2<br />
| ?<br />
|-<br />
| 0x01FFB826<br />
| <br />
| 0x3826<br />
| 0x1E<br />
| This is the CTCert ECDSA privk.<br />
|-<br />
| 0x01FFB844<br />
| <br />
| 0x3844<br />
| 0x3C<br />
| This is the CTCert ECDSA signature.<br />
|-<br />
| 0x01FFB880<br />
| <br />
| 0x3880<br />
| 0x80<br />
| This is all-zero.<br />
|-<br />
| 0x01FFB900<br />
| <br />
| 0x3900<br />
| 0x200<br />
| This is the 0x200-bytes from NAND sector0.<br />
|-<br />
| 0x01FFBB00<br />
| <br />
| 0x3B00<br />
| 0x200<br />
| This is the 0x200-bytes from the plaintext NAND firm partition FIRM header, read by bootrom.<br />
|-<br />
| 0x01FFBD00<br />
| <br />
| 0x3D00<br />
| 0x100<br />
| This is the RSA-2048 modulus for [[RSA_Registers|RSA]]-engine slot0 set by bootrom.<br />
|-<br />
| 0x01FFBE00<br />
| <br />
| 0x3E00<br />
| 0x100<br />
| This is the RSA-2048 modulus for RSA-engine slot1 set by bootrom.<br />
|-<br />
| 0x01FFBF00<br />
| <br />
| 0x3F00<br />
| 0x100<br />
| This is the RSA-2048 modulus for RSA-engine slot2.<br />
|-<br />
| 0x01FFC000<br />
| <br />
| 0x4000<br />
| 0x100<br />
| This is the RSA-2048 modulus for RSA-engine slot3.<br />
|-<br />
| 0x01FFC100<br />
| <br />
| 0x4100<br />
| 0x800<br />
| These are RSA-2048 keys: 4 slots, each slot is 0x200-bytes. Slot+0 is the modulus, slot+0x100 is the private exponent. This can be confirmed by RSA-decrypting a message into a signature, then RSA-encrypting the signature back into a message, and comparing the original message with the output from the last operation.<br />
<br />
[[FIRM]] doesn't seem to ever use these. None of these are related to RSA-keyslot0 used for v6.0/v7.0 key generation. These moduli are separate from all other moduli used elsewhere.<br />
|-<br />
| 0x01FFC900<br />
| 0x07FFC900<br />
| 0x4900<br />
| 0x400<br />
| The unprotected ARM9-bootrom copies data to 0x07FFC900(mirror of 0x01FFC900) size 0x400. This data is copied from AXI WRAM, initialized by ARM11-bootrom(the addr used for the src is determined by [[CONFIG_Registers|REG_UNITINFO]]). These are RSA moduli: retailsrcptr = 0x1FFFD000, devsrvptr = 0x1FFFD400.<br />
* The first 0x100-bytes here is the RSA-2048 modulus for the CFA NCCH header, and for the gamecard NCSD header.<br />
* 0x01FFCA00 is the RSA-2048 modulus for the CXI accessdesc signature, written to rsaengine keyslot1 by NATIVE_FIRM.<br />
* 0x01FFCB00 size 0x200 is unknown, probably RSA related, these aren't used by [[FIRM]](these are not console-unique).<br />
|-<br />
| 0x01FFCD00<br />
| <br />
| 0x4D00<br />
| 0x80<br />
| Unknown, not used by [[FIRM]]. This isn't console-unique.<br />
The first 0x10-bytes are checked by the v6.0/v7.0 NATIVE_FIRM keyinit function, when non-zero it clears this block and continues to do the key generation. Otherwise when this block was already all-zero, it immediately returns. This memclear was probably an attempt at destroying the RSA slot0 modulus, that missed (exactly 0x1000-bytes away). Even though they "failed" here, one would still need to derive the private exponent, which would require obtaining a ciphertext and plaintext.<br />
|-<br />
| 0x01FFCD80<br />
| <br />
| 0x4D80<br />
| 0x64<br />
| 0x01FFCD84 size 0x10-bytes is the NAND CID(the 0x64-byte region at 0x01FFCD80 is initialized by Process9 + ARM9-bootrom). The u32 at 0x01FFCDC4 is the total number of NAND sectors, read from a MMC command.<br />
|-<br />
| 0x01FFCDE4<br />
| <br />
| 0x4DE4<br />
| 0x21C<br />
| Uninitialized memory.<br />
|-<br />
| 0x01FFD000<br />
| 0x07FFD000<br />
| 0x5000<br />
| 0x2470<br />
| The unprotected ARM9-bootrom copies 0x1FFFA000(AXIWRAM mem initialized by ARM11-bootrom) size 0x2470 to 0x07FFD000(mirror of 0x01FFD000). This block contains DSi keys.<br />
* 0x01FFD000 is the RSA-1024 modulus for the retail System Menu<br />
* 0x01FFD080 is the RSA-1024 modulus for DSi Wifi firmware and DSi Sound<br />
* 0x01FFD100 is the RSA-1024 modulus for base DSi apps (Settings, Shop, etc.)<br />
* 0x01FFD180 is the RSA-1024 modulus for DSiWare and RSA-signed cartridge headers<br />
* 0x01FFD210 is the keyY for per-console-encrypted ES blocks<br />
* 0x01FFD220 is the keyY for fixed-keyX ES blocks<br />
* 0x01FFD300 is the DSi common (normal)key<br />
* 0x01FFD350 is a normalkey set on keyslot 0x02, and is likely only used during boot<br />
* 0x01FFD380 is the keyslot 0x00 keyX and the first half of the retail keyX for modcrypt crypto "Nintendo"<br />
* 0x01FFD398 is the keyX used for 'Tad' crypto, usually in keyslot 0x02 "Nintendo DS", ..<br />
* 0x01FFD3A8 is set as the middle two words of keyslot 0x03's keyX, before being overwritten "NINTENDO"<br />
* 0x01FFD3BC is the keyY for keyslot 0x01, see below<br />
* 0x01FFD3C8 is the fixed keyY used for eMMC partition crypto on retail DSi, see below (keyslot 0x03)<br />
* 0x01FFD3E0 is the 0x1048-byte Blowfish data for DSi cart crypto<br />
* 0x01FFE428 is the 0x1048-byte Blowfish data for DS cart crypto<br />
On the 3DS, keyslots 0x01 and 0x03 have the last word set as 0xE1A00005 instead of the next word in ITCM. This is consistent with retail DSis.<br />
|-<br />
| 0x01FFF470<br />
| <br />
| 0x7470<br />
| 0xB90<br />
| Uninitialized memory.<br />
0x01FFFC00 size 0x100-bytes starting with [[9.5.0-22|9.5.0-X]] is the FIRM header used during FIRM-launching.<br />
|}<br />
<br />
=Memory map by firmware=<br />
* [[Virtual address mapping FW0B]]<br />
* [[Virtual address mapping FW1F]]<br />
* [[Virtual address mapping FW25]]<br />
* [[Virtual address mapping FW2E]]<br />
* [[Virtual address mapping FW37]]<br />
* [[Virtual address mapping FW38]]<br />
* [[Virtual address mapping FW3F]]<br />
* FW49([[9.6.0-24|9.6.0-X]]) and [[10.0.0-27|10.0.0-X]] ARM11-kernel vmem mapping is identical to FW40([[9.5.0-22|9.5.0-X]]).<br />
<br />
<br />
* [[Virtual address mapping TWLFIRM04]]<br />
<br />
<br />
* [[Virtual address mapping New3DS v8.1]]<br />
* [[Virtual address mapping New3DS v9.0]]<br />
* [[Virtual address mapping New3DS v9.2]]<br />
<br />
=ARM11 Detailed physical memory map=<br />
18000000 - 18600000: VRAM<br />
<br />
1FF80000 - 1FFAB000: Kernel code<br />
1FFAB000 - 1FFF0000: SlabHeap [temporarily contains boot processes]<br />
1FFF0000 - 1FFF1000: ?<br />
1FFF1000 - 1FFF2000: ?<br />
1FFF2000 - 1FFF3000: ?<br />
1FFF3000 - 1FFF4000: ?<br />
1FFF4000 - 1FFF5000: Exception vectors<br />
1FFF5000 - 1FFF5800: Unused?<br />
1FFF5800 - 1FFF5C00: 256-entry L2 MMU table for VA FF4xx000<br />
1FFF5C00 - 1FFF6000: 256-entry L2 MMU table for VA FF5xx000<br />
1FFF6000 - 1FFF6400: 256-entry L2 MMU table for VA FF6xx000<br />
1FFF6400 - 1FFF6800: 256-entry L2 MMU table for VA FF7xx000<br />
1FFF6800 - 1FFF6C00: 256-entry L2 MMU table for VA FF8xx000<br />
1FFF6C00 - 1FFF7000: 256-entry L2 MMU table for VA FF9xx000<br />
1FFF7000 - 1FFF7400: 256-entry L2 MMU table for VA FFAxx000<br />
1FFF7400 - 1FFF7800: 256-entry L2 MMU table for VA FFBxx000<br />
1FFF7800 - 1FFF7C00: MMU table but unused?<br />
1FFF7C00 - 1FFF8000: 256-entry L2 MMU table for VA FFFxx000 <br />
1FFF8000 - 1FFFC000: 4096-entry L1 MMU table for VA xxx00000 (CPU 0)<br />
1FFFC000 - 20000000: 4096-entry L1 MMU table for VA xxx00000 (CPU 1)<br />
20000000 - 28000000: Main memory<br />
<br />
The entire FCRAM is cleared during NATIVE_FIRM boot. This is done by the ARM11 kernel in order by region as it initializes after loading [[FIRM]] launch parameters from FCRAM.<br />
<br />
== FCRAM memory-regions layout ==<br />
{| class="wikitable" border="1"<br />
! [[Configuration_Memory#APPMEMTYPE|Configmem-APPMEMTYPE]] Value<br />
! Base address relative to FCRAM+0, for APPLICATION mem-region<br />
! Region size, for APPLICATION mem-region<br />
! Base address relative to FCRAM+0, for SYSTEM mem-region<br />
! Region size, for SYSTEM mem-region<br />
! Base address relative to FCRAM+0, for BASE mem-region<br />
! Region size, for BASE mem-region<br />
|-<br />
| 0 (default with regular 3DS kernel, used when the type is not 2-5)<br />
| 0x0<br />
| 0x04000000(64MB)<br />
| 0x04000000<br />
| 0x02C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 2<br />
| 0x0<br />
| 0x06000000(96MB)<br />
| 0x06000000<br />
| 0x00C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 3<br />
| 0x0<br />
| 0x05000000(80MB)<br />
| 0x05000000<br />
| 0x01C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 4<br />
| 0x0<br />
| 0x04800000(72MB)<br />
| 0x04800000<br />
| 0x02400000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 5<br />
| 0x0<br />
| 0x02000000(32MB)<br />
| 0x02000000<br />
| 0x04C00000<br />
| 0x06C00000<br />
| 0x01400000<br />
|-<br />
| 6 (This is the default on New3DS. With [[New_3DS]] kernel this is the type used when the value is not 7)<br />
| 0x0<br />
| 0x07C00000(124MB)<br />
| 0x07C00000<br />
| 0x06400000<br />
| 0x0E000000<br />
| 0x02000000<br />
|-<br />
| 7<br />
| 0x0<br />
| 0x0B200000(178MB)<br />
| 0x0B200000<br />
| 0x02E00000<br />
| 0x0E000000<br />
| 0x02000000<br />
|}<br />
<br />
The SYSTEM mem-region size is calculated with: size = FCRAMTOTALSIZE - (APPLICATION_MEMREGIONSIZE + BASE_MEMREGIONSIZE).<br />
<br />
Support for type6/7 was [[NCCH/Extended Header|implemented]] in [[NS]] with [[8.0.0-18]], these are only supported in the [[New_3DS]] ARM11-kernel not the regular 3DS kernel. These two types are the only ones supported by the New3DS kernel.<br />
<br />
All memory allocated by the kernel itself for kernel use is located under BASE. Most system-modules run under the BASE memregion too.<br />
<br />
Free/used memory on [[4.5.0-10]] with Home Menu / Internet Browser, with the default APPMEMTYPE on retail:<br />
{| class="wikitable" border="1"<br />
! Region<br />
! Base address relative to FCRAM+0<br />
! Region size<br />
! Used memory once [[Home Menu]] finishes loading for system boot, on [[4.5.0-10]]<br />
! Used memory with [[Internet Browser]] running instead of [[Home Menu]], on [[4.5.0-10]]<br />
! Free memory once [[Home Menu]] finishes loading for system boot, on [[4.5.0-10]]<br />
! Free memory with [[Internet Browser]] running instead of [[Home Menu]], on [[4.5.0-10]]<br />
|-<br />
| APPLICATION<br />
| 0x0<br />
| 0x04000000<br />
| 0x0<br />
| <br />
| 0x04000000<br />
| <br />
|-<br />
| SYSTEM<br />
| 0x04000000<br />
| 0x02C00000<br />
| 0x01488000<br />
| 0x02A50000<br />
| 0x01778000<br />
| 0x001B0000<br />
|-<br />
| BASE<br />
| 0x06C00000<br />
| 0x01400000<br />
| 0x01202000<br />
| 0x01236000<br />
| 0x001FE000<br />
| 0x001CA000<br />
|}<br />
<br />
=ARM11 Detailed virtual memory map=<br />
(valid only for FW0B, see [[#Memory map by firmware|Memory map by firmware]] for subsequent versions)<br />
<br />
E8000000 - E8600000: mapped VRAM (18000000 - 18600000)<br />
<br />
EFF00000 - F0000000: mapped Internal memory (1FF00000 - 20000000)<br />
F0000000 - F8000000: mapped Main memory<br />
<br />
FF401000 - FF402000: mapped ? (27FC7000 - 27FC8000)<br />
<br />
FF403000 - FF404000: mapped ? (27FC2000 - 27FC3000)<br />
<br />
FF405000 - FF406000: mapped ? (27FBB000 - 27FBC000)<br />
<br />
FF407000 - FF408000: mapped ? (27FB3000 - 27FB4000)<br />
<br />
FF409000 - FF40A000: mapped ? (27F8E000 - 27F8F000)<br />
<br />
FFF00000 - FFF45000: mapped SlabHeap <br />
<br />
FFF60000 - FFF8B000: mapped Kernel code<br />
<br />
FFFCC000 - FFFCD000: mapped IO [[I2C|I2C]] second bus (10144000 - 10145000)<br />
<br />
FFFCE000 - FFFCF000: mapped IO PDC([[LCD]]) (10400000 - 10401000)<br />
<br />
FFFD0000 - FFFD1000: mapped IO PDN (10141000 - 10142000)<br />
<br />
FFFD2000 - FFFD3000: mapped IO PXI (10163000 - 10164000)<br />
<br />
FFFD4000 - FFFD5000: mapped IO PAD (10146000 - 10147000)<br />
<br />
FFFD6000 - FFFD7000: mapped IO LCD (10202000 - 10203000)<br />
<br />
FFFD8000 - FFFD9000: mapped IO DSP (10140000 - 10141000)<br />
<br />
FFFDA000 - FFFDB000: mapped IO XDMA (10200000 - 10201000)<br />
<br />
FFFDC000 - FFFE0000: mapped ? (1FFF8000 - 1FFFC000)<br />
<br />
FFFE1000 - FFFE2000: mapped ? (1FFF0000 - 1FFF1000)<br />
<br />
FFFE3000 - FFFE4000: mapped ? (1FFF2000 - 1FFF3000)<br />
<br />
FFFE5000 - FFFE9000: mapped L1 MMU table for VA xxx00000<br />
<br />
FFFEA000 - FFFEB000: mapped ? (1FFF1000 - 1FFF2000)<br />
<br />
FFFEC000 - FFFED000: mapped ? (1FFF3000 - 1FFF4000)<br />
<br />
FFFEE000 - FFFF0000: mapped IO IRQ (17E00000 - 17E02000)<br />
<br />
FFFF0000 - FFFF1000: mapped Exception vectors<br />
<br />
FFFF2000 - FFFF6000: mapped L1 MMU table for VA xxx00000<br />
<br />
FFFF7000 - FFFF8000: mapped ? (1FFF1000 - 1FFF2000)<br />
<br />
FFFF9000 - FFFFA000: mapped ? (1FFF3000 - 1FFF4000)<br />
<br />
FFFFB000 - FFFFE000: mapped L2 MMU tables (1FFF5000 - 1FFF8000)<br />
<br />
==0xFF4XX000==<br />
Each [[KThread|thread]] is allocated a 0x1000-byte page in this region: the first page at 0xFF401000 is for the first created thread, 0xFF403000 for the second thread. This region is used to store the SVC-mode stack for the thread, and thread context data used for context switching. When the IRQ handler, prefetch/data abort handlers, and undefined instruction handler are entered where the SPSR-mode=user, these handlers then store LR+SPSR for the current mode on the SVC-mode stack, then these handlers switch to SVC-mode.<br />
<br />
This page does not contain a dedicated block for storing R0-PC(etc). For user-mode, the user-mode regs are instead saved on the SVC-mode stack when IRQs such as timers for context switching are triggered.<br />
<br />
Structure of this page, relative to page_endaddr-0xC8:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| 0x0<br />
| <br />
| SVC-mode stack-top. The 0x10-byte SVC-access-control for this thread is also located here, which is checked by the SVC-handler.<br />
|-<br />
| 0x18<br />
| 0x28<br />
| SVC-mode saved registers, stored/loaded during context switches: R4-R9, SL, FP, SP, LR. After loading these registers, the context switch code will jump to the loaded LR.<br />
|-<br />
| 0xC0<br />
| 4<br />
| fpexc from vmrs, used during context switches with the above saved registers.<br />
|}<br />
<br />
For NATIVE_FIRM the memory pages for this region are located in FCRAM, however for TWL_FIRM these are located in AXI WRAM. For TWL_FIRM v6704 the first thread's page for this region is located at physical address 0x1FF93000, the next one at 0x1FF92000, etc.<br />
<br />
== IO Process virtual addressing equivalence ==<br />
It seems an IO register's process virtual address can be calculated by adding 0xEB00000 to its physical address. However for kernel mappings there is no fixed address equivalence.<br />
<br />
=ARM11 User-land memory regions=<br />
==NATIVE_FIRM/SAFE_MODE_FIRM Userland Memory==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Virtual Address Base<br />
! Physical Address Base<br />
! Region Max Size<br />
! Address-range available for svcMapMemoryBlock<br />
! Description<br />
|-<br />
| 0x00100000 / 0x14000000<br />
| <br />
| 0x03F00000<br />
| No<br />
| The [[ExeFS]]:/.code is loaded here, executables must be loaded to the 0x00100000 region when the exheader "special memory" flag is clear. The 0x03F00000-byte size restriction only applies when this flag is clear. Executables are usually loaded to 0x14000000 when the exheader "special memory" flag is set, however this address can be arbitrary.<br />
|-<br />
| 0x04000000<br />
| ?<br />
| ?<br />
| No<br />
| Used for mapping buffers during IPC, see [[IPC Command Structure]].<br />
|-<br />
| 0x08000000<br />
| Main stack physaddr - <heap size for the allocated vaddr 0x08000000 memory><br />
| 0x08000000<br />
| Yes<br />
| Heap mapped by [[SVC|ControlMemory]]<br />
|-<br />
| 0x10000000-StackSize<br />
| .bss physical address - total stack pages<br />
| StackSize from process exheader<br />
| <br />
| Stack for the main-thread, initialized by the ARM11 kernel. The StackSize from the exheader is usually 0x4000, therefore the stack-bottom is usually 0x0FFFC000. The stack for the other threads is normally located in the process .data section however this can be arbitrary.<br />
|-<br />
| 0x10000000<br />
| <br />
| 0x04000000<br />
| Yes<br />
| [[SVC|Shared]] memory<br />
|-<br />
| 0x14000000<br />
| FCRAM+0<br />
| 0x08000000<br />
| No<br />
| Can be mapped by [[SVC|ControlMemory]], this is used for processes' [[SVC|LINEAR]]/GSP heap.<br />
|-<br />
| 0x1E800000<br />
| 0x1F000000<br />
| 0x00400000<br />
| No<br />
| [[New_3DS]] additional memory, access to this is specified by the exheader. Added with [[8.0.0-18]], see above section regarding this memory.<br />
|-<br />
| 0x1EC00000<br />
| 0x10100000<br />
| 0x01000000<br />
| No<br />
| [[IO]] registers, the mapped IO pages which each process can access is specified in the [[NCCH/Extended_Header|exheader]]. (Applications normally don't have access to registers in this range)<br />
|-<br />
| 0x1F000000<br />
| 0x18000000<br />
| 0x00600000<br />
| No<br />
| VRAM, access to this is specified by the exheader.<br />
|-<br />
| 0x1FF00000<br />
| 0x1FF00000<br />
| 0x00080000<br />
| No<br />
| DSP memory, access to this is specified by the exheader.<br />
|-<br />
| 0x1FF80000<br />
| FCRAM memory page allocated by the ARM11 kernel.<br />
| 0x1000<br />
| No<br />
| [[Configuration Memory]], all processes have read-only access to this.<br />
|-<br />
| 0x1FF81000<br />
| FCRAM memory page allocated by the ARM11 kernel.<br />
| 0x1000<br />
| No<br />
| [[Configuration Memory|Shared]] page, all processes have read-access to this. Write access to this is specified by the exheader "Shared page writing" kernel flag.<br />
|-<br />
| 0x1FF82000<br />
| Dynamically taken from the BASE region of FCRAM<br />
| Number of threads * 0x1000 / 8<br />
| No<br />
| [[Thread Local Storage]]<br />
|-<br />
| 0x30000000<br />
| FCRAM+0<br />
| 0x08000000(Old3DS) / 0x10000000([[New_3DS]])<br />
| No<br />
| This LINEAR memory mapping was added with [[8.0.0-18]], see [[SVC#enum_MemoryOperation|here]]. This replaces the original 0x14000000 mapping, for system(memory-region=BASE)/newer titles. The Old3DS kernel uses size 0x08000000 for LINEAR-memory address range checks, while the New3DS kernel uses size 0x10000000 for those range checks. Old3DS/New3DS system-module code doing vaddr->phys-addr conversion uses size 0x10000000.<br />
|-<br />
| 0x20000000 / 0x40000000<br />
| <br />
| <br />
| <br />
| This is the end-address of userland memory, memory under this address is process-unique. Memory starting at this address is only accessible in privileged-mode. This address was changed from 0x20000000 to 0x40000000 with [[8.0.0-18]].<br />
|}<br />
<br />
All executable pages are read-only, and data pages have the execute-never permission set. Normally .text from the loaded ExeFS:/.code is the only mapped executable memory. Executable [[RO Services|CROs]] can be loaded into memory, once loaded the CRO .text section memory page permissions are changed via [[SVC|ControlProcessMemory]] from RW- to R-X. The address and size of each ExeFS:/.code section is stored in the exheader, the permissions for each section is: .text R-X, .rodata R--, .data RW-, and .bss RW-. The loaded .code is mapped to the addresses specified in the exheader by the ARM11 kernel. The stack permissions is initialized by the ARM11 kernel: RW-. The heap permissions is normally RW-.<br />
<br />
All userland memory is mapped with RW permissions for privileged-mode. However, normally the ARM11 kernel only uses userland read/write instructions(or checks that the memory can be written from userland first) for accessing memory specified by [[SVC|SVCs]].<br />
<br />
Processes can't directly access memory for other processes. When service [[Services API|commands]] are used, the kernel maps memory in the destination process for input/output buffers, where the addresses in the command received by the process is replaced by this mapped memory. When this is an input buffer, the buffer data is copied to the mapped memory. When this is an output buffer, the data stored in the mapped memory is copied to the destination buffer specified in the command.<br />
<br />
The physical address which memory for the application memory-type is mapped to begins at FCRAM+0, the total memory allocated for this memory-type is stored in [[Configuration_Memory]]. Applications' .text + .rodata + .data under the application memory-type is mapped at FCRAM + APPMEMALLOC - (aligned page-size for .text + .rodata + .data). The application .bss is mapped at CODEADDR - .bss size aligned down to the page size.<br />
<br />
==TWL_FIRM Userland Memory==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Virtual Address Base<br />
! Physical Address Base<br />
! Size<br />
! Description<br />
|-<br />
| 0x00100000<br />
| 0x1FFAB000 (with newer TWL_FIRM such as v6704 this is located at 0x1FFAC000)<br />
| 0x00055000<br />
| Code + .(ro)data copied from the process 0x00300000 region is located here(.bss is located here as well).<br />
|-<br />
| 0x00155000<br />
| 0x18555000<br />
| 0x000AB000<br />
| <br />
|-<br />
| 0x00200000<br />
| 0x18500000<br />
| 0x00100000<br />
| <br />
|-<br />
| 0x00300000<br />
| 0x24000000<br />
| 0x04000000<br />
| The beginning of the ARM11 process .text is located here.<br />
|-<br />
| 0x08000000<br />
| 0x20000000<br />
| 0x07E00000<br />
| <br />
|-<br />
| 0x1EC00000<br />
| 0x10100000<br />
| 0x00400000<br />
| [[IO]]<br />
|-<br />
| 0x1F000000<br />
| 0x18000000<br />
| 0x00600000<br />
| VRAM<br />
|-<br />
| 0x1FF00000<br />
| 0x1FF00000<br />
| 0x00080000<br />
| This is mapped to the DSP memory.<br />
|}<br />
<br />
The above regions are mapped by the ARM11 kernel. Later when the ARM11 process uses [[SVC|svcKernelSetState]] with type4, the kernel unmaps(?) the following regions: 0x00300000..0x04300000, 0x08000000..0x0FE00000, and 0x10000000..0xF8000000.<br />
<br />
=== Detailed TWL_FIRM ARM11 Memory ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Process Virtual Address<br />
! Physical Address<br />
! Size<br />
! Description<br />
|-<br />
| 0x08000000<br />
| 0x20000000<br />
| 0x01000000*4<br />
| DS(i) 0x02000000 RAM. Vaddr = (DSRAMOffset*4) + 0x08000000, where DSRAMOffset is DSRAMAddr-0x02000000.<br />
|-<br />
| 0x0FC00000<br />
| 0x27C00000<br />
| <br />
| Loaded SRL binary, initially the dev DSi launcher SRL is located here(copied here by the ARM11 process).<br />
|-<br />
| 0x0FD00000<br />
| 0x27D00000<br />
| <br />
| The data located here is copied to here by the ARM11 process. The data located here is a TWL NAND [http://dsibrew.org/wiki/Bootloader bootloader] image, using the same format+encryption/verification methods as the DSi NAND bootloader(stage2). The keyX for this bootloader keyslot is initially set to the retail DSi key-data, however when TWL_FIRM is launched this keyX key-data is replaced with a separate keyX. TWL_FIRM can use either the retail DSi bootloader RSA-1024 modulus, or a seperate modulus: normally only the latter is used(the former is only used when loading the image from FS instead of FCRAM). When using the image from FCRAM(default code-path), TWL_FIRM will not calculate+check the hashes for the bootloader code binaries(this is done when loading from FS however).<br />
|-<br />
| 0x0FDF7000<br />
| 0x27DF7000<br />
| 0x1000<br />
| SRL header<br />
|}<br />
<br />
= System memory details =<br />
0xFFFF9000 Pointer to the current KThread instance<br />
0xFFFF9004 Pointer to the current KProcess instance<br />
0xFFFF9008 Pointer to the current KScheduler instance<br />
0xFFFF9010 Pointer to the last KThread to encounter an exception<br />
<br />
0x8000040 Pointer to the current KThread instance on the ARM9<br />
0x8000044 Pointer to the current KProcess instance on the ARM9<br />
0x8000048 Pointer to the current KScheduler instance on the ARM9<br />
<br />
= VRAM Map While Running System Applets =<br />
*0x1E6000-0x22C500 -- top screen 3D left framebuffer 0(240x400x3) (The "3D right first-framebuf" addr stored in the LCD register is set to this, when the 3D is set to "off")<br />
*0x22C800-0x272D00 -- top screen 3D right framebuffer 0(240x400x3)<br />
*0x273000-0x2B9500 -- top screen 3D left framebuffer 1(240x400x3)<br />
*0x2B9800-0x2FFD00 -- top screen 3D right framebuffer 1(240x400x3)<br />
*0x48F000-0x4C7400 -- bottom screen framebuffer 0(240x320x3)<br />
*0x4C7800-0x4FF800 -- bottom screen framebuffer 1(240x320x3)<br />
<br />
These LCD framebuffer addresses are not changed by the system when launching regular applications, the application itself handles that if needed. These VRAM framebuffers are cleared when launching regular applications.</div>Nicholatianhttps://www.3dbrew.org/w/index.php?title=ARM7_Registers&diff=17527ARM7 Registers2016-06-15T19:31:39Z<p>Nicholatian: Fixed up the formatting</p>
<hr />
<div>The 3DS utilizes an onboard ARM7 core to handle <code>TWL_FIRM</code> and <code>AGB_FIRM</code>'s ARM7 requirements. This is due to the fact that much of the hardware used by both ARM7 and ARM9 is (evidently) not physically hooked up to ARM11. Thus, ARM11 cannot simply emulate ARM7.<br />
<br />
ARM7 has the GBA BIOS implemented in hardware. The BIOS is completely identical to the original GBA BIOS. The system is booted silently by calling <code>SWI 0x1</code> (a.k.a. <code>RegisterRamReset</code>), followed by jumping to the code that does <code>SWI 0x0</code> (a.k.a. <code>SoftReset</code>) to finish booting. The boot splash is still in BIOS, however, and can be seen by calling or replacing one of the previous interrupts with <code>SWI 0x26</code> (a.k.a. <code>HardReset</code>).<br />
<br />
==Registers==<br />
ARM9 interfaces with the ARM7 through the following registers:<br />
<br />
{| class="wikitable"<br />
|-<br />
! Type<br />
! Address<br />
! Name<br />
! Size (bytes)<br />
|-<br />
| <code>u8</code><br />
| <code>0x10018000</code><br />
| <code>ARM7_CNT</code><br />
| 1 <br />
|-<br />
| ''Unknown''<br />
| <code>0x10018080</code><br />
| <code>ARM7_CODE</code><br />
| ''?''<br />
|-<br />
| <code>u16</code><br />
| <code>0x10018100</code><br />
| <code>ARM7_SAVE_MODE</code><br />
| 2<br />
|-<br />
| <code>u16</code><br />
| <code>0x10018104</code><br />
| <code>ARM7_?_CNT</code><br />
| 2<br />
|-<br />
| <code>u16</code><br />
| <code>0x10018108</code><br />
| <code>ARM7_RTC_CNT?</code><br />
| 2<br />
|-<br />
| <code>u32</code><br />
| <code>0x10018110</code><br />
| <code>?</code><br />
| 4<br />
|-<br />
| <code>u32</code><br />
| <code>0x10018114</code><br />
| <code>?</code><br />
| 4<br />
|-<br />
| <code>u32</code><br />
| <code>0x10018118</code><br />
| <code>ARM7_RTC_LO?</code><br />
| 4<br />
|-<br />
| <code>u32</code><br />
| <code>0x1001811C</code><br />
| <code>ARM7_RTC_HI?</code><br />
| 4<br />
|-<br />
| <code>arm7_save_cfg_t</code><br />
| <code>0x10018120</code><br />
| <code>ARM7_SAVE_CFG</code><br />
| 16<br />
|}<br />
<br />
===ARM7_CNT===<br />
This seems to control the mode of the ARM7. 1 = TWL, 2 = GBA.<br />
<br />
===ARM7_CODE===<br />
This is the first code that will be run after execution begins. <code>TwlProcess9</code> uses this to put ARM7 in a loop (TWL), and to set the <code>POSTFLG</code> and branch to more copied code (GBA).This doesn't seem to start execution by itself.<br />
<br />
===ARM7_SAVE_MODE===<br />
This tells the save storage emulation hardware which device type to emulate (EEPROM, 512k flash, and SRAM are all that have been spotted). This comes directly from the [[3DS_Virtual_Console#Footer|ROM footer]].<br />
<br />
===ARM7_RTC ''?''===<br />
These registers may be used to control a real-time clock. To set or read the data here, first <code>ARM7_RTC_CNT</code>'s bit 15 is waited on. Next <code>ARM7_RTC_CNT</code> is set to zero. <br />
<br />
For a write: the two registers are written, a 1 is written to <code>ARM7_RTC_CNT</code>, and it is waited on the same as before. Afterwards if bit 14 is not set in <code>ARM7_RTC_CNT</code>, the value was set successfully.<br />
<br />
For a read: a 2 is written to <code>ARM7_RTC_CNT</code>, it's waited on again. Afterwards, if bit 14 is not set, the RTC can be read. Presumably the hardware can be re-enabled by writing a zero to <code>ARM7_RTC_CNT</code> at this point, but <code>AGB_FIRM</code> does not.<br />
<br />
===ARM7_SAVE_CFG===<br />
This is copied from rom footer + <code>0x10</code>. It presumably configures details about storage, such as IDs, and likely allows enabling the RTC for games which need it. Format of this data is unknown, and slightly difficult to determine without some hardware poking.<br />
<br />
==Memory map==<br />
The virtual memory mapping for the ARM7 is the same as for the [[Memory_layout#TWL_FIRM_Userland_Memory|other core]]. However, it has additional internal memory mapped to it. Interestingly enough, much of this memory seems to lie within ARM9's own internal memory.<br />
<br />
* <code>0x08060000</code> → <code>0x03800000</code>, ARM7 WRAM (64KiB)<br />
* <code>0x080B0000</code> → <code>0x03000000</code>, GBA IWRAM (32KiB)<br />
* <code>0x080C0000</code> → EEPROM/SRAM/Flash (<code>0x10018104</code> must be set to 1 before reading memory here, and restored to its previous value afterwards)<br />
* <code>0x01FFC000</code> → <code>0x01000000</code>, ARM9 ITCM under TWL (16KiB)</div>Nicholatianhttps://www.3dbrew.org/w/index.php?title=User:Nicholatian/vector.css&diff=17526User:Nicholatian/vector.css2016-06-15T19:15:06Z<p>Nicholatian: Dark skin ftw</p>
<hr />
<div>/* CSS placed here will affect users of the Vector skin */<br />
<br />
/* Override Vector colour scheme to make it dark (compiled from modified LESS code) */<br />
h1,h2,h3,h4,h5,h6{color:#c1c1c1}hr{color:#222}.editOptions{background-color:#333;border-color:#4c4c4c}input,textarea{background-color:#4c4c4c;border-color:#4c4c4c;color:#c1c1c1}a,.mw-body a.external,.mw-body a.extiw{color:#e69710}a:visited,.mw-body a.external:visited,.mw-body a.extiw:visited{color:#8a7f6c}a.new,#p-personal a.new{color:#d44}ul{list-style-image:none}div.thumbinner,.catlinks{background-color:#4c4c4c;border-color:#666}#toc,div.toc,ul#filetoc,li.gallerybox div.thumb{background-color:#4c4c4c;border-color:#666}code{border:none;background-color:inherit;color:inherit}table.mw_metadata td,table.mw_metadata th,table.wikitable,table.wikitable>*>tr>th,table.wikitable>*>tr>td,pre{color:#c1c1c1;background-color:#4c4c4c;border-color:#666}table.mw_metadata th,table.wikitable>*>tr>th{background-color:#595959}table.diff{background-color:#4c4c4c}td .diffchange{color:#4c4c4c}#pagehistory li.selected,td.diff-context{background-color:inherit;color:inherit}#pagehistory li{border:0}ul.mw-gallery-packed-hover li.gallerybox:hover div.gallerytextwrapper,ul.mw-gallery-packed-overlay li.gallerybox div.gallerytextwrapper,ul.mw-gallery-packed-hover li.gallerybox.mw-gallery-focused div.gallerytextwrapper{background-color:rgba(0,0,0,0.8)}#left-navigation div.vectorTabs,#right-navigation div.vectorTabs{background-image:inherit;background-color:#250b2d}#left-navigation div.vectorTabs ul,#right-navigation div.vectorTabs ul{background-color:#250b2d}#left-navigation div.vectorTabs ul li,#right-navigation div.vectorTabs ul li{background-color:#222;background-image:-moz-linear-gradient(top, #2e2e2e 20%, #222 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(20%, #2e2e2e), color-stop(100%, #222));background-image:-webkit-linear-gradient(top, #2e2e2e 20%, #222 100%);background-image:linear-gradient(#2e2e2e 20%, #222 100%)}#left-navigation div.vectorTabs li.new a,#right-navigation div.vectorTabs li.new a,#left-navigation div.vectorTabs li.new a:visited,#right-navigation div.vectorTabs li.new a:visited{color:#d44}#left-navigation div.vectorTabs li.selected,#right-navigation div.vectorTabs li.selected{background-color:#333;background-image:-moz-linear-gradient(top, #e69710 0, #333 10%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #e69710), color-stop(10%, #333));background-image:-webkit-linear-gradient(top, #e69710 0, #333 10%);background-image:linear-gradient(#e69710 0, #333 10%)}#left-navigation div.vectorTabs li.selected a,#right-navigation div.vectorTabs li.selected a,#left-navigation div.vectorTabs li.selected a:visited,#right-navigation div.vectorTabs li.selected a:visited{color:#8a7f6c}#left-navigation div.vectorTabs li a,#right-navigation div.vectorTabs li a{color:#e69710}#left-navigation div.vectorTabs span,#right-navigation div.vectorTabs span{background:transparent}div#mw-head #right-navigation div.vectorMenu h3{background:inherit}div#mw-head div.vectorMenu h3 span{color:#e69710}div.vectorMenu h3 a{background:inherit}div.vectorMenu ul{background-color:black;border:solid 1px #0c0c0c}div.vectorMenu li a{color:#e69710}div.vectorMenu li.selected a,div.vectorMenu li.selected a:visited{color:#8a7f6c;text-decoration:none}div.vectorMenu#p-cactions div.menu{border-color:#666}div.vectorMenu#p-cactions ul{border:0;background-color:#4c4c4c}#mw-navigation div#mw-panel div.portal{background-image:none;border-top:1px solid #4c4c4c}#mw-navigation div#mw-panel div.portal#p-logo,#mw-navigation div#mw-panel div.portal#p-navigation{border-top:none}html{font-size:100%}html,body{height:100%;margin:0;padding:0;font-family:sans-serif}body{background-color:#2a2a2a}.mw-body{margin-left:10em;padding:1em;border:1px solid #250b2d;border-right-width:0;margin-top:-1px;background-color:#333;color:#c1c1c1;direction:ltr}.mw-body .mw-editsection,.mw-body .mw-editsection-like{font-family:sans-serif}.mw-body p{line-height:inherit;margin:.5em 0}.mw-body h1,.mw-body h2,.mw-body #firstHeading{font-family:"Linux Libertine",Georgia,Times,serif;line-height:1.3;margin-bottom:.25em;padding:0}.mw-body h1,.mw-body #firstHeading{font-size:1.8em}.mw-body h2{font-size:1.5em;margin-top:1em}.mw-body h3,.mw-body h4,.mw-body h5,.mw-body h6{line-height:1.6;margin-top:.3em;margin-bottom:0;padding-bottom:0}.mw-body h3{font-size:1.17em}.mw-body h3,.mw-body h4{font-weight:bold}.mw-body h4,.mw-body h5,.mw-body h6{font-size:100%}.mw-body #toc h2,.mw-body .toc h2{font-size:100%;font-family:sans-serif}div.emptyPortlet{display:none}ul{list-style-type:disc;list-style-image:/* @embed */ url('skins/Vector/images/bullet-icon.png')}pre,.mw-code{line-height:1.3em}#siteNotice{font-size:.8em}.redirectText{font-size:140%}.redirectMsg img{vertical-align:text-bottom}.mw-body-content{position:relative;line-height:1.6;font-size:.875em}body.vector-animateLayout .mw-body,body.vector-animateLayout div#footer,body.vector-animateLayout #left-navigation{-webkit-transition:margin-left 250ms,padding 250ms;-moz-transition:margin-left 250ms,padding 250ms;-o-transition:margin-left 250ms,padding 250ms;transition:margin-left 250ms,padding 250ms}body.vector-animateLayout #p-logo{-webkit-transition:left 250ms;-moz-transition:left 250ms;-o-transition:left 250ms;transition:left 250ms}body.vector-animateLayout #mw-panel{-webkit-transition:padding-right 250ms;-moz-transition:padding-right 250ms;-o-transition:padding-right 250ms;transition:padding-right 250ms}body.vector-animateLayout #p-search{-webkit-transition:margin-right 250ms;-moz-transition:margin-right 250ms;-o-transition:margin-right 250ms;transition:margin-right 250ms}body.vector-animateLayout #p-personal{-webkit-transition:right 250ms;-moz-transition:right 250ms;-o-transition:right 250ms;transition:right 250ms}body.vector-animateLayout #mw-head-base{-webkit-transition:margin-left 250ms;-moz-transition:margin-left 250ms;-o-transition:margin-left 250ms;transition:margin-left 250ms}#p-personal{position:absolute;top:.33em;right:.75em;z-index:100}#p-personal h3{display:none}#p-personal ul{list-style-type:none;list-style-image:none;margin:0;padding-left:10em}#p-personal li{line-height:1.125em;float:left;margin-left:.75em;margin-top:.5em;font-size:.75em;white-space:nowrap}#pt-userpage,#pt-anonuserpage{background-position:left top;background-repeat:no-repeat;background-image:url('skins/Vector/images/user-icon.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/user-icon.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/user-icon.svg');padding-left:15px !important}#p-search{float:left;margin-right:.5em;margin-left:.5em}#p-search h3{display:none}#p-search form,#p-search input{margin:0;margin-top:.4em}div#simpleSearch{display:block;width:12.6em;padding-right:1.4em;height:1.4em;margin-top:.65em;position:relative;min-height:1px;border:solid 1px #aaa;color:black;background-color:white;background-image:/* @embed */ url('skins/Vector/images/search-fade.png');background-position:top left;background-repeat:repeat-x}div#simpleSearch input{margin:0;padding:0;border:0;background-color:transparent;color:black}div#simpleSearch #searchInput{width:100%;padding:.2em 0 .2em .2em;font-size:13px;direction:ltr;-webkit-appearance:textfield}div#simpleSearch #searchInput:focus{outline:none}div#simpleSearch #searchInput.placeholder{color:#999}div#simpleSearch #searchInput:-ms-input-placeholder{color:#999}div#simpleSearch #searchInput:-moz-placeholder{color:#999}div#simpleSearch #searchInput::-webkit-search-decoration,div#simpleSearch #searchInput::-webkit-search-cancel-button,div#simpleSearch #searchInput::-webkit-search-results-button,div#simpleSearch #searchInput::-webkit-search-results-decoration{-webkit-appearance:textfield}div#simpleSearch #searchButton,div#simpleSearch #mw-searchButton{position:absolute;top:0;right:0;width:1.65em;height:100%;cursor:pointer;text-indent:-99999px;line-height:1;direction:ltr;white-space:nowrap;overflow:hidden;background-image:url('skins/Vector/images/search-ltr.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/search-ltr.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/search-ltr.svg');background-position:center center;background-repeat:no-repeat}div#simpleSearch #mw-searchButton{z-index:1}div.vectorTabs h3{display:none}div.vectorTabs{float:left;height:2.5em;background-image:/* @embed */ url('skins/Vector/images/tab-break.png');background-position:bottom left;background-repeat:no-repeat;padding-left:1px}div.vectorTabs ul{float:left;height:100%;list-style-type:none;list-style-image:none;margin:0;padding:0;background-image:/* @embed */ url('skins/Vector/images/tab-break.png');background-position:right bottom;background-repeat:no-repeat}div.vectorTabs ul li{float:left;line-height:1.125em;display:inline-block;height:100%;margin:0;padding:0;background-color:#f3f3f3;background-image:/* @embed */ url('skins/Vector/images/tab-normal-fade.png');background-position:bottom left;background-repeat:repeat-x;white-space:nowrap}div.vectorTabs ul>li{display:block}div.vectorTabs li.new a,div.vectorTabs li.new a:visited{color:#a55858}div.vectorTabs li.selected{background-image:/* @embed */ url('skins/Vector/images/tab-current-fade.png')}div.vectorTabs li.selected a,div.vectorTabs li.selected a:visited{color:#333;text-decoration:none}div.vectorTabs li.icon a{background-position:bottom right;background-repeat:no-repeat}div.vectorTabs li a{display:inline-block;height:1.9em;padding-left:.5em;padding-right:.5em;color:#e69710;cursor:pointer;font-size:.8em}div.vectorTabs li>a{display:block}div.vectorTabs span{display:inline-block;background-image:/* @embed */ url('skins/Vector/images/tab-break.png');background-position:bottom right;background-repeat:no-repeat}div.vectorTabs span a{display:inline-block;padding-top:1.25em}div.vectorTabs span>a{float:left;display:block}div.vectorMenu{direction:ltr;float:left;cursor:pointer;position:relative}body.rtl div.vectorMenu{direction:rtl}div#mw-head div.vectorMenu h3{float:left;background-image:/* @embed */ url('skins/Vector/images/tab-break.png');background-repeat:no-repeat;background-position:bottom right;margin-left:-1px;font-size:1em;height:2.5em;padding-right:1px;margin-right:-1px}div.vectorMenu h3 span{display:block;font-size:.8em;padding-left:.7em;padding-top:1.375em;margin-right:20px;font-weight:normal;color:#4d4d4d}div.vectorMenu h3 a{position:absolute;top:0;right:0;width:20px;height:2.5em;background-image:url('skins/Vector/images/arrow-down-icon.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/arrow-down-icon.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/arrow-down-icon.svg');background-position:100% 70%;background-repeat:no-repeat;-webkit-transition:background-position 250ms;-moz-transition:background-position 250ms;-o-transition:background-position 250ms;transition:background-position 250ms}div.vectorMenu.menuForceShow h3 a{background-position:100% 100%}div.vectorMenuFocus h3 a{background-image:url('skins/Vector/images/arrow-down-focus-icon.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/arrow-down-focus-icon.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/arrow-down-focus-icon.svg')}div.vectorMenu div.menu{min-width:100%;position:absolute;top:2.5em;left:-1px;background-color:white;border:solid 1px silver;border-top-width:0;clear:both;text-align:left;display:none}div.vectorMenu:hover div.menu,div.vectorMenu.menuForceShow div.menu{display:block}div.vectorMenu ul{list-style-type:none;list-style-image:none;padding:0;margin:0;text-align:left}div.vectorMenu ul,x:-moz-any-link{min-width:5em}div.vectorMenu ul,x:-moz-any-link,x:default{min-width:0}div.vectorMenu li{padding:0;margin:0;text-align:left;line-height:1em}div.vectorMenu li a{display:inline-block;padding:.5em;white-space:nowrap;color:#e69710;cursor:pointer;font-size:.8em}div.vectorMenu li>a{display:block}div.vectorMenu li.selected a,div.vectorMenu li.selected a:visited{color:#333;text-decoration:none}@-webkit-keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{from{-webkit-transform:rotate(0deg);-moz-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);transform:rotate(360deg)}}#ca-unwatch.icon a,#ca-watch.icon a{margin:0;padding:0;display:block;width:26px;padding-top:3.1em;margin-top:0;height:0;overflow:hidden;background-position:5px 60%}#ca-unwatch.icon a{background-image:url('skins/Vector/images/unwatch-icon.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/unwatch-icon.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/unwatch-icon.svg')}#ca-watch.icon a{background-image:url('skins/Vector/images/watch-icon.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/watch-icon.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/watch-icon.svg')}#ca-unwatch.icon a:hover,#ca-unwatch.icon a:focus{background-image:url('skins/Vector/images/unwatch-icon-hl.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/unwatch-icon-hl.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/unwatch-icon-hl.svg')}#ca-watch.icon a:hover,#ca-watch.icon a:focus{background-image:url('skins/Vector/images/watch-icon-hl.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/watch-icon-hl.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/watch-icon-hl.svg')}#ca-unwatch.icon a.loading,#ca-watch.icon a.loading{background-image:url('skins/Vector/images/watch-icon-loading.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/watch-icon-loading.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/watch-icon-loading.svg');-webkit-animation:rotate 700ms infinite linear;-moz-animation:rotate 700ms infinite linear;-o-animation:rotate 700ms infinite linear;animation:rotate 700ms infinite linear;outline:none;cursor:default;pointer-events:none;background-position:50% 60%;-webkit-transform-origin:50% 57%;transform-origin:50% 57%}#ca-unwatch.icon a span,#ca-watch.icon a span{display:none}#mw-navigation h2{position:absolute;top:-9999px}#mw-page-base{height:5em;background-position:bottom left;background-repeat:repeat-x;background-image:url('skins/Vector/images/page-fade.png');background-color:#2a2a2a;background-image:-moz-linear-gradient(top, #333 50%, #2a2a2a 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(50%, #333), color-stop(100%, #2a2a2a));background-image:-webkit-linear-gradient(top, #333 50%, #2a2a2a 100%);background-image:linear-gradient(#333 50%, #2a2a2a 100%);background-color:#333}#mw-head-base{margin-top:-5em;margin-left:10em;height:5em}div#mw-head{position:absolute;top:0;right:0;width:100%}div#mw-head h3{margin:0;padding:0}#left-navigation{float:left;margin-left:10em;margin-top:2.5em;margin-bottom:-2.5em;display:inline}#right-navigation{float:right;margin-top:2.5em}#p-logo{position:absolute;top:-160px;left:0;width:10em;height:160px}#p-logo a{display:block;width:10em;height:160px;background-repeat:no-repeat;background-position:center center;text-decoration:none}div#mw-panel{font-size:inherit;position:absolute;top:160px;padding-top:1em;width:10em;left:0}div#mw-panel div.portal{margin:0 .6em 0 .7em;padding:.25em 0;direction:ltr;background-position:top left;background-repeat:no-repeat;background-image:/* @embed */ url('skins/Vector/images/portal-break.png')}div#mw-panel div.portal h3{font-size:.75em;color:#4d4d4d;font-weight:normal;margin:0;padding:.25em 0 .25em .25em;cursor:default;border:none}div#mw-panel div.portal div.body{margin:0 0 0 1.25em;padding-top:0}div#mw-panel div.portal div.body ul{list-style-type:none;list-style-image:none;margin:0;padding:0}div#mw-panel div.portal div.body ul li{line-height:1.125em;margin:0;padding:.25em 0;font-size:.75em;word-wrap:break-word}div#mw-panel div.portal div.body ul li a{color:#e69710}div#mw-panel div.portal div.body ul li a:visited{color:#8a7f6c}div#mw-panel div.portal.first{background-image:none;margin-top:0}div#mw-panel div.portal.first h3{display:none}div#mw-panel div.portal.first div.body{margin-left:.5em}div#footer{margin-left:10em;margin-top:0;padding:.75em;direction:ltr}div#footer ul{list-style-type:none;list-style-image:none;margin:0;padding:0}div#footer ul li{margin:0;padding:0;padding-top:.5em;padding-bottom:.5em;color:#333;font-size:.7em}div#footer #footer-icons{float:right}div#footer #footer-icons li{float:left;margin-left:.5em;line-height:2em;text-align:right}div#footer #footer-info li{line-height:1.4em}div#footer #footer-places li{float:left;margin-right:1em;line-height:2em}body.ltr div#footer #footer-places{float:left}.mw-body .external{background-position:center right;background-repeat:no-repeat;background-image:url('skins/Vector/images/external-link-ltr-icon.png');background-image:-webkit-linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/external-link-ltr-icon.svg');background-image:linear-gradient(transparent, transparent),/* @embed */ url('skins/Vector/images/external-link-ltr-icon.svg');padding-right:13px}</div>Nicholatianhttps://www.3dbrew.org/w/index.php?title=Talk:Main_Page&diff=17522Talk:Main Page2016-06-15T18:09:07Z<p>Nicholatian: /* Uploads are broken */ new section</p>
<hr />
<div>So how about a [http://wiisixtyfour.webs.com/images/3dsbrew-bg4545.png logo]? --[[User:Bg4545|wiisixtyfour]] 06:59, 1 April 2011 (CEST)<br />
<br />
Great one, let's put it as default logo ! --[[User:GeekShadow|GeekShadow]] 09:37, 1 April 2011 (CEST)<br />
<br />
Here's one I made, which doesn't use any official artwork/photography: [http://dl.dropbox.com/u/1077900/Graphics/3dbrew.png PNG] [http://dl.dropbox.com/u/1077900/Graphics/3dbrew.svg SVG] --[[User:BHSPitMonkey|BHSPitMonkey]] 05:36, 7 April 2011 (CEST)<br />
<br />
How about making the default skin [http://3dbrew.org/w/index.php?title=Main_Page&useskin=monobook MonoBook]?, I like the it better. --[[User:Elisherer|Elisherer]] 10:58, 6 October 2011 (CEST)<br />
<br />
I want to dump RAM.What can I do now?How can I learn? --[[User:Matyapiro31|Matyapiro31]] 16:30, 20 November 2011 (CET)<br />
:Sorry, this is not the correct page to talk about that. However, it's a good topic for our new forum! http://n-dev.net/index.php --[[User:Lazymarek9614|Lazymarek9614]] 17:43, 20 November 2011 (CET)<br />
<br />
-Hello, I would like to translate this great wiki into French, how should I do ? Thanks :)<br />
:I guess each page you want to translate you need to edit the page's link with a '/' (slash) after it and the language code (fr for french i think), for instance edit the page http://www.3dbrew.org/wiki/Main_Page/Fr and then put a link on the bottom next to Japanese.. --[[User:Elisherer|Elisherer]] 17:49, 21 December 2011 (CET)<br />
::You should take a look [http://www.mediawiki.org/wiki/Template:Languages here]...Apperantly we don't have the needed template for it to work automaticaly maybe we need the admin to install some kind of extension to support this type of thing. --[[User:Elisherer|Elisherer]] 18:59, 21 December 2011 (CET)<br />
<br />
-Yes, it would be more practical. For now, I'll continue translating like that, please tell me when the plugin is added.<br />
---I added a language selection bar at the bottom of each main page.<br />
<br />
I cannot have be accessing for a week.Why?--Matyapiro31 12:51, 19 April 2012 (CEST)<br />
== SVG upload ==<br />
<br />
Hey neimod, can you enable svg uploading? I want to upload graphics for the buttons [http://sherer.co.il/svg/ I made] (for future homebrew and stuff)--[[User:Elisherer|Elisherer]] 14:41, 9 February 2012 (CET)<br />
: You can address this issue to [[User:Mha|Mha]] (mha on irc) --[[User:Neimod|Neimod]] 19:04, 9 February 2012 (CET)<br />
<br />
<br />
Game Screenshots...<br />
<br />
Hey guys how can i export the photos from DoA:D from 3DS to PC i have the right file but on mc if i change to .jpg or mpo it does not open...<br />
<br />
== Does anyone know how to tell an installed/braindumped title's version? ==<br />
<br />
I'm on 9.3 and have hax. I want to know this so I can contribute versions to to the title list. --[[User:Hiccup|Hiccup]] ([[User talk:Hiccup|talk]]) 14:57, 6 January 2016 (CET)<br />
:1.If you have NAND Xorpad you can dump and decrypt to get the .[[TMD]] files and read the version from it. 2.Use [[AM]] service, and use "AM_ListTitles" from libctru, structure "AM_TitleEntry" includes the version. 3.Most versions of System Titles are fetched via System Update SOAP response, thanks to [[User:Yellows8|Yellows8]] for that.<br />
:BTW I suggest you to ask questions on 4dsdev.org or IRC(EFNET.org#3dsdev) thus it may be dealt faster. --[[User:Syphurith|Syphurith]] ([[User talk:Syphurith|talk]]) 11:35, 7 January 2016 (CET)<br />
<br />
== question ==<br />
<br />
Can we get an actual board to discuss things instead of a shitty wiki that's setup like this? --[[User:NintendoFan|NintendoFan]] ([[User talk:NintendoFan|talk]]) 09:36, 3 May 2016 (CEST)<br />
<br />
: It says so in the previous discussion on this page :P [4dsdev.org] --[[User:Ryccardo|Ryccardo]] ([[User talk:Ryccardo|talk]]) 09:52, 3 May 2016 (CEST)<br />
<br />
:: 4dsdev looks quite dead with a sticky about merging that is 5 months old. :P GBAtemp [http://gbatemp.net/categories/nintendo-3ds-discussions.198/] is quite active, why not there? --[[User:MKody|MKody]] ([[User talk:MKody|talk]]) 10:40, 3 May 2016 (CEST)<br />
<br />
::: Eh, while GBATemp is a good place I'd much rather have a board that's specifically dedicated to 3DS modding, not just modding in general. Also, I'd much rather start fresh with a new board than trying to revive a dead community that's been merged into some other board. --[[User:NintendoFan|NintendoFan]] ([[User talk:NintendoFan|talk]]) 07:58, 6 May 2016 (CEST)<br />
<br />
== Uploads are broken ==<br />
<br />
MediaWiki throws a MWException whenever I try to upload an image file. Perhaps uploads are not configured properly? —'''<span style="text-shadow:0 0 3px #111">[[User:Nicholatian|<span style="color:#ddd">nicho</span>]][[User_talk:Nicholatian|<span style="color:#ddd">latian</span>]]''[[Special:Contributions/Nicholatian|<span style="color:#c43">fury</span>]]''</span>''' 20:09, 15 June 2016 (CEST)</div>Nicholatianhttps://www.3dbrew.org/w/index.php?title=NCCH/Extended_Header&diff=17521NCCH/Extended Header2016-06-15T18:02:42Z<p>Nicholatian: This should be a lot more readable</p>
<hr />
<div>This page documents the format of the '''NCCH Extended Header''', or '''exheader''' for short.<br />
<br />
The exheader has two sections:<br />
<br />
* The actual exheader data, containing System Control Info (SCI) and Access Control Info (ACI);<br />
* A signed copy of NCCH HDR public key, and exheader ACI. This version of the ACI is used as limitation to the actual ACI.<br />
<br />
== Main Structure ==<br />
All values are little endian unless otherwise specified.<br />
<br />
See also: [https://github.com/profi200/Project_CTR/blob/master/ctrtool/exheader.h]<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>0x200</code><br />
| SCI<br />
|-<br />
| <code>0x200</code><br />
| <code>0x200</code><br />
| ACI<br />
|-<br />
| <code>0x400</code><br />
| <code>0x100</code><br />
| <code>AccessDesc</code> signature (RSA-2048-SHA256)<br />
|-<br />
| <code>0x500</code><br />
| <code>0x100</code><br />
| NCCH HDR RSA-2048 public key<br />
|-<br />
| <code>0x600</code><br />
| <code>0x200</code><br />
| ACI (for limitation of first ACI)<br />
|}<br />
<br />
The <code>AccessDesc</code> signature covers the NCCH HDR public key and second ACI. The <code>AccessDesc</code> public key is initialised by the boot ROM.<br />
<br />
When loading the exheader, [[FIRM|Process9]] compares the exheader data with the data in the <code>AccessDesc</code> (note that not everything is compared here). When these don't match, an error is returned. The Process9 code handling this validation was updated with [[6.0.0-11|v6.0]]; the only change in this function seems to be the check for the "Ideal processor" field.<br />
<br />
== System Control Info ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>0x8</code><br />
| Application title<br />
|-<br />
| <code>0x8</code><br />
| <code>0x5</code><br />
| Reserved<br />
|-<br />
| <code>0xD</code><br />
| <code>0x1</code><br />
| Flag (bit 0: <code>CompressExefsCode</code>, bit 1: <code>SDApplication</code>)<br />
|-<br />
| <code>0xE</code><br />
| <code>0x2</code><br />
| Remaster version<br />
|-<br />
| <code>0x10</code><br />
| <code>0xC</code><br />
| Text code set info<br />
|-<br />
| <code>0x1C</code><br />
| <code>0x4</code><br />
| Stack size<br />
|-<br />
| <code>0x20</code><br />
| <code>0xC</code><br />
| Read-only code set info<br />
|-<br />
| <code>0x2C</code><br />
| <code>0x4</code><br />
| Reserved<br />
|-<br />
| <code>0x30</code><br />
| <code>0xC</code><br />
| Data code set info<br />
|-<br />
| <code>0x3C</code><br />
| <code>0x4</code><br />
| BSS size<br />
|-<br />
| <code>0x40</code><br />
| <code>0x180</code> (<code>48*8</code>)<br />
| Dependency module (program ID) list<br />
|-<br />
| <code>0x1C0</code><br />
| <code>0x40</code><br />
| <code>SystemInfo</code><br />
|}<br />
<br />
Most of these fields are used in [[LOADER:LoadProcess]].<br />
<br />
=== Code Set Info ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>4</code><br />
| Address<br />
|-<br />
| <code>0x4</code><br />
| <code>4</code><br />
| Physical region size (in page-multiples)<br />
|-<br />
| <code>0x8</code><br />
| <code>4</code><br />
| Size (in bytes)<br />
|}<br />
<br />
=== System Info ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>0x8</code><br />
| <code>SaveData</code> Size<br />
|-<br />
| <code>0x8</code><br />
| <code>0x8</code><br />
| Jump ID<br />
|-<br />
| <code>0x10</code><br />
| <code>0x30</code><br />
| Reserved<br />
|}<br />
<br />
== Access Control Info ==<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>0x170</code><br />
| [[#ARM11 Local System Capabilities|ARM11 local system capabilities]]<br />
|-<br />
| <code>0x170</code><br />
| <code>0x80</code><br />
| [[#ARM11 Kernel Capabilities|ARM11 kernel capabilities]]<br />
|-<br />
| <code>0x1F0</code><br />
| <code>0x10</code><br />
| [[#ARM9 Access Control|ARM9 access control]]<br />
|}<br />
<br />
=== ARM11 Local System Capabilities ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>0x8</code><br />
| Program ID<br />
|-<br />
| <code>0x8</code><br />
| <code>0x4</code><br />
| Core version (The Title ID low of the required [[FIRM]])<br />
|-<br />
| <code>0xC</code><br />
| <code>0x2</code><br />
| [[#Flag1|Flag1]] and [[#Flag2|Flag2]] (both implemented starting from [[8.0.0-18]]).<br />
|-<br />
| <code>0xE</code><br />
| <code>0x1</code><br />
| [[#Flag0|Flag0]]<br />
|-<br />
| <code>0xF</code><br />
| <code>0x1</code><br />
| Priority<br />
|-<br />
| <code>0x10</code><br />
| <code>0x20</code> (<code>16*2</code>)<br />
| Resource limit descriptors. The first byte here controls the maximum allowed [[PMApp:SetAppResourceLimit|<code>CpuTime</code>]].<br />
|-<br />
| <code>0x30</code><br />
| <code>0x20</code><br />
| [[#Storage Info|Storage info]]<br />
|-<br />
| <code>0x50</code><br />
| <code>0x100</code> (<code>32*8</code>)<br />
| [[#Service Access Control|Service access control]]<br />
|-<br />
| <code>0x150</code><br />
| <code>0x10</code> (<code>2*8</code>)<br />
| Extended service access control, support for this was implemented with [[9.3.0-21|9.3.0-X]].<br />
|-<br />
| <code>0x160</code><br />
| <code>0xF</code><br />
| Reserved<br />
|-<br />
| <code>0x16F</code><br />
| <code>0x1</code><br />
| Resource limit category. (0 = <code>APPLICATION</code>, 1 = <code>SYS_APPLET</code>, 2 = <code>LIB_APPLET</code>, 3 = <code>OTHER</code> (sysmodules running under the BASE memregion))<br />
|}<br />
<br />
==== Flag0 ====<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bits<br />
! Description<br />
|-<br />
| <code>0-1</code><br />
| Ideal processor<br />
|-<br />
| <code>2-3</code><br />
| Affinity mask<br />
|-<br />
| <code>4-7</code><br />
| System mode<br />
|}<br />
<br />
In the exheader data, the ideal processor field is a bit-index, while in the <code>AccessDesc</code> the ideal processor field is a bitmask. When the bit specified by the exheader field is not set in the <code>AccessDesc</code> field, an error is returned.<br />
<br />
<pre>if((1 << exheaderval) & accessdescval == 0) return error</pre><br />
<br />
During a FIRM-launch when a <code>TitleInfo</code> structure was specified, the field at offset [[FIRM#FIRM_Launch_Parameters|0x400]] in the FIRM-launch parameters is set to the SystemMode of the specified title, however in some cases other values are written there. With [[8.0.0-18]] NS will now check the output of [[PTM|PTMSYSM]] command <code>0x040A0000</code>, when the output is non-zero and a certain NS state field is value-zero, the following is executed otherwise this is skipped. With that check passed on [[8.0.0-18]], NS will then check (<code>Flag2 & 0xF</code>). When that is <code>value2</code>, the output value (used for the FIRM-launcher parameter field mentioned above) is set to <code>value7</code>. Otherwise, when that value is non-zero, the output value is set to 6.<br />
<br />
==== Flag1 ====<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bits<br />
! Description<br />
|-<br />
| <code>0</code><br />
| <code>EnableL2Cache</code> (Unknown what this actually does, New3DS-only presumably)<br />
|-<br />
| <code>1</code><br />
| <code>cpuspeed_804MHz</code> (Default "cpuspeed" when not set)<br />
|-<br />
| <code>2-7</code><br />
| Unused<br />
|}<br />
<br />
In order for the exheader to have any of the above new bits set, the <code>AccessDesc</code> must have the corresponding bit set, otherwise the invalid-exheader error is returned.<br />
<br />
Homebrew which runs under a title which has the above <code>cpuspeed</code> flag set, runs much faster on New3DS. It's unknown how exactly the system handles these flags.<br />
<br />
When launching titles / perhaps other things with [[APT]], [[NS]] uses [[PTMSYSM:ConfigureNew3DSCPU]] with data which originally came from these flags; NS does this regardless of what the running 3DS system is. However, due to a bug(?) in NS the value sent to that command is always either 0x0 or 0x3. When calculating that value, the code only ever uses the cpuspeed field, not the cache field: code to actually load and check the value of the cache field appears to be missing.<br />
<br />
==== Flag2 ====<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bit<br />
! Description<br />
|-<br />
| <code>0-3</code><br />
| ''Unknown''<br />
|-<br />
| <code>4-7</code><br />
| Unused<br />
|}<br />
<br />
The exheader value for the above 4-bit value must be ≤ to the <code>AccessDesc</code> value, otherwise the invalid-exheader error is returned.<br />
<br />
==== Storage Info ====<br />
Used in [[FSReg:Register]].<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>8</code><br />
| Extdata ID<br />
|-<br />
| <code>0x8</code><br />
| <code>8</code><br />
| System savedata IDs<br />
|-<br />
| <code>0x10</code><br />
| <code>8</code><br />
| Storage accessible unique IDs<br />
|-<br />
| <code>0x18</code><br />
| <code>7</code><br />
| Filesystem access info<br />
|-<br />
| <code>0x1F</code><br />
| <code>1</code><br />
| Other attributes<br />
|}<br />
<br />
File System Access Info:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bit and bitmask<br />
! Description<br />
|-<br />
| <code>0</code>, <code>0x1</code><br />
| Category system application<br />
|-<br />
| <code>1</code>, <code>0x2</code><br />
| Category hardware check<br />
|-<br />
| <code>2</code>, <code>0x4</code><br />
| Category filesystem tool<br />
|-<br />
| <code>3</code>, <code>0x8</code><br />
| Debug<br />
|-<br />
| <code>4</code>, <code>0x10</code><br />
| TWL card backup<br />
|-<br />
| <code>5</code>, <code>0x20</code><br />
| TWL NAND data<br />
|-<br />
| <code>6</code>, <code>0x40</code><br />
| BOSS<br />
|-<br />
| <code>7</code>, <code>0x80</code><br />
| [[FS:OpenArchive|<code>sdmc:/</code>]]<br />
|-<br />
| <code>8</code>, <code>0x100</code><br />
| Core<br />
|-<br />
| <code>9</code>, <code>0x200</code><br />
| [[Flash Filesystem|<code>nand:/ro/</code>]] (Read Only)<br />
|-<br />
| <code>10</code>, <code>0x400</code><br />
| [[Flash Filesystem|<code>nand:/rw/</code>]]<br />
|-<br />
| <code>11</code>, <code>0x800</code><br />
| [[Flash Filesystem|<code>nand:/ro/</code>]] (Write Access)<br />
|-<br />
| <code>12</code>, <code>0x1000</code><br />
| Category system settings<br />
|-<br />
| <code>13</code>, <code>0x2000</code><br />
| Cardboard<br />
|-<br />
| <code>14</code>, <code>0x4000</code><br />
| Export/Import IVS<br />
|-<br />
| <code>15</code>, <code>0x8000</code><br />
| [[FS:OpenArchive|<code>sdmc:/</code>]] (Write-only)<br />
|-<br />
| <code>16</code>, <code>0x10000</code><br />
| Switch cleanup (Introduced in [[3.0.0-5|3.0.0]]?) <br />
|-<br />
| <code>17</code>, <code>0x20000</code><br />
| Savedata move (Introduced in [[5.0.0-11|5.0.0]]) <br />
|-<br />
| <code>18</code>, <code>0x40000</code><br />
| Shop (Introduced in [[5.0.0-11|5.0.0]]) <br />
|-<br />
| <code>19</code>, <code>0x80000</code><br />
| Shell (Introduced in [[5.0.0-11|5.0.0]]) <br />
|-<br />
| <code>20</code>, <code>0x100000</code><br />
| Category home menu (Introduced in [[6.0.0-11|6.0.0]])<br />
|-<br />
| <code>21</code>, <code>0x200000</code><br />
| Seed DB. Introduced in [[9.6.0-24|9.6.0-X]] [[FIRM]]. [[Home Menu]] has this bit set starting with [[9.6.0-24|9.6.0-X]].<br />
|}<br />
<br />
====Other Attributes====<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bit<br />
! Description<br />
|-<br />
| <code>0</code><br />
| Not use ROMFS<br />
|-<br />
| <code>1</code><br />
| Use Extended savedata access.<br />
|}<br />
<br />
When this is set, the "Extdata ID" and "Storage Accessable Unique IDs" regions are used to store a total of 6 "Accessible Save IDs". Introduced in [[6.0.0-11|6.0.0]].<br />
<br />
==== Service Access Control ====<br />
This is the list of [[Services_API|services]] which the process is allowed to access, this is registered with the [[Services|services]] manager. Each service listed in the exheader must be listed in the <code>AccessDesc</code>, otherwise the invalid exheader error is returned. The order of the services for exheader/<code>AccessDesc</code> doesn't matter. The <code>AccessDesc</code> can list services which are not in the exheader, but normally the service-access-control data for exheader/<code>AccessDesc</code> are exactly the same.<br />
<br />
This list is submitted to [[SRVPM:RegisterProcess]].<br />
<br />
=== ARM11 Kernel Capabilities ===<br />
The kernel capability descriptors are passed to [[SVC|svcCreateProcess]].<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>0x70</code> (<code>28*4</code>)<br />
| Descriptors<br />
|-<br />
| <code>0x70</code><br />
| <code>0x10</code><br />
| Reserved<br />
|}<br />
<br />
There are different descriptor types, determined by the number of leading ones in the binary value representation of bits 20-31. The different types are laid out as follows:<br />
<br />
{| class="wikitable" border="1"<br />
|-<br />
! Pattern of bits 20-31<br />
! Type<br />
! Fields<br />
|-<br />
| <code>0b1110xxxxxxxx</code><br />
| Interrupt info<br />
|<br />
|-<br />
| <code>0b11110xxxxxxx</code><br />
| System call mask<br />
| Bits 24-26: System call mask table index; Bits 0-23: mask<br />
|-<br />
| <code>0b1111110xxxxx</code><br />
| Kernel release version<br />
| Bits 8-15: Major version; Bits 0-7: Minor version<br />
|-<br />
| <code>0b11111110xxxx</code><br />
| Handle table size<br />
| Bits 0-18: size<br />
|-<br />
| <code>0b111111110xxx</code><br />
| [[#ARM11_Kernel_Flags|Kernel flags]]<br />
| See below<br />
|-<br />
| <code>0b11111111100x</code><br />
| Mapping static address<br />
|<br />
|-<br />
| <code>0b111111111110</code><br />
| Mapping IO address<br />
| Bits 0-19: IO page index to map; Bit 20: Map read-only (otherwise read-write)<br />
|}<br />
<br />
==== ARM11 Kernel Flags ====<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bit<br />
! Description<br />
|-<br />
| <code>0</code><br />
| Allow debug<br />
|-<br />
| <code>1</code><br />
| Force debug<br />
|-<br />
| <code>2</code><br />
| Allow non-alphanum<br />
|-<br />
| <code>3</code><br />
| Shared page writing<br />
|-<br />
| <code>4</code><br />
| Privilege priority<br />
|-<br />
| <code>5</code><br />
| Allow <code>main()</code> args<br />
|-<br />
| <code>6</code><br />
| Shared device memory<br />
|-<br />
| <code>7</code><br />
| Runnable on sleep<br />
|-<br />
| <code>8-11</code><br />
| Memory type (1: application, 2: system, 3: base)<br />
|-<br />
| <code>12</code><br />
| [[Memory_layout#NATIVE_FIRM.2FSAFE_MODE_FIRM_Userland_Memory|Special memory]]<br />
|-<br />
| <code>13</code><br />
| Process has access to CPU core 2 (New3DS only)<br />
|}<br />
<br />
=== ARM9 Access Control ===<br />
{| class="wikitable" border="1"<br />
|-<br />
! Offset<br />
! Size<br />
! Description<br />
|-<br />
| <code>0x0</code><br />
| <code>15</code><br />
| Descriptors<br />
|-<br />
| <code>0xF</code><br />
| <code>1</code><br />
| ARM9 Descriptor Version. Originally this value had to be ≥ 2. Starting with [[9.3.0-21|9.3.0-X]] this value has to be either value 2 or value 3.<br />
|}<br />
<br />
Descriptors:<br />
{| class="wikitable" border="1"<br />
|-<br />
! Bit<br />
! Description<br />
|-<br />
| <code>0</code><br />
| Mount [[Flash Filesystem|<code>nand:/</code>]]<br />
|-<br />
| <code>1</code><br />
| Mount [[Flash Filesystem|<code>nand:/ro/</code>]] (Write Access)<br />
|-<br />
| <code>2</code><br />
| Mount [[Flash Filesystem|<code>twln:/</code>]]<br />
|-<br />
| <code>3</code><br />
| Mount [[Flash Filesystem|<code>wnand:/</code>]]<br />
|-<br />
| <code>4</code><br />
| Mount card SPI<br />
|-<br />
| <code>5</code><br />
| Use SDIF3<br />
|-<br />
| <code>6</code><br />
| Create seed<br />
|-<br />
| <code>7</code><br />
| Use card SPI<br />
|-<br />
| <code>8</code><br />
| SD application (Not checked)<br />
|-<br />
| <code>9</code><br />
| Mount [[SD Filesystem|sdmc:/]] (Write Access)<br />
|}</div>Nicholatianhttps://www.3dbrew.org/w/index.php?title=User:Nicholatian&diff=17520User:Nicholatian2016-06-15T16:50:23Z<p>Nicholatian: Added some basic info</p>
<hr />
<div>{| class="wikitable" width="300px" align="right"<br />
|-<br />
! colspan="2" width="100%" | Alexander Nicholi<br />
|-<br />
| colspan="2" width="100%" | [[File:Nicholatian.png|280px|center]]<br />
|-<br />
| colspan="1" width="33.3%" style="text-align:right" | '''Gender'''<br />
| colspan="1" width="66.6%" | Genderless<br />
|-<br />
| colspan="1" width="33.3%" style="text-align:right" | '''Age'''<br />
| colspan="1" width="66.6%" | 113<br />
|-<br />
| colspan="1" width="33.3%" style="text-align:right" | '''Location'''<br />
| colspan="1" width="66.6%" | Antarctica<br />
|-<br />
| colspan="1" width="33.3%" style="text-align:right" | '''Title'''<br />
| colspan="1" width="66.6%" | ASMAGICIAN<br />
|}<br />
I am a software developer and homebrew enthusiast; on the wiki I usually like to do aesthetic cleanup of articles. I am getting my first 3DS very soon, however I have spent years learning about assembly, ROM hacking, and homebrew dev on the ''Game Boy Advance.''<br />
<br />
==Projects==<br />
Here are some summaries of the homebrew/hacking-related projects I am either currently working on or have worked on in the past.<br />
<br />
===Pokémon Citrite===<br />
A ROM hack of Pokémon Emerald that I started in 2014 on the ''Game Boy Advance.'' It evolved alongside my knowledge of ROM hacking and grew with how much I learned about the GBA and Game Freak's engine. Over time I learned many fundamental skills, including how to:<br />
<br />
* Write ARMv4 Thumb assembly<br />
* Reverse engineer code in IDA Pro<br />
* Effectively manipulate the GBA's hardware<br />
* Hack in C code into the existing Emerald binary<br />
* Automate ROM hacking into a single "build step" using Make<br />
<br />
Development of Pokémon Citrite gradually came to a halt however, as it dawned on me that my game would never see popular fruition, mainly because I was permanently banned from the PokéCommunity (a forum with the largest Pokémon ROM hacking scene) unjustly. After departing from the ROM hacking development scene I decided to get involved with homebrew on the GBA, and write my own game engine for it in C++; this allowed the essence of Citrite to live on, but without any connection to Pokémon so I could retain copyrights (See: [[#Trinity|Trinity]]).<br />
<br />
===Trinity===<br />
An independent continuation of [[#Pokémon_Citrite|Pokémon Citrite]] written in C++ for the GBA. Source code will be based on the fruits of [[#libGBAmm|libGBAmm]] and [[#Saturn|Saturn]] once those projects are ready for use.<br />
<br />
===libGBAmm===<br />
An object-oriented rewrite of the libGBA provided by <span class="plainlinks">[https://github.com/devkitPro/libgba devkitPro]</span>, currently <span class="plainlinks">[https://github.com/nicholatian/libgbamm available on GitHub]</span> as a work-in-progress.<br />
<br />
===Saturn===<br />
A generic framework that builds on [[#libGBAmm|libGBAmm]], comprising a template project that can be used to jump-start other projects on the GBA. Will be written in C++, like libGBAmm, and will include:<br />
<br />
* Classes and functions that make working with graphics more human<br />
* A frame-based asynchronous task system<br />
* A mainloop complete with a modifiable set of purposed callbacks<br />
* A console interface that switches between input and output upon Select<br />
* More abstractions for key input, sound, and link cable networking<br />
<br />
===libcthulhu===<br />
No details yet, but stay tuned. <tt>:)</tt></div>Nicholatian