Skip to content

Commit

Permalink
Merge branch 'master' into 3gx-loader
Browse files Browse the repository at this point in the history
  • Loading branch information
TuxSH committed Jul 12, 2023
2 parents 685ec2c + 97418ca commit fcef01f
Show file tree
Hide file tree
Showing 22 changed files with 242 additions and 196 deletions.
38 changes: 11 additions & 27 deletions arm9/source/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ static_assert(sizeof(CfgDataMcu) > 0, "wrong data size");

static const char *singleOptionIniNamesBoot[] = {
"autoboot_emunand",
"use_emunand_firm_if_r_pressed",
"enable_external_firm_and_modules",
"enable_game_patching",
"app_syscore_threads_on_core_2",
Expand Down Expand Up @@ -647,10 +646,9 @@ static size_t saveLumaIniConfigToStr(char *out)
lumaVerStr, lumaRevSuffixStr,

(int)CONFIG_VERSIONMAJOR, (int)CONFIG_VERSIONMINOR,
(int)CONFIG(AUTOBOOTEMU), (int)CONFIG(USEEMUFIRM),
(int)CONFIG(LOADEXTFIRMSANDMODULES), (int)CONFIG(PATCHGAMES),
(int)CONFIG(REDIRECTAPPTHREADS), (int)CONFIG(PATCHVERSTRING),
(int)CONFIG(SHOWGBABOOT),
(int)CONFIG(AUTOBOOTEMU), (int)CONFIG(LOADEXTFIRMSANDMODULES),
(int)CONFIG(PATCHGAMES), (int)CONFIG(REDIRECTAPPTHREADS),
(int)CONFIG(PATCHVERSTRING), (int)CONFIG(SHOWGBABOOT),

1 + (int)MULTICONFIG(DEFAULTEMU), 4 - (int)MULTICONFIG(BRIGHTNESS),
splashPosStr, (unsigned int)cfg->splashDurationMsec,
Expand Down Expand Up @@ -825,7 +823,6 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
};

static const char *singleOptionsText[] = { "( ) Autoboot EmuNAND",
"( ) Use EmuNAND FIRM if booting with R",
"( ) Enable loading external FIRMs and modules",
"( ) Enable game patching",
"( ) Redirect app. syscore threads to core2",
Expand All @@ -834,8 +831,9 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
};

