Tutorial  Updated

Build DSi NAND from scratch

How do you build a NAND?
Before we start building NAND, let's look at the basic structure to help you to identify each section used, the placement, and purpose.

NAND Layout

AddressItemNotes
0x00000000-0x00000200MBR (Samsung, ST)This tells stage1 (BIOS) how NAND is laid out.
0x00000200-0x0004E800stage2This is the bootloader, needed to run the console. There are two main options for stage2: v2665-9336, and v2435-8325. Both are explained later in the guide.
This region does not get encrypted when the rest of NAND does.
0x0010EE00-0x0010F000TWL_MAIN VBRTWL_MAIN is a FAT16 partition used to store the firmware, system data, and games. The VBR is the start of the partition.
0x0010F000-0x0010F018TWL_MAIN extra bytesNot really sure what these are, but they're needed to make a valid partition. I included them in the VBR download.
0x0CF09A00-0x0CF09C00TWL_PHOTO VBRTWL_PHOTO is a FAT12 partition used to store photo data. Different bytes, but same purpose as TWL_MAIN vbr.
0x0CF09C00-0x0CF09C04TWL_PHOTO extra bytesDifferent bytes, but same purpose as TWL_MAIN extra bytes.
0x0F000000-0x0F000040no$gba footerA footer where the CID and ConsoleID are stored. This is used by emulators, NAND mounting tools, and NAND restore tools.





Creating TWL_MAIN partition
Let's start with building the partitions in NAND. First, you must download the TWL_MAIN VBR with the extra bytes. Then insert both the VBR and extra bytes into a zerofilled file that is the full size of the partition (0xCDF1200). Inserting the VBR makes the file a valid partition, so you can now mount the partition with the tool of your choice.

Installing system titles
There are a few essential system titles* needed for the NAND to boot. These are the System Settings (HNBx), Launcher (HNAx), wlanfirm (HNCA), and sysmenuVersion (HNLx).
*I suggest starting with factory firmware, as this has fewer requirements to work. HWInfo (discussed later) is not needed, and configs can be somewhat ignored.
If you have WiFi module versions DWM-W024 or J27H020, you will need wlanfirm v512 or higher. Otherwise you will experience a brick. If you have DWM-W015, you can run any wlanfirm.
You can find lists of all titles, their versions, and downloads here. These downloads will need a TAD unpacker (perl | python).

DSiWare title data is split into two locations. One for the ticket, and one for the app + metadata (TMD):

  • Ticket folder : nand:/ticket/[TID_CATEGORY]/
  • App+TMD folder : nand:/title/[TID_CATEGORY]/[TID_UNIQUE]/content/
The TID_CATEGORY is the application type (Launcher, system, user, data), obtained from 0x234-237 in the app (may be .nds). The bytes are in reverse order, so you'll need to flip them around (eg. 0f 00 03 00 --] 00 03 00 0f).

The TID_UNIQUE, found from 0x230-233 in the app, is a unique 4 byte ASCII identifier. This ID is also in reverse order.
To install, take the ticket file and save it to the ticket folder as [TID_UNIQUE].tik. Now take the TMD and copy it to the title folder as title.tmd. The naming of the app is a bit more complicated.

The name of the app is based on the app version. So, version 1 of the app would mean the app gets saved to the title folder as 00000001.app. The version of the app can be found at 0x1E4-1E7 in the TMD. Dev apps will be a bit different, having hex strings in place of versions, like 0f960d6a.

Each title installed MUST go into the paths listed above, otherwise it will be deleted by the Launcher, or cause the system to fail to boot. Below are preset title paths for the latest firmwares of each region. I suggest using the lists as a reference.

