Added dual emuNAND support, multi-payload loader with built-in screen init (inspired by arm9select, thanks Fix94)

This commit is contained in:
Aurora
2016-03-17 00:08:13 +01:00
parent 8ce395caa5
commit dcb09a9472
14 changed files with 400 additions and 33 deletions

View File

@@ -26,7 +26,7 @@ void __attribute__((naked)) shutdownLCD(void){
*(vu32 *)0x10202244 = 0;
*(vu32 *)0x10202014 = 0;
//Wait for the ARM11 entrypoint to be set
//Wait for the entry to be set
while(!*arm11);
//Jump to it
((void (*)())*arm11)();

View File

@@ -8,15 +8,20 @@
#include "memory.h"
#include "fatfs/sdmmc/sdmmc.h"
void getEmunandSect(u32 *off, u32 *head){
void getEmunandSect(u32 *off, u32 *head, u32 emuNAND){
u8 *const temp = (u8 *)0x24300000;
u32 nandSize = getMMCDevice(0)->total_size;
if(sdmmc_sdcard_readsectors(nandSize, 1, temp) == 0){
u32 nandOffset = emuNAND == 1 ? 0 :
(nandSize > 0x200000 ? 0x400000 : 0x200000);
if(sdmmc_sdcard_readsectors(nandOffset + nandSize, 1, temp) == 0){
if(*(u32 *)(temp + 0x100) == NCSD_MAGIC){
*off = 0;
*head = nandSize;
*off = nandOffset;
*head = nandOffset + nandSize;
}
//Fallback to the first emuNAND if there's no second one
else if(emuNAND == 2) getEmunandSect(off, head, 1);
}
}

View File

@@ -10,7 +10,7 @@
#define NCSD_MAGIC (0x4453434E)
void getEmunandSect(u32 *off, u32 *head);
void getEmunandSect(u32 *off, u32 *head, u32 emuNAND);
void getSDMMC(void *pos, u32 *off, u32 size);
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff);
void getMPU(void *pos, u32 *off, u32 size);

View File

@@ -53,11 +53,11 @@ void setupCFW(void){
fileRead(&tempConfig, lastConfigPath, 1);
//Always force a sysNAND boot when quitting AGB_FIRM
if(previousFirm == 0x7) {
if(previousFirm == 0x7){
if(!updatedSys) mode = tempConfig & 0x1;
overrideConfig = 1;
//Else, force the last used boot options unless A is pressed
} else if(!(pressed & BUTTON_A)) {
} else if(!(pressed & BUTTON_A)){
mode = tempConfig & 0x1;
emuNAND = (tempConfig >> 1) & 0x1;
overrideConfig = 1;
@@ -79,7 +79,11 @@ void setupCFW(void){
/* If L or R aren't pressed on a 9.0/9.2 SysNAND, or the 9.0 FIRM is selected
or R is pressed on a > 9.2 SysNAND, boot emuNAND */
if((updatedSys && (!mode || ((pressed & BUTTON_R1) && pressed != SAFEMODE))) ||
(!updatedSys && mode && !(pressed & BUTTON_R1))) emuNAND = 1;
(!updatedSys && mode && !(pressed & BUTTON_R1))){
//If not 9.0 FIRM and B is pressed, attempt booting the second emuNAND
if(mode && (pressed & BUTTON_B)) emuNAND = 2;
else emuNAND = 1;
}
//Write the current boot options on A9LH
if(a9lhBoot){
@@ -88,8 +92,9 @@ void setupCFW(void){
}
}
if(mode) firmPathPatched = emuNAND ? "/rei/patched_firmware_emu.bin" :
"/rei/patched_firmware_sys.bin";
if(mode) firmPathPatched = emuNAND ? (emuNAND == 1 ? "/rei/patched_firmware_emu.bin" :
"/rei/patched_firmware_em2.bin") :
"/rei/patched_firmware_sys.bin";
//Skip decrypting and patching FIRM
if(fileExists("/rei/usepatchedfw")){
@@ -156,7 +161,7 @@ static u32 loadEmu(void){
u32 *pos_offset = (u32 *)memsearch((void *)emuCodeOffset, "NAND", size, 4);
u32 *pos_header = (u32 *)memsearch((void *)emuCodeOffset, "NCSD", size, 4);
getSDMMC(firmLocation, &sdmmcOffset, firmSize);
getEmunandSect(&emuOffset, &emuHeader);
getEmunandSect(&emuOffset, &emuHeader, emuNAND);
getEmuRW(firmLocation, firmSize, &emuRead, &emuWrite);
getMPU(firmLocation, &mpuOffset, firmSize);
*pos_sdmmc = sdmmcOffset;
@@ -228,7 +233,8 @@ u32 patchFirm(void){
//Patch path for emuNAND-patched FIRM
if(emuNAND){
void *pos_path = memsearch((void *)rebootOffset, L"sy", size, 4);
memcpy(pos_path, L"emu", 5);
const wchar_t *path = emuNAND == 1 ? L"emu" : L"em2";
memcpy(pos_path, path, 5);
}
}

View File

@@ -17,6 +17,7 @@
#define BUTTON_L1 (1 << 9)
#define BUTTON_L1R1 (BUTTON_R1 | BUTTON_L1)
#define BUTTON_A 1
#define BUTTON_B (1 << 1)
#define SAFEMODE (BUTTON_L1R1 | BUTTON_A | (1 << 6))
//FIRM Header layout

View File

@@ -8,7 +8,7 @@
#define PAYLOAD_ADDRESS 0x24F00000
void loadPayload(void){
if(fileExists("rei/arm9payload.bin") &&
if(fileExists("rei/payloads/default.bin") &&
fileRead((u8 *)PAYLOAD_ADDRESS, "rei/loader.bin", 0))
((void (*)())PAYLOAD_ADDRESS)();
}