static const char *optionsDescription[] = { "Select the default EmuNAND.\n\n"
"It will be booted when no\n"
"directional pad buttons are pressed.",
"It will be booted when no directional\n"
"pad buttons are pressed (Up/Right/Down\n"
"/Left equal EmuNANDs 1/2/3/4).",

"Select the screen brightness.",

Expand Down Expand Up @@ -881,17 +879,6 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
"(Up/Right/Down/Left equal EmuNANDs\n"
"1/2/3/4).",

"If enabled, when holding R on boot\n"
"SysNAND will be booted with an\n"
"EmuNAND FIRM.\n\n"
"Otherwise, an EmuNAND will be booted\n"
"with the SysNAND FIRM.\n\n"
"To use a different EmuNAND from the\n"
"default, hold a directional pad button\n"
"(Up/Right/Down/Left equal EmuNANDs\n"
"1/2/3/4), also add A if you have\n"
"a matching payload.",

"Enable loading external FIRMs and\n"
"system modules.\n\n"
"This isn't needed in most cases.\n\n"
Expand All @@ -915,14 +902,10 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
"by about 10%. Can break some games\n"
"and other applications.\n",

"Enable showing the current NAND/FIRM:\n\n"
"Enable showing the current NAND:\n\n"
"\t* Sys = SysNAND\n"
"\t* Emu = EmuNAND 1\n"
"\t* EmuX = EmuNAND X\n"
"\t* SysE = SysNAND with EmuNAND 1 FIRM\n"
"\t* SyEX = SysNAND with EmuNAND X FIRM\n"
"\t* EmuS = EmuNAND 1 with SysNAND FIRM\n"
"\t* EmXS = EmuNAND X with SysNAND FIRM\n\n"
"\t* EmuX = EmuNAND X\n\n"
"or a user-defined custom string in\n"
"System Settings.\n\n"
"Refer to the wiki for instructions.",
Expand All @@ -934,8 +917,10 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
FirmwareSource nandType = FIRMWARE_SYSNAND;
if(isSdMode)
{
// Check if there is at least one emuNAND
u32 emuIndex = 0;
nandType = FIRMWARE_EMUNAND;
locateEmuNand(&nandType);
locateEmuNand(&nandType, &emuIndex, false);
}

struct multiOption {
Expand All @@ -958,7 +943,6 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
bool enabled;
bool visible;
} singleOptions[] = {
{ .visible = nandType == FIRMWARE_EMUNAND },
{ .visible = nandType == FIRMWARE_EMUNAND },
{ .visible = true },
{ .visible = true },
Expand Down
11 changes: 5 additions & 6 deletions arm9/source/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@

#define CONFIG_FILE "config.ini"
#define CONFIG_VERSIONMAJOR 3
#define CONFIG_VERSIONMINOR 7
#define CONFIG_VERSIONMINOR 8

#define BOOTCFG_NAND BOOTCONFIG(0, 7)
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(6, 1)
#define BOOTCFG_NTRCARDBOOT BOOTCONFIG(7, 1)
#define BOOTCFG_NAND BOOTCONFIG(0, 1)
#define BOOTCFG_EMUINDEX BOOTCONFIG(1, 3)
#define BOOTCFG_NOFORCEFLAG BOOTCONFIG(3, 1)
#define BOOTCFG_NTRCARDBOOT BOOTCONFIG(4, 1)

enum multiOptions
{
Expand All @@ -57,7 +57,6 @@ enum multiOptions
enum singleOptions
{
AUTOBOOTEMU = 0,
USEEMUFIRM,
LOADEXTFIRMSANDMODULES,
PATCHGAMES,
REDIRECTAPPTHREADS,
Expand Down
6 changes: 3 additions & 3 deletions arm9/source/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ __attribute__((aligned(4))) static u8 nandCtr[AES_BLOCK_SIZE];
static u8 nandSlot;
static u32 fatStart = 0;

FirmwareSource firmSource = FIRMWARE_SYSNAND;
FirmwareSource ctrNandLocation = FIRMWARE_SYSNAND;

__attribute__((aligned(4))) static const u8 key1s[2][AES_BLOCK_SIZE] = {
{0x07, 0x29, 0x44, 0x38, 0xF8, 0xC9, 0x75, 0x93, 0xAA, 0x0E, 0x4A, 0xB4, 0xAE, 0x84, 0xC1, 0xD8},
Expand All @@ -348,7 +348,7 @@ int ctrNandInit(void)
u8 __attribute__((aligned(4))) temp[0x200];

//Read NCSD header
result = firmSource == FIRMWARE_SYSNAND ? sdmmc_nand_readsectors(0, 1, temp) : sdmmc_sdcard_readsectors(emuOffset + emuHeader, 1, temp);
result = ctrNandLocation == FIRMWARE_SYSNAND ? sdmmc_nand_readsectors(0, 1, temp) : sdmmc_sdcard_readsectors(emuOffset + emuHeader, 1, temp);

if(!result)
{
Expand All @@ -375,7 +375,7 @@ int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)

//Read
int result;
if(firmSource == FIRMWARE_SYSNAND)
if(ctrNandLocation == FIRMWARE_SYSNAND)
result = sdmmc_nand_readsectors(sector + fatStart, sectorCount, outbuf);
else
{
Expand Down
2 changes: 1 addition & 1 deletion arm9/source/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
#define SHA_224_HASH_SIZE (224 / 8)
#define SHA_1_HASH_SIZE (160 / 8)

extern FirmwareSource firmSource;
extern FirmwareSource ctrNandLocation;

void sha(void *res, const void *src, u32 size, u32 mode);

Expand Down
33 changes: 21 additions & 12 deletions arm9/source/emunand.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
u32 emuOffset,
emuHeader;

void locateEmuNand(FirmwareSource *nandType)
void locateEmuNand(FirmwareSource *nandType, u32 *emunandIndex, bool configureCtrNandParams)
{
static u8 __attribute__((aligned(4))) temp[0x200];
static u32 nandSize = 0,
Expand All @@ -51,7 +51,10 @@ void locateEmuNand(FirmwareSource *nandType)
fatStart = *(u32 *)(temp + 0x1C6); //First sector of the FAT partition
}

for(u32 i = 0; i < 3; i++)
/*if (*nandType == FIRMWARE_SYSNAND)
return;*/

for(u32 i = 0; i < 3; i++) // Test the different kinds of multi-EmuNAND there are, unless we are looking for the first one
{
static const u32 roundedMinsizes[] = {0x1D8000, 0x26E000};

Expand All @@ -65,39 +68,45 @@ void locateEmuNand(FirmwareSource *nandType)
nandOffset = roundedMinsizes[ISN3DS ? 1 : 0]; //"Minsize" layout
break;
case 0:
nandOffset = *nandType == FIRMWARE_EMUNAND ? 0 : (nandSize > 0x200000 ? 0x400000 : 0x200000); //"Legacy" layout
nandOffset = nandSize > 0x200000 ? 0x400000 : 0x200000; //"Legacy" layout
break;
}

if(*nandType != FIRMWARE_EMUNAND) nandOffset *= ((u32)*nandType - 1);
nandOffset *= *emunandIndex; // always 0 for 1st EmuNAND

if(fatStart >= nandOffset + roundedMinsizes[ISN3DS ? 1 : 0])
{
//Check for RedNAND
if(!sdmmc_sdcard_readsectors(nandOffset + 1, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0)
{
emuOffset = nandOffset + 1;
emuHeader = 0;
if (configureCtrNandParams)
{
emuOffset = nandOffset + 1;
emuHeader = 0;
}
return;
}

//Check for Gateway EmuNAND
else if(i != 2 && !sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) && memcmp(temp + 0x100, "NCSD", 4) == 0)
{
emuOffset = nandOffset;
emuHeader = nandSize;
if (configureCtrNandParams)
{
emuOffset = nandOffset;
emuHeader = nandSize;
}
return;
}
}

if(*nandType == FIRMWARE_EMUNAND) break;
if(*emunandIndex == 0) break; // See above comments
}

//Fallback to the first EmuNAND if there's no second/third/fourth one, or to SysNAND if there isn't any
if(*nandType != FIRMWARE_EMUNAND)
if(*emunandIndex != 0)
{
*nandType = FIRMWARE_EMUNAND;
locateEmuNand(nandType);
*emunandIndex = 0;
locateEmuNand(nandType, emunandIndex, configureCtrNandParams);
}
else *nandType = FIRMWARE_SYSNAND;
}
Expand Down
2 changes: 1 addition & 1 deletion arm9/source/emunand.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@
extern u32 emuOffset,
emuHeader;

void locateEmuNand(FirmwareSource *nandType);
void locateEmuNand(FirmwareSource *nandType, u32 *emunandIndex, bool configureCtrNandParams);
u32 patchEmuNand(u8 *arm9Section, u32 kernel9Size, u8 *process9Offset, u32 process9Size, u8 *kernel9Address, u32 firmVersion);
23 changes: 17 additions & 6 deletions arm9/source/firm.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ u32 loadNintendoFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadF
u32 firmVersion = 0xFFFFFFFF,
firmSize;

bool ctrNandError = isSdMode && !mountFs(false, false);
bool ctrNandError = isSdMode && !remountCtrNandPartition(false);

if(!ctrNandError)
{
Expand Down Expand Up @@ -269,6 +269,8 @@ static inline void mergeSection0(FirmwareType firmType, u32 firmVersion, bool lo
u32 srcModuleSize,
nbModules = 0;

bool isLgyFirm = firmType == TWL_FIRM || firmType == AGB_FIRM;

struct
{
char name[8];
Expand Down Expand Up @@ -311,7 +313,7 @@ static inline void mergeSection0(FirmwareType firmType, u32 firmVersion, bool lo
u8 *dst = firm->section[0].address;
const char *extModuleSizeError = "The external FIRM modules are too large.";
// SAFE_FIRM only for N3DS and only if ENABLESAFEFIRMROSALINA is on
u32 maxModuleSize = (firmType == NATIVE_FIRM || firmType == SAFE_FIRM) ? 0x80000 : 0x600000;
u32 maxModuleSize = !isLgyFirm ? 0x80000 : 0x600000;
for(u32 i = 0, dstModuleSize; i < nbModules; i++, dst += dstModuleSize, maxModuleSize -= dstModuleSize)
{
if(loadFromStorage)
Expand Down Expand Up @@ -344,11 +346,20 @@ static inline void mergeSection0(FirmwareType firmType, u32 firmVersion, bool lo
memcpy(dst, moduleList[i].src, dstModuleSize);
}

//4) Patch NATIVE_FIRM/SAFE_FIRM (N3DS) if necessary
if(nbModules == 6)
//4) Patch kernel to take module size into account
u32 newKipSectionSize = dst - firm->section[0].address;
u32 oldKipSectionSize = firm->section[0].size;
u8 *kernel11Addr = (u8 *)firm + firm->section[1].offset;
u32 kernel11Size = firm->section[1].size;
if (isLgyFirm)
{
if (patchK11ModuleLoadingLgy(newKipSectionSize, kernel11Addr, kernel11Size) != 0)
error("Failed to load sysmodules");
}
else
{
if(patchK11ModuleLoading(firm->section[0].size, dst - firm->section[0].address, (u8 *)firm + firm->section[1].offset, firm->section[1].size) != 0)
error("Failed to inject custom sysmodule");
if (patchK11ModuleLoading(oldKipSectionSize, newKipSectionSize, nbModules, kernel11Addr, kernel11Size) != 0)
error("Failed to load sysmodules");
}
}

Expand Down
70 changes: 51 additions & 19 deletions arm9/source/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,40 @@ static bool switchToMainDir(bool isSd)
}
}

bool mountFs(bool isSd, bool switchToCtrNand)
bool mountSdCardPartition(bool switchMainDir)
{
static bool sdInitialized = false, nandInitialized = false;
if (isSd)
{
if (!sdInitialized)
sdInitialized = f_mount(&sdFs, "sdmc:", 1) == FR_OK;
return sdInitialized && switchToMainDir(true);
}
else
static bool sdInitialized = false;
if (!sdInitialized)
sdInitialized = f_mount(&sdFs, "sdmc:", 1) == FR_OK;

if (sdInitialized && switchMainDir)
return f_chdrive("sdmc:") == FR_OK && switchToMainDir(true);
return sdInitialized;
}

bool remountCtrNandPartition(bool switchMainDir)
{
static bool nandInitialized = false;

if (nandInitialized)
{
if (!nandInitialized)
nandInitialized = f_mount(&nandFs, "nand:", 1) == FR_OK;
return nandInitialized && (!switchToCtrNand || (f_chdrive("nand:") == FR_OK && switchToMainDir(false)));
if (f_unmount("nand:") != FR_OK)
return false;
nandInitialized = false;
}

if (!nandInitialized)
nandInitialized = f_mount(&nandFs, "nand:", 1) == FR_OK;

if (nandInitialized && switchMainDir)
return f_chdrive("nand:") == FR_OK && switchToMainDir(false);
return nandInitialized;
}

void unmountPartitions(void)
{
f_unmount("nand:");
f_unmount("sdmc:");
}

u32 fileRead(void *dest, const char *path, u32 maxSize)
Expand Down Expand Up @@ -412,8 +431,7 @@ static bool backupEssentialFiles(void)
{
size_t sz = sizeof(fileCopyBuffer);

bool ok = !(isSdMode && !mountFs(false, false));

bool ok = true;
ok = ok && fileCopy("nand:/ro/sys/HWCAL0.dat", "backups/HWCAL0.dat", false, fileCopyBuffer, sz);
ok = ok && fileCopy("nand:/ro/sys/HWCAL1.dat", "backups/HWCAL1.dat", false, fileCopyBuffer, sz);

Expand Down Expand Up @@ -454,10 +472,19 @@ static bool backupEssentialFiles(void)

bool doLumaUpgradeProcess(void)
{
// Ensure CTRNAND is mounted
bool ok = mountFs(false, false), ok2 = true;
if (!ok)
return false;
FirmwareSource oldCtrNandLocation = ctrNandLocation;
bool ok = true, ok2 = true, ok3 = true;

// Ensure SysNAND CTRNAND is mounted
if (isSdMode)
{
ctrNandLocation = FIRMWARE_SYSNAND;
if (!remountCtrNandPartition(false))
{
ctrNandLocation = oldCtrNandLocation;
return false;
}
}

// Try to boot.firm to CTRNAND, when applicable
if (isSdMode && memcmp(launchedPathForFatfs, "sdmc:", 5) == 0)
Expand All @@ -470,5 +497,10 @@ bool doLumaUpgradeProcess(void)
fileDelete("sdmc:/luma/config.bin");
fileDelete("nand:/rw/luma/config.bin");

return ok && ok2;
if (isSdMode)
{
ctrNandLocation = oldCtrNandLocation;
ok3 = remountCtrNandPartition(false);
}
return ok && ok2 && ok3;
}

0 comments on commit fcef01f

Please sign in to comment.