Allow chainloading larger FIRMs via FCRAM

This commit is contained in:
d0k3 2017-09-27 01:32:26 +02:00
parent 2e0125cd37
commit a90379f2c1
5 changed files with 22 additions and 15 deletions

View File

@ -88,7 +88,8 @@
// -> codelzss.c for decompressing .code
// meaning: careful when using this!
#define TEMP_BUFFER ((u8*)0x20800000)
#define TEMP_BUFFER_SIZE (0x1800000) // 24MB(!)
#define TEMP_BUFFER_SIZE (0x400000) // 4MB
#define TEMP_BUFFER_EXTSIZE (0x1800000) // 24MB(!) (only used by codelzss.c right now)
// buffer area defines (in use by image.c, for RAMdrive)
#define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK

View File

@ -26,10 +26,10 @@
FIRM_VALID_ADDRESS, \
0x20000000, 0x27FFFA00
u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
u32 GetFirmSize(FirmHeader* header) {
u8 magic[] = { FIRM_MAGIC };
if (memcmp(header->magic, magic, sizeof(magic)) != 0)
return 1;
return 0;
u32 firm_size = sizeof(FirmHeader);
int section_arm11 = -1;
@ -37,8 +37,8 @@ u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
for (u32 i = 0; i < 4; i++) {
FirmSectionHeader* section = header->sections + i;
if (!section->size) continue;
if (section->offset < firm_size) return 1;
if ((section->offset % 512) || (section->address % 16) || (section->size % 512)) return 1;
if (section->offset < firm_size) return 0;
if ((section->offset % 512) || (section->address % 16) || (section->size % 512)) return 0;
if ((header->entry_arm11 >= section->address) &&
(header->entry_arm11 < section->address + section->size))
section_arm11 = i;
@ -48,12 +48,16 @@ u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
firm_size = section->offset + section->size;
}
if ((firm_size > FIRM_MAX_SIZE) || (data_size && (firm_size > data_size)))
return 1;
if (firm_size > FIRM_MAX_SIZE) return 0;
if ((header->entry_arm11 && (section_arm11 < 0)) || (header->entry_arm9 && (section_arm9 < 0)))
return 1;
return 0;
return firm_size;
}
u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
u32 firm_size = GetFirmSize(header);
return (!firm_size || (data_size && (firm_size > data_size))) ? 1 : 0;
}
u32 ValidateFirmA9LHeader(FirmA9LHeader* header) {

View File

@ -48,6 +48,7 @@ typedef struct {
u32 ValidateFirmHeader(FirmHeader* header, u32 data_size);
u32 ValidateFirmA9LHeader(FirmA9LHeader* header);
u32 ValidateFirm(void* firm, u32 firm_size, bool installable);
u32 GetFirmSize(FirmHeader* header);
FirmSectionHeader* FindFirmArm9Section(FirmHeader* firm);
u32 GetArm9BinarySize(FirmA9LHeader* a9l);

View File

@ -1641,13 +1641,14 @@ u32 GodMode(bool is_b9s) {
bool bootloader = !is_b9s && IS_SIGHAX && (boot_origin & BOOT_NAND);
bool bootmenu = bootloader && CheckButton(BOOTMENU_KEY);
bool godmode9 = !bootloader;
FirmHeader* firm_in_mem = (FirmHeader*) DIR_BUFFER;
FirmHeader* firm_in_mem = (FirmHeader*) (void*) (TEMP_BUFFER + TEMP_BUFFER_SIZE); // should be safe here
memcpy(firm_in_mem, "NOPE", 4); // to prevent bootloops
if (bootloader) { // check for FIRM in FCRAM, but prevent bootloops
for (u8* addr = (u8*) 0x20000200; addr < (u8*) 0x24000000; addr += 0x400000) {
if (memcmp(addr - 0x200, "A9NC", 4) != 0) continue;
if (ValidateFirmHeader((FirmHeader*) (void*) addr, 0x100000) != 0) continue;
if (memcmp(firm_in_mem, "FIRM", 4) != 0) memmove(firm_in_mem, addr, 0x100000);
u32 firm_size = GetFirmSize((FirmHeader*) (void*) addr);
if (!firm_size || (firm_size > (0x400000 - 0x200))) continue;
if (memcmp(firm_in_mem, "FIRM", 4) != 0) memmove(firm_in_mem, addr, firm_size);
if (memcmp(addr, "FIRM", 4) == 0) memcpy(addr, "NOPE", 4); // prevent bootloops
}
}
@ -1735,7 +1736,7 @@ u32 GodMode(bool is_b9s) {
}
if (bootloader) {
const char* bootfirm_paths[] = { BOOTFIRM_PATHS };
if (ValidateFirm(firm_in_mem, 0x100000, false) == 0) BootFirm(firm_in_mem, "0:/bootonce.firm");
if (ValidateFirm(firm_in_mem, FIRM_MAX_SIZE, false) == 0) BootFirm(firm_in_mem, "0:/bootonce.firm");
for (u32 i = 0; i < sizeof(bootfirm_paths) / sizeof(char*); i++) {
BootFirmHandler(bootfirm_paths[i], false, (BOOTFIRM_TEMPS >> i) & 0x1);
}

View File

@ -1413,7 +1413,7 @@ u32 DumpCxiSrlFromTmdFile(const char* path) {
u32 ExtractCodeFromCxiFile(const char* path, const char* path_out) {
u8* code = (u8*) TEMP_BUFFER;
u32 code_max_size = TEMP_BUFFER_SIZE;
u32 code_max_size = TEMP_BUFFER_EXTSIZE; // uses the extended temp buffer size
NcchHeader ncch;
NcchExtHeader exthdr;