From 0eb87df84f2e3877a247596549b8a81599f94594 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Mon, 27 Jun 2016 13:21:08 +0200 Subject: [PATCH] Enable support for reading FIRM system modules from SD card (in /luma/sysmodules) --- source/firm.c | 69 +++++++++++++++++++++++++++++++++++++++++------- source/firm.h | 2 +- source/fs.c | 6 +++++ source/fs.h | 1 + source/patches.c | 17 ------------ source/patches.h | 1 - 6 files changed, 68 insertions(+), 28 deletions(-) diff --git a/source/firm.c b/source/firm.c index f0e73b9..6ec8589 100755 --- a/source/firm.c +++ b/source/firm.c @@ -378,6 +378,7 @@ static inline void patchSafeFirm(void) patchFirmWrites(arm9Section, section[2].size); } + else patchFirmWriteSafe(arm9Section, section[2].size); if(DEVMODE) { @@ -385,20 +386,70 @@ static inline void patchSafeFirm(void) patchExceptionHandlersInstall(arm9Section, section[2].size); patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address)); } - - else patchFirmWriteSafe(arm9Section, section[2].size); } -static inline void copySection0AndInjectLoader(void) +static inline void copySection0AndInjectSystemModules(void) { u8 *arm11Section0 = (u8 *)firm + section[0].offset; + char fileName[] = "/luma/sysmodules/--------.cxi"; + const char *ext = ".cxi"; - u32 loaderSize; - u32 loaderOffset = getLoader(arm11Section0, &loaderSize); + struct + { + u32 size; + char name[8]; + const u8 *addr; + } modules[5] = {{0}}; - memcpy(section[0].address, arm11Section0, loaderOffset); - memcpy(section[0].address + loaderOffset, injector, injector_size); - memcpy(section[0].address + loaderOffset + injector_size, arm11Section0 + loaderOffset + loaderSize, section[0].size - (loaderOffset + loaderSize)); + u8 *pos = arm11Section0; + u32 loaderIndex = 0; + for(u32 i = 0; i < 5; i++) + { + modules[i].addr = pos; + modules[i].size = *(u32 *)(pos + 0x104) * 0x200; + + memcpy(modules[i].name, pos + 0x200, 8); + pos += modules[i].size; + + //Read modules from files if they exist + u32 nameOff; + for(nameOff = 0; nameOff < 8 && modules[i].name[nameOff] != 0; nameOff++); + memcpy(fileName + 17, modules[i].name, nameOff); + memcpy(fileName + 17 + nameOff, ext, 5); + + u32 fileSize = getFileSize(fileName); + if(fileSize != 0) + { + modules[i].addr = NULL; + modules[i].size = fileSize; + } + + if(memcmp(modules[i].name, "loader", 7) == 0) loaderIndex = i; + } + + if(modules[loaderIndex].addr != NULL) + { + modules[loaderIndex].size = injector_size; + modules[loaderIndex].addr = injector; + } + + pos = section[0].address; + for(u32 i = 0; i < 5; i++) + { + if(modules[i].addr != NULL) + memcpy(pos, modules[i].addr, modules[i].size); + else + { + //Read modules from files if they exist + u32 nameOff; + for(nameOff = 0; nameOff < 8 && modules[i].name[nameOff] != 0; nameOff++); + memcpy(fileName + 17, modules[i].name, nameOff); + memcpy(fileName + 17 + nameOff, ext, 5); + fileRead(pos, fileName); + } + + pos += modules[i].size; + } } static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch) @@ -407,7 +458,7 @@ static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch) u32 sectionNum; if(firmType == NATIVE_FIRM) { - copySection0AndInjectLoader(); + copySection0AndInjectSystemModules(); sectionNum = 1; } else sectionNum = 0; diff --git a/source/firm.h b/source/firm.h index 31eeffc..cd3b6e5 100644 --- a/source/firm.h +++ b/source/firm.h @@ -46,5 +46,5 @@ static inline void loadFirm(FirmwareType firmType, u32 externalFirm); static inline void patchNativeFirm(FirmwareSource nandType, u32 emuHeader, A9LHMode a9lhMode); static inline void patchLegacyFirm(FirmwareType firmType); static inline void patchSafeFirm(void); -static inline void copySection0AndInjectLoader(void); +static inline void copySection0AndInjectSystemModules(void); static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch); \ No newline at end of file diff --git a/source/fs.c b/source/fs.c index d39e3ca..a8c264b 100644 --- a/source/fs.c +++ b/source/fs.c @@ -30,6 +30,7 @@ u32 fileRead(void *dest, const char *path) { unsigned int read; size = f_size(&file); + if(dest == NULL) return size; f_read(&file, dest, size, &read); f_close(&file); } @@ -38,6 +39,11 @@ u32 fileRead(void *dest, const char *path) return size; } +u32 getFileSize(const char *path) +{ + return fileRead(NULL, path); +} + void fileWrite(const void *buffer, const char *path, u32 size) { FIL file; diff --git a/source/fs.h b/source/fs.h index 6956148..b0fd5af 100644 --- a/source/fs.h +++ b/source/fs.h @@ -9,6 +9,7 @@ #define PATTERN(a) a "_*.bin" u32 mountFs(void); +u32 getFileSize(const char *path); u32 fileRead(void *dest, const char *path); void fileWrite(const void *buffer, const char *path, u32 size); void findDumpFile(const char *path, char *fileName); diff --git a/source/patches.c b/source/patches.c index 78fb716..f25484f 100644 --- a/source/patches.c +++ b/source/patches.c @@ -264,21 +264,4 @@ void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType, u32 isN3DS) break; } } -} - -u32 getLoader(u8 *pos, u32 *loaderSize) -{ - u8 *off = pos; - u32 size; - - while(1) - { - size = *(u32 *)(off + 0x104) * 0x200; - if(*(u32 *)(off + 0x200) == 0x64616F6C) break; - off += size; - } - - *loaderSize = size; - - return (u32)(off - pos); } \ No newline at end of file diff --git a/source/patches.h b/source/patches.h index 3e470fa..4c7c765 100644 --- a/source/patches.h +++ b/source/patches.h @@ -29,5 +29,4 @@ void patchUnitInfoValueSet(u8 *pos, u32 size); void patchKernelFCRAMAndVRAMMappingPermissions(u8 *pos, u32 size); void reimplementSvcBackdoor(u8 *pos, u32 size); void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType, u32 isN3DS); -u32 getLoader(u8 *pos, u32 *loaderSize); u8 *getUnitInfoValueSet(u8 *pos, u32 size); \ No newline at end of file