
- Move emuNAND hook to ITCM, fixing previously untested emuNAND support for 5.0 (and possibly more versions). This was a very long-standing bug - Fix booting on versions 4.x to 8.x, and restore full support for 5.x to 8.x. All Arm11 custom sysmodules and k11ext have been disabled on 4.x because the Luma3DS v13.0 changes couldn't be ported (this means no Rosalina and no region-free and such, and while I could restore some of the functionality, you should just update *after* installing Luma, like you've been instructed to)
148 lines
3.9 KiB
C
148 lines
3.9 KiB
C
#include <3ds.h>
|
|
#include <assert.h>
|
|
#include "memory.h"
|
|
#include "patcher.h"
|
|
#include "ifile.h"
|
|
#include "util.h"
|
|
#include "loader.h"
|
|
#include "service_manager.h"
|
|
#include "3dsx.h"
|
|
#include "hbldr.h"
|
|
|
|
u32 config, multiConfig, bootConfig;
|
|
bool isN3DS, isSdMode, nextGamePatchDisabled;
|
|
|
|
// MAKE SURE fsreg has been init before calling this
|
|
static Result fsldrPatchPermissions(void)
|
|
{
|
|
u32 pid;
|
|
Result res = 0;
|
|
FS_ProgramInfo info;
|
|
ExHeader_Arm11StorageInfo storageInfo = {
|
|
.fs_access_info = FSACCESS_NANDRW | FSACCESS_NANDRO_RO | FSACCESS_SDMC_RW,
|
|
};
|
|
|
|
info.programId = 0x0004013000001302LL; // loader PID
|
|
info.mediaType = MEDIATYPE_NAND;
|
|
TRY(svcGetProcessId(&pid, CUR_PROCESS_HANDLE));
|
|
return FSREG_Register(pid, 0xFFFF000000000000LL, &info, &storageInfo);
|
|
}
|
|
|
|
static inline void loadCFWInfo(void)
|
|
{
|
|
s64 out;
|
|
u64 hbldrTid = 0;
|
|
|
|
bool isLumaWithKext = svcGetSystemInfo(&out, 0x20000, 0) == 1;
|
|
if (isLumaWithKext)
|
|
{
|
|
svcGetSystemInfo(&out, 0x10000, 3);
|
|
config = (u32)out;
|
|
svcGetSystemInfo(&out, 0x10000, 4);
|
|
multiConfig = (u32)out;
|
|
svcGetSystemInfo(&out, 0x10000, 5);
|
|
bootConfig = (u32)out;
|
|
|
|
svcGetSystemInfo(&out, 0x10000, 0x100);
|
|
hbldrTid = (u64)out;
|
|
svcGetSystemInfo(&out, 0x10000, 0x201);
|
|
isN3DS = (bool)out;
|
|
svcGetSystemInfo(&out, 0x10000, 0x203);
|
|
isSdMode = (bool)out;
|
|
}
|
|
else
|
|
{
|
|
// Try to support non-Luma or builds where kext is disabled
|
|
s64 numKips = 0;
|
|
svcGetSystemInfo(&numKips, 26, 0);
|
|
|
|
if (numKips >= 6)
|
|
panic(0xDEADCAFE);
|
|
|
|
#ifndef BUILD_FOR_EXPLOIT_DEV
|
|
config = 1u << PATCHVERSTRING; // all options 0, except maybe the MSET version display patch
|
|
#else
|
|
config = 0;
|
|
#endif
|
|
multiConfig = 0;
|
|
bootConfig = 0;
|
|
isN3DS = OS_KernelConfig->app_memtype >= 6;
|
|
isSdMode = true;
|
|
}
|
|
|
|
hbldrTid = hbldrTid == 0 ? HBLDR_DEFAULT_3DSX_TID : hbldrTid;
|
|
Luma_SharedConfig->hbldr_3dsx_tid = hbldrTid;
|
|
Luma_SharedConfig->selected_hbldr_3dsx_tid = hbldrTid;
|
|
Luma_SharedConfig->use_hbldr = true;
|
|
}
|
|
|
|
void __ctru_exit(int rc) { (void)rc; } // needed to avoid linking error
|
|
|
|
// this is called after main exits
|
|
void __wrap_exit(int rc)
|
|
{
|
|
(void)rc;
|
|
// Not supposed to terminate... kernel will clean up the handles if it does happen anyway
|
|
svcExitProcess();
|
|
}
|
|
|
|
void __sync_init();
|
|
void __libc_init_array(void);
|
|
|
|
// called before main
|
|
void initSystem(void)
|
|
{
|
|
__sync_init();
|
|
loadCFWInfo();
|
|
|
|
Result res;
|
|
for(res = 0xD88007FA; res == (Result)0xD88007FA; svcSleepThread(500 * 1000LL))
|
|
{
|
|
res = srvInit();
|
|
if(R_FAILED(res) && res != (Result)0xD88007FA)
|
|
panic(res);
|
|
}
|
|
|
|
assertSuccess(fsRegInit());
|
|
assertSuccess(fsldrPatchPermissions());
|
|
|
|
//fsldrInit();
|
|
assertSuccess(srvGetServiceHandle(fsGetSessionHandle(), "fs:LDR"));
|
|
|
|
// Hackjob
|
|
assertSuccess(FSUSER_InitializeWithSdkVersion(*fsGetSessionHandle(), 0x70200C8));
|
|
assertSuccess(FSUSER_SetPriority(0));
|
|
|
|
assertSuccess(pxiPmInit());
|
|
|
|
//__libc_init_array();
|
|
}
|
|
|
|
static const ServiceManagerServiceEntry services[] = {
|
|
{ "Loader", 2, loaderHandleCommands, false },
|
|
{ "hb:ldr", 2, hbldrHandleCommands, true },
|
|
{ NULL },
|
|
};
|
|
|
|
static const ServiceManagerNotificationEntry notifications[] = {
|
|
{ 0x000, NULL },
|
|
};
|
|
|
|
static u8 ALIGN(4) staticBufferForHbldr[0x400];
|
|
static_assert(ARGVBUF_SIZE > 2 * PATH_MAX, "Wrong 3DSX argv buffer size");
|
|
|
|
int main(void)
|
|
{
|
|
nextGamePatchDisabled = false;
|
|
|
|
// Loader doesn't use any input static buffer, so we should be fine
|
|
u32 *sbuf = getThreadStaticBuffers();
|
|
sbuf[0] = IPC_Desc_StaticBuffer(sizeof(staticBufferForHbldr), 0);
|
|
sbuf[1] = (u32)staticBufferForHbldr;
|
|
sbuf[2] = IPC_Desc_StaticBuffer(sizeof(staticBufferForHbldr), 1);
|
|
sbuf[3] = (u32)staticBufferForHbldr;
|
|
|
|
assertSuccess(ServiceManager_Run(services, notifications, NULL));
|
|
return 0;
|
|
}
|