Savegames: Difference between revisions
Line 9: | Line 9: | ||
=== Wearleveling === | === Wearleveling === | ||
The 3DS employs a wearleveling scheme on the savegame FLASH chips. This is done trough blockmaps. | The 3DS employs a wearleveling scheme on the savegame FLASH chips. This is done trough 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 blockmap structure is simple: | |||
<pre> | |||
struct header_entry { | |||
uint8_t chksums[8]; | |||
uint8_t phys_sec; | |||
uint8_t alloc_cnt; | |||
} __attribute__((__packed__)); | |||
</pre> | |||
The journal structure is as follows: | |||
<pre> | <pre> | ||
struct sector_entry { | struct sector_entry { | ||
Line 17: | Line 27: | ||
uint8_t phys_sec; // Mapped from sector | uint8_t phys_sec; // Mapped from sector | ||
uint8_t prev_phys_sec; // Virtual sector previously mapped to | uint8_t prev_phys_sec; // Virtual sector previously mapped to | ||
uint8_t phys_realloc_cnt;// Amount of times physical sector has been remapped | uint8_t phys_realloc_cnt; // Amount of times physical sector has been remapped | ||
uint8_t virt_realloc_cnt;// Amount of times virtual sector has been remapped | uint8_t virt_realloc_cnt; // Amount of times virtual sector has been remapped | ||
uint8_t chksums[8]; | uint8_t chksums[8]; | ||
} __attribute__(( | } __attribute__((__packed__)); | ||
struct long_sector_entry { | struct long_sector_entry{ | ||
struct sector_entry sector; | struct sector_entry sector; | ||
struct sector_entry dupe; | struct sector_entry dupe; | ||
uint32_t magic; | uint32_t magic; | ||
}; | }__attribute__((__packed__)); | ||
</pre> | </pre> | ||