Enable support for reading FIRM system modules from SD card (in /luma/sysmodules)

This commit is contained in:
TuxSH 2016-06-27 13:21:08 +02:00
parent a9db998d84
commit 0eb87df84f
6 changed files with 68 additions and 28 deletions

View File

@ -378,6 +378,7 @@ static inline void patchSafeFirm(void)
patchFirmWrites(arm9Section, section[2].size); patchFirmWrites(arm9Section, section[2].size);
} }
else patchFirmWriteSafe(arm9Section, section[2].size);
if(DEVMODE) if(DEVMODE)
{ {
@ -385,20 +386,70 @@ static inline void patchSafeFirm(void)
patchExceptionHandlersInstall(arm9Section, section[2].size); patchExceptionHandlersInstall(arm9Section, section[2].size);
patchSvcBreak9(arm9Section, section[2].size, (u32)(section[2].address)); 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; u8 *arm11Section0 = (u8 *)firm + section[0].offset;
char fileName[] = "/luma/sysmodules/--------.cxi";
const char *ext = ".cxi";
u32 loaderSize; struct
u32 loaderOffset = getLoader(arm11Section0, &loaderSize); {
u32 size;
char name[8];
const u8 *addr;
} modules[5] = {{0}};
memcpy(section[0].address, arm11Section0, loaderOffset); u8 *pos = arm11Section0;
memcpy(section[0].address + loaderOffset, injector, injector_size); u32 loaderIndex = 0;
memcpy(section[0].address + loaderOffset + injector_size, arm11Section0 + loaderOffset + loaderSize, section[0].size - (loaderOffset + loaderSize)); 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) static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch)
@ -407,7 +458,7 @@ static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch)
u32 sectionNum; u32 sectionNum;
if(firmType == NATIVE_FIRM) if(firmType == NATIVE_FIRM)
{ {
copySection0AndInjectLoader(); copySection0AndInjectSystemModules();
sectionNum = 1; sectionNum = 1;
} }
else sectionNum = 0; else sectionNum = 0;

View File

@ -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 patchNativeFirm(FirmwareSource nandType, u32 emuHeader, A9LHMode a9lhMode);
static inline void patchLegacyFirm(FirmwareType firmType); static inline void patchLegacyFirm(FirmwareType firmType);
static inline void patchSafeFirm(void); static inline void patchSafeFirm(void);
static inline void copySection0AndInjectLoader(void); static inline void copySection0AndInjectSystemModules(void);
static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch); static inline void launchFirm(FirmwareType firmType, u32 isFirmlaunch);

View File

@ -30,6 +30,7 @@ u32 fileRead(void *dest, const char *path)
{ {
unsigned int read; unsigned int read;
size = f_size(&file); size = f_size(&file);
if(dest == NULL) return size;
f_read(&file, dest, size, &read); f_read(&file, dest, size, &read);
f_close(&file); f_close(&file);
} }
@ -38,6 +39,11 @@ u32 fileRead(void *dest, const char *path)
return size; return size;
} }
u32 getFileSize(const char *path)
{
return fileRead(NULL, path);
}
void fileWrite(const void *buffer, const char *path, u32 size) void fileWrite(const void *buffer, const char *path, u32 size)
{ {
FIL file; FIL file;

View File

@ -9,6 +9,7 @@
#define PATTERN(a) a "_*.bin" #define PATTERN(a) a "_*.bin"
u32 mountFs(void); u32 mountFs(void);
u32 getFileSize(const char *path);
u32 fileRead(void *dest, const char *path); u32 fileRead(void *dest, const char *path);
void fileWrite(const void *buffer, const char *path, u32 size); void fileWrite(const void *buffer, const char *path, u32 size);
void findDumpFile(const char *path, char *fileName); void findDumpFile(const char *path, char *fileName);

View File

@ -265,20 +265,3 @@ void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType, u32 isN3DS)
} }
} }
} }
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);
}

View File

@ -29,5 +29,4 @@ void patchUnitInfoValueSet(u8 *pos, u32 size);
void patchKernelFCRAMAndVRAMMappingPermissions(u8 *pos, u32 size); void patchKernelFCRAMAndVRAMMappingPermissions(u8 *pos, u32 size);
void reimplementSvcBackdoor(u8 *pos, u32 size); void reimplementSvcBackdoor(u8 *pos, u32 size);
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType, u32 isN3DS); void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType, u32 isN3DS);
u32 getLoader(u8 *pos, u32 *loaderSize);
u8 *getUnitInfoValueSet(u8 *pos, u32 size); u8 *getUnitInfoValueSet(u8 *pos, u32 size);