mirror of
https://github.com/LumaTeam/Luma3DS.git
synced 2026-02-22 01:44:38 +00:00
Add basic support for prototype firmware
* Installs arm9 exception handlers * Disables NAND signature checks, allowing the firmware to boot on retail devices
This commit is contained in:
parent
9b8a95a1de
commit
92e586cb3c
@ -39,6 +39,7 @@
|
||||
#include "chainloader.h"
|
||||
|
||||
static Firm *firm = (Firm *)0x20001000;
|
||||
u32 firmProtoVersion = 0;
|
||||
|
||||
static __attribute__((noinline)) bool overlaps(u32 as, u32 ae, u32 bs, u32 be)
|
||||
{
|
||||
@ -203,29 +204,38 @@ u32 loadNintendoFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadF
|
||||
{
|
||||
firmVersion = 0xFFFFFFFF;
|
||||
|
||||
if(!ISN3DS && *firmType == NATIVE_FIRM)
|
||||
if(!ISN3DS && (*firmType == NATIVE_FIRM || *firmType == NATIVE_FIRM1X2X))
|
||||
{
|
||||
__attribute__((aligned(4))) static const u8 hashes[3][0x20] = {
|
||||
__attribute__((aligned(4))) static const u8 hashes[4][0x20] = {
|
||||
{0xD7, 0x43, 0x0F, 0x27, 0x8D, 0xC9, 0x3F, 0x4C, 0x96, 0xB5, 0xA8, 0x91, 0x48, 0xDB, 0x08, 0x8A,
|
||||
0x7E, 0x46, 0xB3, 0x95, 0x65, 0xA2, 0x05, 0xF1, 0xF2, 0x41, 0x21, 0xF1, 0x0C, 0x59, 0x6A, 0x9D},
|
||||
{0x39, 0x75, 0xB5, 0x28, 0x24, 0x5E, 0x8B, 0x56, 0xBC, 0x83, 0x79, 0x41, 0x09, 0x2C, 0x42, 0xE6,
|
||||
0x26, 0xB6, 0x80, 0x59, 0xA5, 0x56, 0xF9, 0xF9, 0x6E, 0xF3, 0x63, 0x05, 0x58, 0xDF, 0x35, 0xEF},
|
||||
{0x81, 0x9E, 0x71, 0x58, 0xE5, 0x44, 0x73, 0xF7, 0x48, 0x78, 0x7C, 0xEF, 0x5E, 0x30, 0xE2, 0x28,
|
||||
0x78, 0x0B, 0x21, 0x23, 0x94, 0x63, 0xE8, 0x4E, 0x06, 0xBB, 0xD6, 0x8D, 0xA0, 0x99, 0xAE, 0x98},
|
||||
{0x1D, 0xD5, 0xB0, 0xC2, 0xD9, 0x4A, 0x4A, 0xF3, 0x23, 0xDD, 0x2F, 0x65, 0x21, 0x95, 0x9B, 0x7E,
|
||||
0xF2, 0x71, 0x7E, 0xB6, 0x7A, 0x3A, 0x74, 0x78, 0x0D, 0xE3, 0xB5, 0x0C, 0x2B, 0x7F, 0x85, 0x37}
|
||||
0xF2, 0x71, 0x7E, 0xB6, 0x7A, 0x3A, 0x74, 0x78, 0x0D, 0xE3, 0xB5, 0x0C, 0x2B, 0x7F, 0x85, 0x37},
|
||||
};
|
||||
|
||||
u32 i;
|
||||
for(i = 0; i < 3; i++) if(memcmp(firm->section[1].hash, hashes[i], 0x20) == 0) break;
|
||||
for(i = 0; i < 4; i++) if(memcmp(firm->section[1].hash, hashes[i], 0x20) == 0) break;
|
||||
|
||||
switch(i)
|
||||
{
|
||||
// Beta
|
||||
case 0:
|
||||
firmVersion = 0x0;
|
||||
firmProtoVersion = 243;
|
||||
*firmType = NATIVE_PROTOTYPE;
|
||||
break;
|
||||
// Release
|
||||
case 1:
|
||||
firmVersion = 0x18;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
firmVersion = 0x1D;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
firmVersion = 0x1F;
|
||||
break;
|
||||
default:
|
||||
@ -737,6 +747,26 @@ u32 patch1x2xNativeAndSafeFirm(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 patchPrototypeNative(void)
|
||||
{
|
||||
u8 *arm9Section = (u8 *)firm + firm->section[2].offset;
|
||||
|
||||
//Find the Process9 .code location, size and memory address
|
||||
u32 process9Size,
|
||||
process9MemAddr;
|
||||
u8 *process9Offset = getProcess9Info(arm9Section, firm->section[2].size, &process9Size, &process9MemAddr);
|
||||
|
||||
u32 kernel9Size = (u32)(process9Offset - arm9Section) - sizeof(Cxi) - 0x200,
|
||||
ret = 0;
|
||||
|
||||
ret += patchProtoNandSignatureCheck(process9Offset, process9Size);
|
||||
|
||||
//Arm9 exception handlers
|
||||
ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void launchFirm(int argc, char **argv)
|
||||
{
|
||||
prepareArm11ForFirmlaunch();
|
||||
|
||||
@ -35,4 +35,5 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora
|
||||
u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch);
|
||||
u32 patchAgbFirm(bool loadFromStorage, bool doUnitinfoPatch);
|
||||
u32 patch1x2xNativeAndSafeFirm(void);
|
||||
u32 patchPrototypeNative(void);
|
||||
void launchFirm(int argc, char **argv);
|
||||
|
||||
@ -386,6 +386,9 @@ boot:
|
||||
case NATIVE_FIRM1X2X:
|
||||
res = patch1x2xNativeAndSafeFirm();
|
||||
break;
|
||||
case NATIVE_PROTOTYPE:
|
||||
res = patchPrototypeNative();
|
||||
break;
|
||||
}
|
||||
|
||||
if(res != 0) error("Failed to apply %u FIRM patch(es).", res);
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
#define K11EXT_VA 0x70000000
|
||||
|
||||
extern u16 launchedPath[];
|
||||
extern u32 firmProtoVersion;
|
||||
|
||||
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
||||
{
|
||||
@ -54,10 +55,20 @@ u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
||||
|
||||
Cxi *off = (Cxi *)(temp - 0x100);
|
||||
|
||||
*process9Size = (off->ncch.exeFsSize - 1) * 0x200;
|
||||
*process9MemAddr = off->exHeader.systemControlInfo.textCodeSet.address;
|
||||
|
||||
return (u8 *)off + (off->ncch.exeFsOffset + 1) * 0x200;
|
||||
// Prototype FW has a different NCCH format
|
||||
if (firmProtoVersion && firmProtoVersion <= 243)
|
||||
{
|
||||
*process9Size = off->ncch.exeFsSize;
|
||||
return (u8 *)off + off->ncch.exeFsOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
*process9Size = (off->ncch.exeFsSize - 1) * 0x200;
|
||||
return (u8 *)off + (off->ncch.exeFsOffset + 1) * 0x200;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage)
|
||||
@ -834,3 +845,20 @@ u32 patchLgyK11(u8 *section1, u32 section1Size, u8 *section2, u32 section2Size)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 patchProtoNandSignatureCheck(u8 *pos, u32 size) {
|
||||
if (firmProtoVersion == 243) {
|
||||
static const u8 pattern[] = {0x08, 0x31, 0x9F, 0xE5};
|
||||
|
||||
// Signature check function returns 0 if failed and 1 if succeeded.
|
||||
// Proc9 breaks if the returned value is 0, change it to break if
|
||||
// the returned value is 2 (never).
|
||||
u8 *off = memsearch(pos, pattern, size, sizeof(pattern)) + 0x20;
|
||||
if (!off)
|
||||
return 1;
|
||||
|
||||
*off = 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -31,6 +31,7 @@
|
||||
* FIRM partition writes patches by delebile
|
||||
* Idea for svcBreak patches from yellows8 and others on #3dsdev
|
||||
* TWL_FIRM patches by Steveice10 and others
|
||||
* Signature patches for prototype FW by PabloMK7
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -68,3 +69,4 @@ u32 patchTwlShaHashChecks(u8 *pos, u32 size);
|
||||
u32 patchAgbBootSplash(u8 *pos, u32 size);
|
||||
void patchTwlBg(u8 *pos, u32 size); // silently fails
|
||||
u32 patchLgyK11(u8 *section1, u32 section1Size, u8 *section2, u32 section2Size);
|
||||
u32 patchProtoNandSignatureCheck(u8 *pos, u32 size);
|
||||
@ -134,7 +134,8 @@ typedef enum FirmwareType
|
||||
AGB_FIRM,
|
||||
SAFE_FIRM,
|
||||
SYSUPDATER_FIRM,
|
||||
NATIVE_FIRM1X2X
|
||||
NATIVE_FIRM1X2X,
|
||||
NATIVE_PROTOTYPE,
|
||||
} FirmwareType;
|
||||
|
||||
typedef enum bootType
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user