Copying System Data
I've listed all the paths below, with links to download the files. There isn't much more to this stage of the NAND setup than copying and pasting.

  • nand:/sys/cert.sys (prod | dev)
  • nand:/sys/TWLFontTable.dat (Worldwide | China | Korea)
  • nand:/shared1/TWLCFG1.dat (all)
  • nand:/shared1/TWLCFG0.dat (all)
  • nand:/shared2/launcher/wrap.bin (all)
  • nand:/shared2/0000 (all)
  • nand:/sys/HWINFO_N.dat (all)
If you have an existing HWINFO_S.dat, you can place it in nand:/sys/. This file is tied to the CPU, and is signed, so your HWInfo MUST match the console you install it to. You can verify that the HWInfo matches the target console with this script. If you have a development unit, it is also possible to resign HWInfo.
Code:
[b]Verify HWINFO_S using retail key:[/b]
    python3 hwinfo.py --consoleid [consoleid] --hwinfo HWINFO_S_prod.dat verify
[b]Verify HWINFO_S using dev key:[/b]
    python3 hwinfo.py --consoleid [consoleid] --hwinfo HWINFO_S_dev.dat verify --dev
[b]Resign HWINFO_S using dev key:[/b]
    python3 hwinfo.py --consoleid [consoleid] --hwinfo HWINFO_S.dat resign --dev

The existing file must have data from 0x0-0x80 in it. So, if you're making HWINFO_S from scratch, put 0x80 of zeroes infront of the actual data, then run the resign command.
This will create a new file HWINFO_S_resigned.dat with the signature changed (0x0-0x80).

Unlaunch
Instead of the typical unlaunch install (unlaunch gets appended to the region specific Launcher), we're going to install it to the prototype Launcher directory. If the main Launcher ever fails (gets corrupted, is deleted), then stage2 will look for a prototype Launcher to boot. This fallback will cause the "backup unlaunch" to be loaded, giving us an extra layer of protection.

Install the unlaunch TMD to nand:/title/00030017/484e4141/content/title.tmd. Be mindful of if there is an existing TMD in that location. If there is, overwrite the start of the unlaunch TMD with the pre-existing TMD. With the TMD as it is now, the Launcher will try to delete it. Write protect the unlaunch TMD to prevent this.

By default, unlaunch will be disabled due to the region specific Launcher being valid. We can safely break the Launcher to enable unlaunch by changing the TMD from "HNAx" to "GNAx". Use specifically "GNAx", as this is used by custom installers. Now, write protect this TMD as well.

Unless you are using factory firmware, or you have a valid HWINFO_S.dat, unlaunch MUST be enabled.



Photo partition
Making TWL_PHOTO is pretty easy. Just like with TWL_MAIN, we'll insert the TWL_PHOTO VBR with extra bytes into a zerofilled file matching the partition's full size. The only difference is that this partition is 0x20B6600 long.

Rather than a bunch of files, we just need to create a single folder. Make photo:/photo/. The photo folder is seen as the "root" of the partition, so, without it, the management file cannot be created, and the camera app will fail.



Creating full nand.bin
Now that we've prepared both partitions, it's time to put them into a larger nand.bin. First, make a zerofilled file with a size of 0x0F000000. Now, insert both TWL_MAIN and TWL_PHOTO.

  • TWL_MAIN gets copied at NAND offset 0x0010EE00, until the entire file is written
  • TWL_PHOTO get copied at NAND offset 0x0CF09A00, until the entire file is written
