Enable support for reading FIRM system modules from SD card (in /luma/sysmodules)
This commit is contained in:
parent
a9db998d84
commit
0eb87df84f
@ -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;
|
||||||
|
@ -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);
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -264,21 +264,4 @@ void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType, u32 isN3DS)
|
|||||||
break;
|
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);
|
|
||||||
}
|
}
|
@ -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);
|
Reference in New Issue
Block a user