mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Allow chainloading larger FIRMs via FCRAM
This commit is contained in:
parent
2e0125cd37
commit
a90379f2c1
@ -88,7 +88,8 @@
|
|||||||
// -> codelzss.c for decompressing .code
|
// -> codelzss.c for decompressing .code
|
||||||
// meaning: careful when using this!
|
// meaning: careful when using this!
|
||||||
#define TEMP_BUFFER ((u8*)0x20800000)
|
#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)
|
// buffer area defines (in use by image.c, for RAMdrive)
|
||||||
#define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK
|
#define RAMDRV_BUFFER ((u8*)0x22800000) // top of STACK
|
||||||
|
@ -25,11 +25,11 @@
|
|||||||
#define FIRM_VALID_ADDRESS_BOOT \
|
#define FIRM_VALID_ADDRESS_BOOT \
|
||||||
FIRM_VALID_ADDRESS, \
|
FIRM_VALID_ADDRESS, \
|
||||||
0x20000000, 0x27FFFA00
|
0x20000000, 0x27FFFA00
|
||||||
|
|
||||||
u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
|
u32 GetFirmSize(FirmHeader* header) {
|
||||||
u8 magic[] = { FIRM_MAGIC };
|
u8 magic[] = { FIRM_MAGIC };
|
||||||
if (memcmp(header->magic, magic, sizeof(magic)) != 0)
|
if (memcmp(header->magic, magic, sizeof(magic)) != 0)
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
u32 firm_size = sizeof(FirmHeader);
|
u32 firm_size = sizeof(FirmHeader);
|
||||||
int section_arm11 = -1;
|
int section_arm11 = -1;
|
||||||
@ -37,8 +37,8 @@ u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
|
|||||||
for (u32 i = 0; i < 4; i++) {
|
for (u32 i = 0; i < 4; i++) {
|
||||||
FirmSectionHeader* section = header->sections + i;
|
FirmSectionHeader* section = header->sections + i;
|
||||||
if (!section->size) continue;
|
if (!section->size) continue;
|
||||||
if (section->offset < firm_size) return 1;
|
if (section->offset < firm_size) return 0;
|
||||||
if ((section->offset % 512) || (section->address % 16) || (section->size % 512)) return 1;
|
if ((section->offset % 512) || (section->address % 16) || (section->size % 512)) return 0;
|
||||||
if ((header->entry_arm11 >= section->address) &&
|
if ((header->entry_arm11 >= section->address) &&
|
||||||
(header->entry_arm11 < section->address + section->size))
|
(header->entry_arm11 < section->address + section->size))
|
||||||
section_arm11 = i;
|
section_arm11 = i;
|
||||||
@ -48,12 +48,16 @@ u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
|
|||||||
firm_size = section->offset + section->size;
|
firm_size = section->offset + section->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((firm_size > FIRM_MAX_SIZE) || (data_size && (firm_size > data_size)))
|
if (firm_size > FIRM_MAX_SIZE) return 0;
|
||||||
return 1;
|
|
||||||
if ((header->entry_arm11 && (section_arm11 < 0)) || (header->entry_arm9 && (section_arm9 < 0)))
|
if ((header->entry_arm11 && (section_arm11 < 0)) || (header->entry_arm9 && (section_arm9 < 0)))
|
||||||
return 1;
|
return 0;
|
||||||
|
|
||||||
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) {
|
u32 ValidateFirmA9LHeader(FirmA9LHeader* header) {
|
||||||
|
@ -48,6 +48,7 @@ typedef struct {
|
|||||||
u32 ValidateFirmHeader(FirmHeader* header, u32 data_size);
|
u32 ValidateFirmHeader(FirmHeader* header, u32 data_size);
|
||||||
u32 ValidateFirmA9LHeader(FirmA9LHeader* header);
|
u32 ValidateFirmA9LHeader(FirmA9LHeader* header);
|
||||||
u32 ValidateFirm(void* firm, u32 firm_size, bool installable);
|
u32 ValidateFirm(void* firm, u32 firm_size, bool installable);
|
||||||
|
u32 GetFirmSize(FirmHeader* header);
|
||||||
|
|
||||||
FirmSectionHeader* FindFirmArm9Section(FirmHeader* firm);
|
FirmSectionHeader* FindFirmArm9Section(FirmHeader* firm);
|
||||||
u32 GetArm9BinarySize(FirmA9LHeader* a9l);
|
u32 GetArm9BinarySize(FirmA9LHeader* a9l);
|
||||||
|
@ -1641,13 +1641,14 @@ u32 GodMode(bool is_b9s) {
|
|||||||
bool bootloader = !is_b9s && IS_SIGHAX && (boot_origin & BOOT_NAND);
|
bool bootloader = !is_b9s && IS_SIGHAX && (boot_origin & BOOT_NAND);
|
||||||
bool bootmenu = bootloader && CheckButton(BOOTMENU_KEY);
|
bool bootmenu = bootloader && CheckButton(BOOTMENU_KEY);
|
||||||
bool godmode9 = !bootloader;
|
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
|
memcpy(firm_in_mem, "NOPE", 4); // to prevent bootloops
|
||||||
if (bootloader) { // check for FIRM in FCRAM, but prevent bootloops
|
if (bootloader) { // check for FIRM in FCRAM, but prevent bootloops
|
||||||
for (u8* addr = (u8*) 0x20000200; addr < (u8*) 0x24000000; addr += 0x400000) {
|
for (u8* addr = (u8*) 0x20000200; addr < (u8*) 0x24000000; addr += 0x400000) {
|
||||||
if (memcmp(addr - 0x200, "A9NC", 4) != 0) continue;
|
if (memcmp(addr - 0x200, "A9NC", 4) != 0) continue;
|
||||||
if (ValidateFirmHeader((FirmHeader*) (void*) addr, 0x100000) != 0) continue;
|
u32 firm_size = GetFirmSize((FirmHeader*) (void*) addr);
|
||||||
if (memcmp(firm_in_mem, "FIRM", 4) != 0) memmove(firm_in_mem, addr, 0x100000);
|
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
|
if (memcmp(addr, "FIRM", 4) == 0) memcpy(addr, "NOPE", 4); // prevent bootloops
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1735,7 +1736,7 @@ u32 GodMode(bool is_b9s) {
|
|||||||
}
|
}
|
||||||
if (bootloader) {
|
if (bootloader) {
|
||||||
const char* bootfirm_paths[] = { BOOTFIRM_PATHS };
|
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++) {
|
for (u32 i = 0; i < sizeof(bootfirm_paths) / sizeof(char*); i++) {
|
||||||
BootFirmHandler(bootfirm_paths[i], false, (BOOTFIRM_TEMPS >> i) & 0x1);
|
BootFirmHandler(bootfirm_paths[i], false, (BOOTFIRM_TEMPS >> i) & 0x1);
|
||||||
}
|
}
|
||||||
|
@ -1413,7 +1413,7 @@ u32 DumpCxiSrlFromTmdFile(const char* path) {
|
|||||||
|
|
||||||
u32 ExtractCodeFromCxiFile(const char* path, const char* path_out) {
|
u32 ExtractCodeFromCxiFile(const char* path, const char* path_out) {
|
||||||
u8* code = (u8*) TEMP_BUFFER;
|
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;
|
NcchHeader ncch;
|
||||||
NcchExtHeader exthdr;
|
NcchExtHeader exthdr;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user