Copying stage2
Download any stage2 that supports unlaunch, and matches your current console (retail on retail, dev on dev). Each stage2 (.nand extension) will be one to one with how it appears in NAND, with the exception of MBR being zerofilled. As such, we can copy 0x00 onwards of the stage2 into 0x00 onwards of the NAND, until the entire file has been written.
There are a few different stage2s available. The standard one shipped on all DSis (v2435-8325) works fine, but we use a slightly updated version (v2665-9336) for the NAND builder. The later revision stage2 is functionally the same, but it blocks the dangerous standard unlaunch installer, pushing people into using a safer alternative. Though if you've followed my guide this far, you probably don't care about safety (:

Copying MBR
There are two possible MBRs depending on your NAND manufacturer, assuming you're using an official NAND chip. If you are using a custom chip (ie. SD card as NAND), you will need to set up the MBR manually to match the DSi's layout. I won't go into that here, but the Wikipedia article on MBR has very detailed information to get you started.

  • SAMSUNG : KLM5617EFW-B301 OR KMAPF0000M-S998 (download)
  • ST : NAND02GAH0LZC5 (download)
To add the MBR, overwrite the first 0x200 of NAND with the .bin.

Encrypting
Encrypting is pretty easy. Simply download twltool, then run the command below.
 twltool nandcrypt --cid [cid] --consoleid [consoleID] --in [nand.bin] --out [nand.enc.bin]
If you try to compress your newly built NANDs, you will notice that the size stays the same. Why? Negative encryption.

When you initially work on the NAND, it is decrypted, and filled with zerobytes. This compresses well. However, when we encrypt the NAND in order to flash it back, all those zerobytes will turn into encrypted data. When this happens, the entire NAND becomes high entropy data, none of which compresses well. There is a solution to this though.

Encrypt the data region of TWL_MAIN (make sure to avoid the file tables), then mount and write to the partition. Afterwards, the final encryption with twltool will turn unused encrypted data back into zeroes.

no$gba footer

We're finally down to the last step. The footer is necessary to restoring the NAND dump, and testing in emulators. The structure is as follows:

  • 16 bytes of ASCII: DSi eMMC CID/CPU
  • 16 bytes: [cid]
  • 32 bytes: [consoleid]
  • 24 bytes: 0x00 repeating
The footer should be 0x40, and should be appended to the end of the NAND. Not overwritten.

Weirdly, the ConsoleID is in reverse endian compared to what most tools use, so swap the ID before you write it. Once you've created the no$gba footer, insert it into the NAND at 0x0F000000. Now that you've written the footer, your NAND is finished, and should be ready to flash to the console!



Thanks @k66 for testing this.
 
Last edited by rvtr,
Thanks to @rvtr 's tutorial, this can save a lot of DSis. :yaynds:
.
.
EDIT:
Since rvtr has been quite busy recently, I am making a hotfix to this guide. (Consent has been obtained)

Installing system titles
Encrypt the tik file using the syscrypt command of twltool. For the usage of syscrypt, see twltool help.

no$gba footer
32 bytes: [consoleid] → 8 bytes: [consoleid]
- Samsung eMMC: add no$gba footer (length 0x40) to the end of NAND.
- ST eMMC: add '00bytes' (length 0x580000), and no$gba footer (length 0x40) to the end of NAND.
.
.
.
(The following is a quick process I wrote based on rvtr's guide, for reference only.)
This is the process of manually creating a compressible NAND
Steps
1.
Create nand.bin, (Samsung eMMC) length 0xF000000, overwrite paste Stage2(.nand) to 0x00, overwrite paste MBR to 0x00.
(Stage2 won't encrypt, I can add it at any time. It's more convenient to add at this time.)
(twltool can only output 240MB (Samsung NAND size), so creating a 245.5MB ST NAND seems pointless.)


2. Encrypt nand.bin using twltool, output nand.enc.bin: copy twl_main (at 0x10EE00, length 0xCDF1200) and twl_photo (at 0xCF09A00, length 0x20B6600), overwrite paste to nand.bin. (Re-encrypting the NAND will restore the encrypted bytes to '00')
Overwrite paste twl_main VBR+00bytes (length 0x11200) to nand.bin 0x10EE00 .
Overwrite paste twl_photo VBR+00bytes (length 0x6600) to nand.bin 0xCF09A00.

3. Encrypt nand.bin using twltool, output nand.enc2.bin.
3a. Samsung eMMC add no$gba footer (length 0x40) to the end of nand.enc2.bin.
3b. ST eMMC add 00bytes (length 0x580000), and no$gba footer (length 0x40) to the end of nand.enc2.bin.

4. ninfs (Allow writing) to mount nand.enc2.bin. OSFMount (cancel Read-only drive) to mount twl_main.img, add system files ,and mount twl_photo.img add photo folder.

5. Test NAND on emulator (e.g. melonDS).
nand a.png
system files.png
.
.
.
If doing this can be a bit faster (The attachment contains a Python script that can perform steps 1-3)
1. Create nand.bin, length 0xF000000, overwrite paste MBR to 0x00.

2.Encrypt nand.bin using twltool, output nand.enc.bin.
Overwrite paste Stage2(.nand) to nand.enc.bin 0x00.
Overwrite paste MBR to nand.enc.bin 0x00.
Overwrite paste twl_main VBR+00bytes (length 0x11200) to nand.enc.bin 0x10EE00 .
Overwrite paste twl_photo VBR+00bytes (length 0x6600) to nand.enc.bin 0xCF09A00.

3. Encrypt nand.enc.bin using twltool, output nand.enc2.bin.
3a. Samsung eMMC add no$gba footer (length 0x40) to the end of nand.enc2.bin.
3b. ST eMMC add 00bytes (length 0x580000), and no$gba footer (length 0x40) to the end of nand.enc2.bin.

4. ninfs (Allow writing) to mount nand.enc2.bin. OSFMount (cancel Read-only drive) to mount twl_main.img, add system files ,and mount twl_photo.img add photo folder.

5. Test NAND on emulator (e.g. melonDS).
nand b.png

About 'VBR+00bytes' (See the attachment)
Calculation method: (I referred to GBATEK's 'DSi SD/MMC Filesystem')
Volume Boot Record (VBR) (FAT12/FAT16) (DOS 4.0 EBPB)
00Bh 2 bytes / sector (DSi: 0200h) =512bytes
00Dh 1 sectors / cluster (DSi: 20h) =32sectors
00Eh 2 sectors / boot-record (DSi: 0001h) =1sector
010h 1 number of FAT-copys (DSi: 02h) =2
011h 2 entrys / root-directory (DSi: 0200h) =512entrys
016h 2 sectors / FAT (DSi: A:0034h, B:0009h) main:0x34=52sectors, photo:0x9=9sectors

Root directory
"The following sectors are the Root directory, again, size depends on the info in bootsector (on FAT32 is it's a normal cluster chain with variable size). Each entry consists of 32 bytes"
512*32 = 16384bytes, 16384/512=32sectors

'VBR+00bytes' = boot-record(VBR) + FAT1 + FAT2 + root-directory
twl_main VBR+00bytes: 1+(2*52)+32 = 137sectors, 137*512 = 70144bytes (0x11200)
twl_photo VBR+00bytes: 1+(2*9)+32 = 51sectors, 51*512 = 26112bytes (0x6600)

A Python version of 'remaketad.pl', supporting batch processing. (See the attachment 'remaketad')
The py file does not include the common key, it needs to be manually entered in the py file.
Input a tad file or folder(containing the tad files), it will output to the nand folder.
Supported commands:
dsi_prod: retail TAD
dsi_dev: development TAD
dsi_debugger: TAD in TwlSystemUpdater

For example:
input 'w.tad', dsi_prod command, remaketad.py w.tad dsi_prod
input 'tad' folder, dsi_prod command, remaketad.py tad dsi_prod

A batch script for encrypting tik using twltool. (See the attachment 'encrypt_tik')
It's just a batch process and does not include twltool, you still need to download twltool.
The input is ticket folder (ticket\subfolder\tik files (unencrypted)), output to ticket_enc folder .
encrypt_tik.py --consoleid [consoleID]
You need to rename the ticket_enc folder to ticket and put it into NAND.
 

Attachments

Last edited by k66,

Site & Scene News

Popular threads in this forum