Revamp CTRNAND support, add proper support for hiding options in config menu
This commit is contained in:
parent
f005da4d12
commit
37030621ac
@ -77,7 +77,7 @@ static void loadCustomVerString(u16 *out, u32 *verStringSize, u32 currentNand)
|
||||
|
||||
IFile file;
|
||||
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, paths[currentNand], FS_OPEN_READ)))
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, paths[currentNand], FS_OPEN_READ)) || R_SUCCEEDED(fileOpen(&file, ARCHIVE_NAND_RW, paths[currentNand], FS_OPEN_READ)))
|
||||
{
|
||||
u64 fileSize;
|
||||
|
||||
@ -135,7 +135,7 @@ static void loadTitleCodeSection(u64 progId, u8 *code, u32 size)
|
||||
|
||||
IFile file;
|
||||
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)) || R_SUCCEEDED(fileOpen(&file, ARCHIVE_NAND_RW, path, FS_OPEN_READ)))
|
||||
{
|
||||
u64 fileSize;
|
||||
|
||||
@ -159,7 +159,7 @@ static void loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
|
||||
|
||||
IFile file;
|
||||
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)))
|
||||
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, path, FS_OPEN_READ)) || R_SUCCEEDED(fileOpen(&file, ARCHIVE_NAND_RW, path, FS_OPEN_READ)))
|
||||
{
|
||||
u64 fileSize;
|
||||
|
||||
|
107
source/config.c
107
source/config.c
@ -29,18 +29,17 @@
|
||||
#include "buttons.h"
|
||||
#include "pin.h"
|
||||
|
||||
bool readConfig(bool isSdMounted)
|
||||
bool readConfig(void)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
if(!isSdMounted ||
|
||||
fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) ||
|
||||
if(fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) ||
|
||||
memcmp(configData.magic, "CONF", 4) != 0 ||
|
||||
configData.formatVersionMajor != CONFIG_VERSIONMAJOR ||
|
||||
configData.formatVersionMinor != CONFIG_VERSIONMINOR)
|
||||
{
|
||||
configData.config = 0;
|
||||
ret = !isSdMounted;
|
||||
ret = false;
|
||||
}
|
||||
else ret = true;
|
||||
|
||||
@ -68,7 +67,7 @@ void writeConfig(ConfigurationStatus needConfig, u32 configTemp)
|
||||
}
|
||||
}
|
||||
|
||||
void configMenu(bool oldPinStatus, u32 oldPinMode)
|
||||
void configMenu(Fs fsStatus, bool oldPinStatus, u32 oldPinMode)
|
||||
{
|
||||
const char *multiOptionsText[] = { "Default EmuNAND: 1( ) 2( ) 3( ) 4( )",
|
||||
"Screen brightness: 4( ) 3( ) 2( ) 1( )",
|
||||
@ -80,7 +79,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
||||
|
||||
const char *singleOptionsText[] = { "( ) Autoboot SysNAND",
|
||||
"( ) Use SysNAND FIRM if booting with R (A9LH)",
|
||||
"( ) Enable FIRMs and modules loading from SD",
|
||||
"( ) Enable loading external FIRMs and modules",
|
||||
"( ) Use custom path",
|
||||
"( ) Enable region/language emu. and ext. .code",
|
||||
"( ) Show NAND or user string in System Settings",
|
||||
@ -148,8 +147,8 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
||||
"1/2/3/4), also add A if you have\n"
|
||||
"a matching payload.",
|
||||
|
||||
"Enable loading FIRMs and\n"
|
||||
"system modules from the SD card.\n\n"
|
||||
"Enable loading external FIRMs and\n"
|
||||
"system modules.\n\n"
|
||||
"This isn't needed in most cases.\n\n"
|
||||
"Refer to the wiki for instructions.",
|
||||
|
||||
@ -193,25 +192,37 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
||||
u32 posXs[4];
|
||||
u32 posY;
|
||||
u32 enabled;
|
||||
bool visible;
|
||||
} multiOptions[] = {
|
||||
{ .posXs = {19, 24, 29, 34} },
|
||||
{ .posXs = {21, 26, 31, 36} },
|
||||
{ .posXs = {12, 22, 31, 0} },
|
||||
{ .posXs = {14, 19, 24, 29} },
|
||||
{ .posXs = {17, 26, 32, 44} },
|
||||
{ .posXs = {19, 30, 42, 0} }
|
||||
{ .posXs = {19, 24, 29, 34}, .visible = fsStatus == SD_CARD },
|
||||
{ .posXs = {21, 26, 31, 36}, .visible = true },
|
||||
{ .posXs = {12, 22, 31, 0}, .visible = true },
|
||||
{ .posXs = {14, 19, 24, 29}, .visible = true },
|
||||
{ .posXs = {17, 26, 32, 44}, .visible = isN3DS },
|
||||
{ .posXs = {19, 30, 42, 0}, .visible = true }
|
||||
};
|
||||
|
||||
//Calculate the amount of the various kinds of options and pre-select the first single one
|
||||
u32 multiOptionsAmount = sizeof(multiOptions) / sizeof(struct multiOption),
|
||||
singleOptionsAmount = sizeof(singleOptionsText) / sizeof(char *),
|
||||
totalIndexes = multiOptionsAmount + singleOptionsAmount - 1,
|
||||
selectedOption = multiOptionsAmount;
|
||||
|
||||
struct singleOption {
|
||||
u32 posY;
|
||||
bool enabled;
|
||||
} singleOptions[singleOptionsAmount];
|
||||
bool visible;
|
||||
} singleOptions[] = {
|
||||
{ .visible = fsStatus == SD_CARD },
|
||||
{ .visible = fsStatus == SD_CARD },
|
||||
{ .visible = true },
|
||||
{ .visible = fsStatus == SD_CARD },
|
||||
{ .visible = true },
|
||||
{ .visible = true },
|
||||
{ .visible = true },
|
||||
{ .visible = true }
|
||||
};
|
||||
|
||||
//Calculate the amount of the various kinds of options and pre-select the first single one
|
||||
u32 multiOptionsAmount = sizeof(multiOptions) / sizeof(struct multiOption),
|
||||
singleOptionsAmount = sizeof(singleOptions) / sizeof(struct singleOption),
|
||||
totalIndexes = multiOptionsAmount + singleOptionsAmount - 1,
|
||||
selectedOption = multiOptionsAmount;
|
||||
while(!singleOptions[selectedOption - multiOptionsAmount].visible) selectedOption++;
|
||||
|
||||
//Parse the existing options
|
||||
for(u32 i = 0; i < multiOptionsAmount; i++)
|
||||
@ -232,7 +243,7 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
||||
//Display all the multiple choice options in white
|
||||
for(u32 i = 0; i < multiOptionsAmount; i++)
|
||||
{
|
||||
if(!(i == NEWCPU && !isN3DS))
|
||||
if(multiOptions[i].visible)
|
||||
{
|
||||
multiOptions[i].posY = endPos + SPACING_Y;
|
||||
endPos = drawString(multiOptionsText[i], true, 10, multiOptions[i].posY, COLOR_WHITE);
|
||||
@ -246,10 +257,13 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
||||
//Display all the normal options in white except for the first one
|
||||
for(u32 i = 0; i < singleOptionsAmount; i++)
|
||||
{
|
||||
singleOptions[i].posY = endPos + SPACING_Y;
|
||||
endPos = drawString(singleOptionsText[i], true, 10, singleOptions[i].posY, color);
|
||||
if(singleOptions[i].enabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[i].posY, color);
|
||||
color = COLOR_WHITE;
|
||||
if(singleOptions[i].visible)
|
||||
{
|
||||
singleOptions[i].posY = endPos + SPACING_Y;
|
||||
endPos = drawString(singleOptionsText[i], true, 10, singleOptions[i].posY, color);
|
||||
if(singleOptions[i].enabled) drawCharacter(selected, true, 10 + SPACING_X, singleOptions[i].posY, color);
|
||||
color = COLOR_WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
drawString(optionsDescription[selectedOption], false, 10, 10, COLOR_WHITE);
|
||||
@ -270,24 +284,31 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
||||
//Remember the previously selected option
|
||||
u32 oldSelectedOption = selectedOption;
|
||||
|
||||
switch(pressed)
|
||||
while(true)
|
||||
{
|
||||
case BUTTON_UP:
|
||||
if(!selectedOption) selectedOption = totalIndexes;
|
||||
else selectedOption = (selectedOption == NEWCPU + 1 && !isN3DS) ? selectedOption - 2 : selectedOption - 1;
|
||||
break;
|
||||
case BUTTON_DOWN:
|
||||
if(selectedOption == totalIndexes) selectedOption = 0;
|
||||
else selectedOption = (selectedOption == NEWCPU - 1 && !isN3DS) ? selectedOption + 2 : selectedOption + 1;
|
||||
break;
|
||||
case BUTTON_LEFT:
|
||||
selectedOption = 0;
|
||||
break;
|
||||
case BUTTON_RIGHT:
|
||||
selectedOption = totalIndexes;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
switch(pressed)
|
||||
{
|
||||
case BUTTON_UP:
|
||||
selectedOption = !selectedOption ? totalIndexes : selectedOption - 1;
|
||||
break;
|
||||
case BUTTON_DOWN:
|
||||
selectedOption = selectedOption == totalIndexes ? 0 : selectedOption + 1;
|
||||
break;
|
||||
case BUTTON_LEFT:
|
||||
pressed = BUTTON_DOWN;
|
||||
selectedOption = 0;
|
||||
break;
|
||||
case BUTTON_RIGHT:
|
||||
pressed = BUTTON_UP;
|
||||
selectedOption = totalIndexes;
|
||||
break;
|
||||
}
|
||||
|
||||
if(selectedOption < multiOptionsAmount)
|
||||
{
|
||||
if(multiOptions[selectedOption].visible) break;
|
||||
}
|
||||
else if(singleOptions[selectedOption - multiOptionsAmount].visible) break;
|
||||
}
|
||||
|
||||
if(selectedOption == oldSelectedOption) continue;
|
||||
|
@ -28,7 +28,7 @@
|
||||
#define MULTICONFIG(a) ((configData.config >> (a * 2 + 9)) & 3)
|
||||
#define BOOTCONFIG(a, b) ((configData.config >> a) & b)
|
||||
|
||||
#define CONFIG_PATH "/luma/config.bin"
|
||||
#define CONFIG_PATH "luma/config.bin"
|
||||
#define CONFIG_VERSIONMAJOR 1
|
||||
#define CONFIG_VERSIONMINOR 6
|
||||
|
||||
@ -78,6 +78,6 @@ typedef enum ConfigurationStatus
|
||||
extern CfgData configData;
|
||||
extern bool isN3DS;
|
||||
|
||||
bool readConfig(bool isSdMounted);
|
||||
bool readConfig(void);
|
||||
void writeConfig(ConfigurationStatus needConfig, u32 configTemp);
|
||||
void configMenu(bool oldPinStatus, u32 oldPinMode);
|
||||
void configMenu(Fs fsStatus, bool oldPinStatus, u32 oldPinMode);
|
@ -347,6 +347,20 @@ int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
|
||||
return result;
|
||||
}
|
||||
|
||||
int ctrNandWrite(u32 sector, u32 sectorCount, u8 *inbuf)
|
||||
{
|
||||
u8 __attribute__((aligned(4))) tmpCtr[sizeof(nandCtr)];
|
||||
memcpy(tmpCtr, nandCtr, sizeof(nandCtr));
|
||||
aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||
|
||||
//Encrypt
|
||||
aes_use_keyslot(nandSlot);
|
||||
aes(inbuf, inbuf, sectorCount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||
|
||||
//Write
|
||||
return sdmmc_nand_writesectors(sector + fatStart, sectorCount, inbuf);
|
||||
}
|
||||
|
||||
void set6x7xKeys(void)
|
||||
{
|
||||
const u8 __attribute__((aligned(4))) keyX0x25[AES_BLOCK_SIZE] = {0xCE, 0xE7, 0xD8, 0xAB, 0x30, 0xC0, 0x0D, 0xAE, 0x85, 0x0E, 0xF5, 0xE3, 0x82, 0xAC, 0x5A, 0xF3};
|
||||
|
@ -107,6 +107,7 @@ extern FirmwareSource firmSource;
|
||||
|
||||
void ctrNandInit(void);
|
||||
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
|
||||
int ctrNandWrite(u32 sector, u32 sectorCount, u8 *inbuf);
|
||||
void set6x7xKeys(void);
|
||||
void decryptExeFs(u8 *inbuf);
|
||||
void decryptNusFirm(const u8 *inbuf, u8 *outbuf, u32 ncchSize);
|
||||
|
@ -34,8 +34,8 @@
|
||||
|
||||
bool loadSplash(void)
|
||||
{
|
||||
const char topSplashPath[] = "/luma/splash.bin",
|
||||
bottomSplashPath[] = "/luma/splashbottom.bin";
|
||||
const char topSplashPath[] = "luma/splash.bin",
|
||||
bottomSplashPath[] = "luma/splashbottom.bin";
|
||||
|
||||
bool isTopSplashValid = getFileSize(topSplashPath) == SCREEN_TOP_FBSIZE,
|
||||
isBottomSplashValid = getFileSize(bottomSplashPath) == SCREEN_BOTTOM_FBSIZE;
|
||||
|
@ -172,9 +172,9 @@ void detectAndProcessExceptionDumps(void)
|
||||
}
|
||||
}
|
||||
|
||||
char path[42];
|
||||
char path[41];
|
||||
char fileName[] = "crash_dump_00000000.dmp";
|
||||
const char *pathFolder = dumpHeader->processor == 9 ? "/luma/dumps/arm9" : "/luma/dumps/arm11";
|
||||
const char *pathFolder = dumpHeader->processor == 9 ? "luma/dumps/arm9" : "luma/dumps/arm11";
|
||||
|
||||
findDumpFile(pathFolder, fileName);
|
||||
memcpy(path, pathFolder, strlen(pathFolder) + 1);
|
||||
|
@ -87,7 +87,8 @@ DRESULT disk_write (
|
||||
UINT count /* Number of sectors to write */
|
||||
)
|
||||
{
|
||||
return (pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ? RES_OK : RES_PARERR;
|
||||
return ((pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ||
|
||||
(pdrv == CTRNAND && !ctrNandWrite(sector, count, (BYTE *)buff))) ? RES_OK : RES_PARERR;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -134,7 +134,7 @@
|
||||
/ This option has no effect when _LFN_UNICODE == 0. */
|
||||
|
||||
|
||||
#define _FS_RPATH 0
|
||||
#define _FS_RPATH 1
|
||||
/* This option configures support of relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
|
@ -244,7 +244,6 @@ int __attribute__((noinline)) sdmmc_nand_readsectors(u32 sector_no, u32 numsecto
|
||||
return geterror(&handleNAND);
|
||||
}
|
||||
|
||||
/*
|
||||
int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in) //experimental
|
||||
{
|
||||
if(handleNAND.isSDHC == 0) sector_no <<= 9;
|
||||
@ -259,7 +258,6 @@ int __attribute__((noinline)) sdmmc_nand_writesectors(u32 sector_no, u32 numsect
|
||||
inittarget(&handleSD);
|
||||
return geterror(&handleNAND);
|
||||
}
|
||||
*/
|
||||
|
||||
static u32 calcSDSize(u8 *csd, int type)
|
||||
{
|
||||
|
@ -95,6 +95,6 @@ u32 sdmmc_sdcard_init();
|
||||
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
||||
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
||||
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);
|
||||
//int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
||||
int sdmmc_nand_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
|
||||
void sdmmc_get_cid(bool isNand, u32 *info);
|
||||
mmcdevice *getMMCDevice(int drive);
|
@ -64,11 +64,17 @@ void main(void)
|
||||
//Detect dev units
|
||||
isDevUnit = CFG_UNITINFO != 0;
|
||||
|
||||
//Mount SD
|
||||
bool isSdMounted = mountFs(true);
|
||||
//Mount SD or CTRNAND
|
||||
Fs fsStatus;
|
||||
if(mountFs(true)) fsStatus = SD_CARD;
|
||||
else
|
||||
{
|
||||
firmSource = FIRMWARE_SYSNAND;
|
||||
fsStatus = (mountFs(false) && switchToCtrNand()) ? CTRNAND : NONE;
|
||||
}
|
||||
|
||||
//Attempt to read the configuration file
|
||||
needConfig = readConfig(isSdMounted) ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
|
||||
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
|
||||
|
||||
u32 devMode = MULTICONFIG(DEVOPTIONS);
|
||||
|
||||
@ -94,6 +100,8 @@ void main(void)
|
||||
//Determine if booting with A9LH
|
||||
isA9lh = !PDN_SPI_CNT;
|
||||
|
||||
if(fsStatus == NONE) error("Error mounting SD and CTRNAND.");
|
||||
|
||||
if(devMode != 0 && isA9lh) detectAndProcessExceptionDumps();
|
||||
|
||||
//Get pressed buttons
|
||||
@ -102,15 +110,8 @@ void main(void)
|
||||
//Save old options and begin saving the new boot configuration
|
||||
configTemp = (configData.config & 0xFFFFFE00) | ((u32)isA9lh << 6);
|
||||
|
||||
if(!isSdMounted)
|
||||
{
|
||||
nandType = FIRMWARE_SYSNAND;
|
||||
firmSource = FIRMWARE_SYSNAND;
|
||||
needConfig = DONT_CONFIGURE;
|
||||
}
|
||||
|
||||
//If it's a MCU reboot, try to force boot options
|
||||
else if(isA9lh && CFG_BOOTENV)
|
||||
if(isA9lh && CFG_BOOTENV)
|
||||
{
|
||||
//Always force a sysNAND boot when quitting AGB_FIRM
|
||||
if(CFG_BOOTENV == 7)
|
||||
@ -149,7 +150,7 @@ void main(void)
|
||||
|
||||
if(shouldLoadConfigMenu)
|
||||
{
|
||||
configMenu(pinExists, pinMode);
|
||||
configMenu(fsStatus, pinExists, pinMode);
|
||||
|
||||
//Update pressed buttons
|
||||
pressed = HID_PAD;
|
||||
@ -189,12 +190,14 @@ void main(void)
|
||||
|
||||
if(splashMode == 2) loadSplash();
|
||||
|
||||
//Determine if the user chose to use the SysNAND FIRM as default for a R boot
|
||||
bool useSysAsDefault = isA9lh ? CONFIG(USESYSFIRM) : false;
|
||||
if(fsStatus == CTRNAND) nandType = FIRMWARE_SYSNAND;
|
||||
|
||||
//If R is pressed, boot the non-updated NAND with the FIRM of the opposite one
|
||||
if(pressed & BUTTON_R1)
|
||||
else if(pressed & BUTTON_R1)
|
||||
{
|
||||
//Determine if the user chose to use the SysNAND FIRM as default for a R boot
|
||||
bool useSysAsDefault = isA9lh ? CONFIG(USESYSFIRM) : false;
|
||||
|
||||
nandType = useSysAsDefault ? FIRMWARE_EMUNAND : FIRMWARE_SYSNAND;
|
||||
firmSource = useSysAsDefault ? FIRMWARE_SYSNAND : FIRMWARE_EMUNAND;
|
||||
}
|
||||
@ -248,14 +251,14 @@ void main(void)
|
||||
else if(firmSource != FIRMWARE_SYSNAND)
|
||||
locateEmuNand(&emuHeader, &firmSource);
|
||||
|
||||
if(isSdMounted && !isFirmlaunch)
|
||||
if(!isFirmlaunch)
|
||||
{
|
||||
configTemp |= (u32)nandType | ((u32)firmSource << 3);
|
||||
writeConfig(needConfig, configTemp);
|
||||
}
|
||||
|
||||
bool loadFromSd = CONFIG(LOADSDFIRMSANDMODULES);
|
||||
u32 firmVersion = loadFirm(&firmType, firmSource, loadFromSd, isSdMounted);
|
||||
u32 firmVersion = loadFirm(&firmType, firmSource, loadFromSd, fsStatus);
|
||||
|
||||
switch(firmType)
|
||||
{
|
||||
@ -274,24 +277,24 @@ void main(void)
|
||||
launchFirm(firmType, loadFromSd);
|
||||
}
|
||||
|
||||
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, bool isSdMounted)
|
||||
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, Fs fsStatus)
|
||||
{
|
||||
section = firm->section;
|
||||
|
||||
const char *firmwareFiles[] = {
|
||||
"/luma/firmware.bin",
|
||||
"/luma/firmware_twl.bin",
|
||||
"/luma/firmware_agb.bin",
|
||||
"/luma/firmware_safe.bin"
|
||||
"luma/firmware.bin",
|
||||
"luma/firmware_twl.bin",
|
||||
"luma/firmware_agb.bin",
|
||||
"luma/firmware_safe.bin"
|
||||
},
|
||||
*cetkFiles[] = {
|
||||
"/luma/cetk",
|
||||
"/luma/cetk_twl",
|
||||
"/luma/cetk_agb",
|
||||
"/luma/cetk_safe"
|
||||
"luma/cetk",
|
||||
"luma/cetk_twl",
|
||||
"luma/cetk_agb",
|
||||
"luma/cetk_safe"
|
||||
};
|
||||
|
||||
if(!mountFs(false)) error("Error mounting CTRNAND.");
|
||||
if(fsStatus == SD_CARD && !mountFs(false)) error("Error mounting CTRNAND.");
|
||||
|
||||
//Load FIRM from CTRNAND
|
||||
u32 firmVersion = firmRead(firm, (u32)*firmType);
|
||||
@ -308,7 +311,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
|
||||
if(firmSource != FIRMWARE_SYSNAND)
|
||||
error("An old unsupported EmuNAND has been detected.\nLuma3DS is unable to boot it.");
|
||||
|
||||
if(HID_PAD == SAFE_MODE) error("SAFE_MODE is not supported on 1.x/2.x FIRM.");
|
||||
if(BOOTCFG_SAFEMODE != 0) error("SAFE_MODE is not supported on 1.x/2.x FIRM.");
|
||||
|
||||
*firmType = NATIVE_FIRM1X2X;
|
||||
}
|
||||
@ -317,7 +320,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
|
||||
else if(firmVersion < 0x25) mustLoadFromSd = true;
|
||||
}
|
||||
|
||||
if(isSdMounted && (loadFromSd || mustLoadFromSd))
|
||||
if(loadFromSd || mustLoadFromSd)
|
||||
{
|
||||
u32 firmSize = fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType], 0x400000);
|
||||
|
||||
@ -329,12 +332,12 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
|
||||
|
||||
if(fileRead(cetk, *firmType == NATIVE_FIRM1X2X ? cetkFiles[0] : cetkFiles[(u32)*firmType], sizeof(cetk)) == sizeof(cetk))
|
||||
decryptNusFirm(cetk, (u8 *)firm, firmSize);
|
||||
else error("The firmware.bin in /luma is encrypted\nor corrupted.");
|
||||
else error("The firmware.bin in luma is encrypted\nor corrupted.");
|
||||
}
|
||||
|
||||
//Check that the SD FIRM is right for the console from the ARM9 section address
|
||||
if((section[3].offset ? section[3].address : section[2].address) != (isN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))
|
||||
error("The firmware.bin in /luma is not valid for this\nconsole.");
|
||||
error("The firmware.bin in luma is not valid for this\nconsole.");
|
||||
|
||||
firmVersion = 0xFFFFFFFF;
|
||||
}
|
||||
@ -342,7 +345,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bo
|
||||
|
||||
if(firmVersion != 0xFFFFFFFF)
|
||||
{
|
||||
if(mustLoadFromSd) error("An old unsupported FIRM has been detected.\nCopy a firmware.bin in /luma to boot.");
|
||||
if(mustLoadFromSd) error("An old unsupported FIRM has been detected.\nCopy a firmware.bin in luma to boot.");
|
||||
decryptExeFs((u8 *)firm);
|
||||
}
|
||||
|
||||
@ -485,7 +488,7 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType, boo
|
||||
|
||||
if(loadFromSd)
|
||||
{
|
||||
char fileName[30] = "/luma/sysmodules/";
|
||||
char fileName[30] = "luma/sysmodules/";
|
||||
const char *ext = ".cxi";
|
||||
|
||||
//Read modules from files if they exist
|
||||
|
@ -47,7 +47,7 @@ typedef struct firmHeader {
|
||||
firmSectionHeader section[4];
|
||||
} firmHeader;
|
||||
|
||||
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, bool isSdMounted);
|
||||
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd, Fs fsStatus);
|
||||
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, u32 devMode);
|
||||
static inline void patchLegacyFirm(FirmwareType firmType, u32 firmVersion, u32 devMode);
|
||||
static inline void patch1x2xNativeAndSafeFirm(u32 devMode);
|
||||
|
12
source/fs.c
12
source/fs.c
@ -38,6 +38,11 @@ bool mountFs(bool isSd)
|
||||
return isSd ? f_mount(&sdFs, "0:", 1) == FR_OK : f_mount(&nandFs, "1:", 1) == FR_OK;
|
||||
}
|
||||
|
||||
bool switchToCtrNand(void)
|
||||
{
|
||||
return f_chdrive("1:") == FR_OK && f_chdir("/rw") == FR_OK;
|
||||
}
|
||||
|
||||
u32 fileRead(void *dest, const char *path, u32 maxSize)
|
||||
{
|
||||
FIL file;
|
||||
@ -84,11 +89,10 @@ bool fileWrite(const void *buffer, const char *path, u32 size)
|
||||
char folder[i + 1];
|
||||
memcpy(folder, path, i);
|
||||
folder[i] = 0;
|
||||
ret = f_mkdir(folder) == FR_OK;
|
||||
if(!ret) break;
|
||||
f_mkdir(folder);
|
||||
}
|
||||
|
||||
if(ret) ret = fileWrite(buffer, path, size);
|
||||
ret = fileWrite(buffer, path, size);
|
||||
}
|
||||
else ret = false;
|
||||
|
||||
@ -118,7 +122,7 @@ void loadPayload(u32 pressed)
|
||||
|
||||
DIR dir;
|
||||
FILINFO info;
|
||||
char path[28] = "/luma/payloads";
|
||||
char path[27] = "luma/payloads";
|
||||
|
||||
FRESULT result = f_findfirst(&dir, &info, path, pattern);
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
extern bool isN3DS, isA9lh;
|
||||
|
||||
bool mountFs(bool isSd);
|
||||
bool switchToCtrNand(void);
|
||||
u32 fileRead(void *dest, const char *path, u32 maxSize);
|
||||
u32 getFileSize(const char *path);
|
||||
bool fileWrite(const void *buffer, const char *path, u32 size);
|
||||
|
@ -93,7 +93,7 @@ void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
|
||||
|
||||
if(CONFIG(USECUSTOMPATH))
|
||||
{
|
||||
const char pathPath[] = "/luma/path.txt";
|
||||
const char pathPath[] = "luma/path.txt";
|
||||
|
||||
u32 pathSize = getFileSize(pathPath);
|
||||
|
||||
|
@ -132,7 +132,7 @@ bool verifyPin(u32 pinMode)
|
||||
u8 cnt = 0;
|
||||
u32 charDrawPos = 16 * SPACING_X;
|
||||
|
||||
const char messagePath[] = "/luma/pinmessage.txt";
|
||||
const char messagePath[] = "luma/pinmessage.txt";
|
||||
|
||||
u32 messageSize = getFileSize(messagePath);
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define PIN_PATH "/luma/pin.bin"
|
||||
#define PIN_PATH "luma/pin.bin"
|
||||
#define PIN_VERSIONMAJOR 1
|
||||
#define PIN_VERSIONMINOR 3
|
||||
|
||||
|
@ -55,4 +55,11 @@ typedef enum FirmwareType
|
||||
AGB_FIRM,
|
||||
SAFE_FIRM,
|
||||
NATIVE_FIRM1X2X
|
||||
} FirmwareType;
|
||||
} FirmwareType;
|
||||
|
||||
typedef enum Fs
|
||||
{
|
||||
SD_CARD = 0,
|
||||
CTRNAND,
|
||||
NONE
|
||||
} Fs;
|
Reference in New Issue
Block a user