From 7505c0b2121338248232e57c012401482b1d3a6a Mon Sep 17 00:00:00 2001 From: d0k3 Date: Wed, 31 May 2017 23:26:45 +0200 Subject: [PATCH] Allow setting up GW type EmuNANDs after SD format addresses #69 --- source/common/common.h | 2 +- source/fs/fsutil.c | 4 +++- source/godmode.c | 43 +++++++++++++++++++++++++++--------------- source/nand/nand.c | 7 ++++++- source/nand/nand.h | 4 +++- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/source/common/common.h b/source/common/common.h index f81c198..3e40b13 100644 --- a/source/common/common.h +++ b/source/common/common.h @@ -49,7 +49,7 @@ #endif // GodMode9 version -#define VERSION "1.2.0" +#define VERSION "1.2.1" // input / output paths #define INPUT_PATHS "0:", "0:/files9", "1:/rw/files9" diff --git a/source/fs/fsutil.c b/source/fs/fsutil.c index 565f0a0..91f7491 100644 --- a/source/fs/fsutil.c +++ b/source/fs/fsutil.c @@ -27,6 +27,7 @@ uint64_t GetSDCardSize() { bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { u8 mbr[0x200] = { 0 }; + u8 ncsd[0x200] = { 0 }; u8 mbrdata[0x42] = { 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, @@ -64,7 +65,8 @@ bool FormatSDCard(u64 hidden_mb, u32 cluster_size, const char* label) { // write the MBR to disk // !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"); return false; } diff --git a/source/godmode.c b/source/godmode.c index e4a18a7..42a53cd 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -206,10 +206,12 @@ void DrawDirContents(DirStruct* contents, u32 cursor, u32* scroll) { } 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 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" }; + 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"; u32 cluster_size = 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); - 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]; } else if (user_select == 6) do { 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; } - VirtualFile nand; - if (!GetVirtualFile(&nand, "S:/nand_minsize.bin")) - return 0; - InitSDCardFS(); // this has to be initialized for EmuNAND to work - if ((nand.size / (1024*1024) <= emunand_size_mb) && ShowPrompt(true, "Clone SysNAND to RedNAND now?")) { + if (emunand_size_mb >= sysnand_min_size_mb) { + const char* option_emunand_type[3] = { "RedNAND type", "GW EmuNAND type", "Don't set up" }; + if (emunand_size_mb >= sysnand_size_mb) + user_select = ShowSelectPrompt(3, option_emunand_type, "Choose EmuNAND type to set up:"); + 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; - 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!"); + DeinitSDCardFS(); } - DeinitSDCardFS(); return 0; } @@ -1225,7 +1238,7 @@ u32 HomeMoreMenu(char* current_path, DirStruct* current_dir, DirStruct* clipboar ShowPrompt(true, "Initializing SD card failed! Retry?")); } ClearScreenF(true, true, COLOR_STD_BG); - InitEmuNandBase(true); + AutoEmuNandBase(true); InitExtFS(); GetDirContents(current_dir, current_path); 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)) clipboard->n_entries = 0; // remove EmuNAND clipboard entries DismountDriveType(DRV_EMUNAND); - InitEmuNandBase(false); + AutoEmuNandBase(false); InitExtFS(); } GetDirContents(current_dir, current_path); @@ -1367,7 +1380,7 @@ u32 GodMode() { timer_start(); // show splash for at least 1 sec InitSDCardFS(); - InitEmuNandBase(true); + AutoEmuNandBase(true); InitNandCrypto(); InitExtFS(); @@ -1512,7 +1525,7 @@ u32 GodMode() { clipboard->n_entries = 0; // remove SD clipboard entries } ClearScreenF(true, true, COLOR_STD_BG); - InitEmuNandBase(true); + AutoEmuNandBase(true); InitExtFS(); GetDirContents(current_dir, current_path); if (cursor >= current_dir->n_entries) cursor = 0; @@ -1715,7 +1728,7 @@ u32 GodMode() { } else if (pad_state & SD_INSERT) { while (!InitSDCardFS() && ShowPrompt(true, "Initialising SD card failed! Retry?")); ClearScreenF(true, true, COLOR_STD_BG); - InitEmuNandBase(true); + AutoEmuNandBase(true); InitExtFS(); GetDirContents(current_dir, current_path); } else if ((pad_state & SD_EJECT) && CheckSDMountState()) { diff --git a/source/nand/nand.c b/source/nand/nand.c index 38a38bc..1183c4e 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -561,7 +561,7 @@ bool CheckMultiEmuNand(void) return (emunand_min_sectors && (GetPartitionOffsetSector("0:") >= (u64) (align(emunand_min_sectors + 1, 0x2000) * 2))); } -u32 InitEmuNandBase(bool reset) +u32 AutoEmuNandBase(bool reset) { if (!reset) { u32 last_valid = emunand_base_sector; @@ -596,3 +596,8 @@ u32 GetEmuNandBase(void) { return emunand_base_sector; } + +u32 SetEmuNandBase(u32 base_sector) +{ + return (emunand_base_sector = base_sector); +} diff --git a/source/nand/nand.h b/source/nand/nand.h index 5961945..ffa62ca 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -75,6 +75,7 @@ int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, u32 d u32 ValidateNandNcsdHeader(NandNcsdHeader* header); u32 GetNandNcsdMinSizeSectors(NandNcsdHeader* ncsd); +u32 GetNandMinSizeSectors(u32 nand_src); u32 GetNandSizeSectors(u32 src); 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); @@ -84,5 +85,6 @@ u32 GetOtpHash(void* hash); u32 GetNandCid(void* cid); bool CheckMultiEmuNand(void); -u32 InitEmuNandBase(bool reset); +u32 AutoEmuNandBase(bool reset); u32 GetEmuNandBase(void); +u32 SetEmuNandBase(u32 base_sector);