Line 11:
Line 11:
The 3DS employs a wear leveling scheme on the savegame FLASH chips. This is done through the usage of blockmaps and a journal. The blockmap is located at offset 0 of the flash chip, and is immediately followed by the journal. The initial state is dictated by the blockmap, and the journal is then applied to that.
The 3DS employs a wear leveling scheme on the savegame FLASH chips. This is done through the usage of blockmaps and a journal. The blockmap is located at offset 0 of the flash chip, and is immediately followed by the journal. The initial state is dictated by the blockmap, and the journal is then applied to that.
+
First, there are 8 bytes whose purposes are currently unknown. Then comes the blockmap.
The blockmap structure is simple:
The blockmap structure is simple:
<pre>
<pre>
struct header_entry {
struct header_entry {
+
uint8_t phys_sec; // when bit7 is set, block has checksums, otherwise checksums are all zero
+
uint8_t alloc_cnt;
uint8_t chksums[8];
uint8_t chksums[8];
−
uint8_t phys_sec;
−
uint8_t alloc_cnt;
} __attribute__((__packed__));
} __attribute__((__packed__));
</pre>
</pre>
+
There's one entry per sector, counting from physical sector 1 (sector 0 contains the blockmap/journal).
+
+
The 2 bytes that follow the blockmap are the CRC16 (modbus) of the first 8 bytes and the blockmap.
+
+
Then comes the journal.
The journal structure is as follows:
The journal structure is as follows:
<pre>
<pre>