Flash Filesystem

From 3dbrew
Revision as of 20:21, 19 September 2016 by Neobrain (talk | contribs) (Reorder and rephase for clarity)
Jump to navigation Jump to search

The Nintendo 3DS has a 1GB NAND Flash chip. Due to the NCSD header, the actual used size of the Old3DS NAND is 0x3AF00000-bytes(943MiB). On New3DS, the actual NAND size and the total size used by the partitions, is 0x4D800000-bytes(1240MiB).


Reading of the flash chip is possible through pinouts on the motherboard and has been performed successfully but the data is encrypted and can't be understood without first decrypting it.

Region Changing

See here.

Redirection to SD card

See NAND_Redirection.


The NAND file system is encrypted using AES-CTR. The TWL regions of NAND use the TWL NAND keyslot, while the CTR regions use the CTR NAND keyslots. The keyslot used for each partition is determined by the NCSD partition FS type and encryption type. The TWL/CTR NAND regions are specified by the NCSD header. The first 0x0B100000 bytes of NAND is encrypted with the TWL keyslot, however before 0x00012E00 only the MBR partition table is encrypted with the TWL keyslot. That region contains the TWL partitions listed below.

The New3DS CTRNAND partition uses a keyslot separate from the Old3DS one.

Note that re-encrypting a NAND image alone from another 3DS for use on a different 3DS is not enough to use that NAND image on a different 3DS: certain files in the "nand" partition would need modified/replaced as well.

NAND structure

Old3DS New3DS Partition name Offset Size NCSD partition FS type NCSD partition encryption type NCSD partition index AES engine keyslot Description
Yes Yes 0x0 0x200 NCSD header, this contains the offsets/sizes of the below CTR-NAND partitions. This block also contains the TWL-NAND MBR partition table.
Yes Yes 0x00000000 0x0B100000 0x01 0x01 0x00 0x03 TWL NAND region
No Yes 0x00012C00 0x200 See below. Console-unique encrypted New3DS key-storage, see below.
Yes Yes twln 0x00012E00 0x08FB5200 0x03 TWL-NAND FAT16 File System. (DSi)
Yes Yes twlp 0x09011A00 0x020B6600 0x03 TWL-NAND PHOTO FAT12 File System. (DSi)
Yes Yes 0x0B100000 0x00030000 0x04 0x02 0x01 0x07 By default this partition is empty(only contains 0x00/0xFF bytes since it was never written to), when AGB_FIRM was never launched. This contains the AGB_FIRM GBA savegame.
Yes Yes firm0 0x0B130000 0x00400000 0x03 0x02 0x02 0x06 Firmware partition.
Yes Yes firm1 0x0B530000 0x00400000 0x03 0x02 0x03 0x06 Firmware partition.(Backup partition, same as above)
Yes No 0x0B930000 0x2F5D0000 0x01 0x02 0x04 0x04 CTR-NAND partition. (3DS)
Yes No nand 0x0B95CA00 0x2F3E3600 0x04 CTR-NAND FAT16 File System.
No Yes 0x0B930000 0x41ED0000 0x01 0x03 0x04 0x05 CTR-NAND partition. (New3DS)
No Yes nand 0x0B95AE00 0x41D2D200 0x05 CTR-NAND FAT16 File System.

3DS TWL NAND FAT partitions has FAT volume name "TWL", for CTR FAT partitions this is "CTR". The offset/size for TWL partitions are stored in the MBR partition table, while the CTR partition table info is stored in the NAND NCSD header. Sector0 in the CTR-NAND partition contains a MBR partition table for the nand FAT16 filesystem, and the MBR signature at +0x1fe.

NAND sectors which were never written to before only contain plaintext 0x00 or 0xFF bytes.

None of the NAND partitions are normally accessible from the ARM11, except for twlp. CTR/TWL NAND FS can only be accessed when the exheader access control descriptor for those are enabled. Normally the CTR/TWL NAND descriptors are never enabled for retail ARM11 CXI processes. The ARM11 can only access "nand:/rw/" mounted as the nandrw archive, and "nand:/ro/" mounted as the nandro archive below.


On some 3DS systems(such as 3DS XL), there's a plaintext FAT16 boot record located at NAND offset 0x4000. This block does not exist for launch-day 3DS systems. This is the only plaintext block for this "partition".


Offset Size Description
0x0 0x10 Normal-key for keyslot 0x11, used for generating the rest of the New3DS keyslots' keyX by decrypting various data with AES-ECB. With 9.6.0-X this is only used for generating the keyX for keyslots 0x15 and 0x18.
0x10 0x10 9.6.0-X: Additional normal-key for keyslot 0x11, used for generating the keyX for keyslots 0x16 and 0x19..0x1F.
0x20 0x1E0 Not yet used as of New3DS FIRM 9.6.0-X.

This 0x200-byte sector contains New3DS keys, this entire sector is encrypted with a console-unique keyX+keyY. The keyX+keyY for this is generated by the New3DS arm9bin-loader. Once the arm9bin-loader finishes decrypting this data, the keyX+keyY in the keyslot are then cleared, then the memory used for generating the keydata is disabled(after it finishes using it for TWL key init).

This entire sector is encrypted with AES-ECB, the entire plaintext sector is identical for all retail New3DS systems(unknown for devunits).

CTR partition

The structure of nand/title appears to be exactly the same as SD, except savegames are stored under the nand/data/<ID0>/sysdata directory instead. The sub-directory name under nand/data is the SHA256 hash over the movable.sed keyY. This nand/data/<ID0> directory is the NAND equivalent of the "sdmc/Nintendo 3DS/<ID0>/<ID1>" directory, however the data contained here is stored in cleartext. The movable.sed keyY is only used for AES MACs for nand/data/<ID0>. The nand/data/<ID0>/extdata directory contains the shared extdata, and is structured exactly the same way as SD extdata.

├── __journal.nn_
├── data
│   └── <ID0>
│       ├── extdata          
│       └── sysdata
├── dbs
├── fixdata
│   └── sysdata
├── private
│   └── movable.sed
├── ro
├── rw
├── ticket (This directory is empty since tickets are stored in ticket.db)
├── title
└── tmp (This is usually empty, even when installation for a system update still needs finalized)

The "ro" and "rw" directories are accessible through the "nandrw" and "nandro" archives, respectively. Their contents are as follows:

├── private
├── shared
└── sys
    ├── HWCAL0.dat
    └── HWCAL1.dat
├── shared
└── sys
    ├── lgy.log (This is written to by TWL_FIRM when errors occur, this is equivalent to native.log)
    ├── LocalFriendCodeSeed_B
    ├── native.log (This is written to by ErrDisp)
    ├── rand_seed
    ├── SecureInfo_A
    └── updater.log

TWL partition

The structure of these TWL partitions is mostly the same as DSi, except tickets are stored in the CTR FAT FS. The twlp partition is exactly the same as DSi. The structure of twln/title is exactly the same as CTR NAND/SD, except the .cmd file is a cleartext file.(This is likely a dummy file) The data directory under system titles' /title directory does not exist, this likely only exists for DSiWare. The directory names titleID-High used under twln/title is from DSi.

├── import
├── shared1
├── shared2
│   └── 0000
├── sys
│   ├── TWLFontTable.dat
│   └── log
│       ├── inspect.log
│       └── product.log
├── ticket
├── title
└── tmp
└── photo