Allow setting up GW type EmuNANDs after SD format

addresses #69
This commit is contained in:
d0k3 2017-05-31 23:26:45 +02:00
parent 5694df0dad
commit 7505c0b212
5 changed files with 41 additions and 19 deletions

View File

@ -49,7 +49,7 @@
#endif #endif
// GodMode9 version // GodMode9 version
#define VERSION "1.2.0" #define VERSION "1.2.1"
// input / output paths // input / output paths
#define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9" #define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9"

View File

@ -27,6 +27,7 @@ uint64_t GetSDCardSize() {
bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) {
u8 mbr[0x200] = { 0 }; u8 mbr[0x200] = { 0 };
u8 ncsd[0x200] = { 0 };
u8 mbrdata[0x42] = { u8 mbrdata[0x42] = {
0x80, 0x01, 0x01, 0x00, 0x0C, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x01, 0x00, 0x0C, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x01, 0x01, 0x00, 0x1C, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x01, 0x00, 0x1C, 0xFE, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -64,7 +65,8 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) {
// write the MBR to disk // write the MBR to disk
// !this assumes a fully deinitialized file system! // !this assumes a fully deinitialized file system!
if ((sdmmc_sdcard_init() != 0) || (sdmmc_sdcard_writesectors(0, 1, mbr) != 0)) { if ((sdmmc_sdcard_init() != 0) || (sdmmc_sdcard_writesectors(0, 1, mbr) != 0) ||
(emu_size && ((sdmmc_nand_readsectors(0, 1, ncsd) != 0) || (sdmmc_sdcard_writesectors(1, 1, ncsd) != 0)))) {
ShowPrompt(false, "Error: SD card i/o failure"); ShowPrompt(false, "Error: SD card i/o failure");
return false; return false;
} }

View File

@ -206,10 +206,12 @@ void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) {
} }
u32 SdFormatMenu(void) { u32 SdFormatMenu(void) {
const u32 emunand_size_table[6] = { 0x0, 0x0, 0x3AF, 0x4D8, 0x3FF, 0x7FF }; const u32 emunand_size_table[6] = { 0x0, 0x0, 0x3AF, 0x4D8, 0x3FF, 0x7FF }; // [2] and [3] are placeholders
const u32 cluster_size_table[5] = { 0x0, 0x0, 0x4000, 0x8000, 0x10000 }; const u32 cluster_size_table[5] = { 0x0, 0x0, 0x4000, 0x8000, 0x10000 };
const char* option_emunand_size[6] = { "No EmuNAND", "O3DS NAND size", "N3DS NAND size", "1GB (legacy size)", "2GB (legacy size)", "User input..." }; const char* option_emunand_size[6] = { "No EmuNAND", "SysNAND size (min)", "SysNAND size (full)", "1GB (legacy size)", "2GB (legacy size)", "User input..." };
const char* option_cluster_size[4] = { "Auto", "16KB Clusters", "32KB Clusters", "64KB Clusters" }; const char* option_cluster_size[4] = { "Auto", "16KB Clusters", "32KB Clusters", "64KB Clusters" };
u64 sysnand_size_mb = (((u64)GetNandSizeSectors(NAND_SYSNAND) * 0x200) + 0xFFFFF) / 0x100000;
u64 sysnand_min_size_mb = (((u64)GetNandMinSizeSectors(NAND_SYSNAND) * 0x200) + 0xFFFFF) / 0x100000;
char label[16] = "0:GM9SD"; char label[16] = "0:GM9SD";
u32 cluster_size = 0; u32 cluster_size = 0;
u64 sdcard_size_mb = 0; u64 sdcard_size_mb = 0;
@ -224,7 +226,11 @@ u32 SdFormatMenu(void) {
} }
user_select = ShowSelectPrompt(6, option_emunand_size, "Format SD card (%lluMB)?\nChoose EmuNAND size:", sdcard_size_mb); user_select = ShowSelectPrompt(6, option_emunand_size, "Format SD card (%lluMB)?\nChoose EmuNAND size:", sdcard_size_mb);
if (user_select && (user_select < 6)) { if (user_select == 2) {
emunand_size_mb = sysnand_min_size_mb;
} else if (user_select == 3) {
emunand_size_mb = sysnand_size_mb;
} else if (user_select && (user_select < 6)) {
emunand_size_mb = emunand_size_table[user_select]; emunand_size_mb = emunand_size_table[user_select];
} else if (user_select == 6) do { } else if (user_select == 6) do {
emunand_size_mb = ShowNumberPrompt(0, "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", sdcard_size_mb); emunand_size_mb = ShowNumberPrompt(0, "SD card size is %lluMB.\nEnter EmuNAND size (MB) below:", sdcard_size_mb);
@ -244,16 +250,23 @@ u32 SdFormatMenu(void) {
return 1; return 1;
} }
VirtualFile nand; if (emunand_size_mb >= sysnand_min_size_mb) {
if (!GetVirtualFile(&nand, "S:/nand_minsize.bin")) const char* option_emunand_type[3] = { "RedNAND type", "GW EmuNAND type", "Don't set up" };
return 0; if (emunand_size_mb >= sysnand_size_mb)
InitSDCardFS(); // this has to be initialized for EmuNAND to work user_select = ShowSelectPrompt(3, option_emunand_type, "Choose EmuNAND type to set up:");
if ((nand.size / (1024*1024) <= emunand_size_mb) && ShowPrompt(true, "Clone SysNAND to RedNAND now?")) { else user_select = ShowPrompt(true, "Clone SysNAND to RedNAND now?") ? 1 : 0;
if (!user_select || (user_select > 2)) return 0;
u8 ncsd[0x200];
u32 flags = OVERRIDE_PERM; u32 flags = OVERRIDE_PERM;
if (!PathCopy("E:", "S:/nand_minsize.bin", &flags)) InitSDCardFS(); // this has to be initialized for EmuNAND to work
SetEmuNandBase((user_select == 2) ? 0 : 1); // 0 -> GW EmuNAND
if ((ReadNandSectors(ncsd, 0, 1, 0xFF, NAND_SYSNAND) != 0) ||
(WriteNandSectors(ncsd, 0, 1, 0xFF, NAND_EMUNAND) != 0) ||
(!PathCopy("E:", "S:/nand_minsize.bin", &flags)))
ShowPrompt(false, "Cloning SysNAND to EmuNAND: failed!"); ShowPrompt(false, "Cloning SysNAND to EmuNAND: failed!");
}
DeinitSDCardFS(); DeinitSDCardFS();
}
return 0; return 0;
} }
@ -1225,7 +1238,7 @@ u32 HomeMoreMenu(char* current_path, DirStruct* current_dir, DirStruct* clipboar
ShowPrompt(true, "Initializing SD card failed! Retry?")); ShowPrompt(true, "Initializing SD card failed! Retry?"));
} }
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
InitEmuNandBase(true); AutoEmuNandBase(true);
InitExtFS(); InitExtFS();
GetDirContents(current_dir, current_path); GetDirContents(current_dir, current_path);
return 0; return 0;
@ -1241,7 +1254,7 @@ u32 HomeMoreMenu(char* current_path, DirStruct* current_dir, DirStruct* clipboar
if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_EMUNAND)) if (clipboard->n_entries && (DriveType(clipboard->entry[0].path) & DRV_EMUNAND))
clipboard->n_entries = 0; // remove EmuNAND clipboard entries clipboard->n_entries = 0; // remove EmuNAND clipboard entries
DismountDriveType(DRV_EMUNAND); DismountDriveType(DRV_EMUNAND);
InitEmuNandBase(false); AutoEmuNandBase(false);
InitExtFS(); InitExtFS();
} }
GetDirContents(current_dir, current_path); GetDirContents(current_dir, current_path);
@ -1367,7 +1380,7 @@ u32 GodMode() {
timer_start(); // show splash for at least 1 sec timer_start(); // show splash for at least 1 sec
InitSDCardFS(); InitSDCardFS();
InitEmuNandBase(true); AutoEmuNandBase(true);
InitNandCrypto(); InitNandCrypto();
InitExtFS(); InitExtFS();
@ -1512,7 +1525,7 @@ u32 GodMode() {
clipboard->n_entries = 0; // remove SD clipboard entries clipboard->n_entries = 0; // remove SD clipboard entries
} }
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
InitEmuNandBase(true); AutoEmuNandBase(true);
InitExtFS(); InitExtFS();
GetDirContents(current_dir, current_path); GetDirContents(current_dir, current_path);
if (cursor >= current_dir->n_entries) cursor = 0; if (cursor >= current_dir->n_entries) cursor = 0;
@ -1715,7 +1728,7 @@ u32 GodMode() {
} else if (pad_state & SD_INSERT) { } else if (pad_state & SD_INSERT) {
while (!InitSDCardFS() && ShowPrompt(true, "Initialising SD card failed! Retry?")); while (!InitSDCardFS() && ShowPrompt(true, "Initialising SD card failed! Retry?"));
ClearScreenF(true, true, COLOR_STD_BG); ClearScreenF(true, true, COLOR_STD_BG);
InitEmuNandBase(true); AutoEmuNandBase(true);
InitExtFS(); InitExtFS();
GetDirContents(current_dir, current_path); GetDirContents(current_dir, current_path);
} else if ((pad_state & SD_EJECT) && CheckSDMountState()) { } else if ((pad_state & SD_EJECT) && CheckSDMountState()) {

View File

@ -561,7 +561,7 @@ bool CheckMultiEmuNand(void)
return (emunand_min_sectors && (GetPartitionOffsetSector("0:") >= (u64) (align(emunand_min_sectors + 1, 0x2000) * 2))); return (emunand_min_sectors && (GetPartitionOffsetSector("0:") >= (u64) (align(emunand_min_sectors + 1, 0x2000) * 2)));
} }
u32 InitEmuNandBase(bool reset) u32 AutoEmuNandBase(bool reset)
{ {
if (!reset) { if (!reset) {
u32 last_valid = emunand_base_sector; u32 last_valid = emunand_base_sector;
@ -596,3 +596,8 @@ u32 GetEmuNandBase(void)
{ {
return emunand_base_sector; return emunand_base_sector;
} }
u32 SetEmuNandBase(u32 base_sector)
{
return (emunand_base_sector = base_sector);
}

View File

@ -75,6 +75,7 @@ int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, u32 d
u32 ValidateNandNcsdHeader(NandNcsdHeader* header); u32 ValidateNandNcsdHeader(NandNcsdHeader* header);
u32 GetNandNcsdMinSizeSectors(NandNcsdHeader* ncsd); u32 GetNandNcsdMinSizeSectors(NandNcsdHeader* ncsd);
u32 GetNandMinSizeSectors(u32 nand_src);
u32 GetNandSizeSectors(u32 src); u32 GetNandSizeSectors(u32 src);
u32 GetNandNcsdPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, NandNcsdHeader* ncsd); u32 GetNandNcsdPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, NandNcsdHeader* ncsd);
u32 GetNandPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, u32 nand_src); u32 GetNandPartitionInfo(NandPartitionInfo* info, u32 type, u32 subtype, u32 index, u32 nand_src);
@ -84,5 +85,6 @@ u32 GetOtpHash(void* hash);
u32 GetNandCid(void* cid); u32 GetNandCid(void* cid);
bool CheckMultiEmuNand(void); bool CheckMultiEmuNand(void);
u32 InitEmuNandBase(bool reset); u32 AutoEmuNandBase(bool reset);
u32 GetEmuNandBase(void); u32 GetEmuNandBase(void);
u32 SetEmuNandBase(u32 base_sector);