Merged the two branches

This commit is contained in:
Aurora 2016-09-08 18:47:13 +02:00
parent 72c8212a0e
commit dc8e4e5f14
13 changed files with 187 additions and 22 deletions

View File

@ -35,8 +35,15 @@ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c)))
bundled = $(dir_build)/rebootpatch.h $(dir_build)/emunandpatch.h $(dir_build)/svcGetCFWInfopatch.h $(dir_build)/injector.h \
$(dir_build)/loader.h $(dir_build)/k11modulespatch.h $(dir_build)/arm9_exceptions.h $(dir_build)/arm11_exceptions.h
bundled = $(dir_build)/rebootpatch.h $(dir_build)/emunandpatch.h $(dir_build)/svcGetCFWInfopatch.h $(dir_build)/injector.h $(dir_build)/loader.h
ifeq ($(strip $(BUILD)),DEV)
CFLAGS += -DDEV
bundled += $(dir_build)/k11modulespatch.h $(dir_build)/arm9_exceptions.h $(dir_build)/arm11_exceptions.h
title := \"$(name) $(revision) (dev) configuration\"
else
title := \"$(name) $(revision) configuration\"
endif
.PHONY: all
all: launcher a9lh ninjhax
@ -109,7 +116,7 @@ $(dir_build)/svcGetCFWInfopatch.h: $(dir_patches)/svcGetCFWInfo.s
$(dir_build)/injector.h: $(dir_injector)/Makefile
@mkdir -p "$(@D)"
@$(MAKE) -C $(dir_injector)
@$(MAKE) -C $(dir_injector) BUILD=$(BUILD)
@bin2c -o $@ -n injector $(@D)/injector.cxi
$(dir_build)/loader.h: $(dir_loader)/Makefile
@ -125,7 +132,7 @@ $(dir_build)/arm11_exceptions.h: $(dir_arm11_exceptions)/Makefile
@bin2c -o $@ -n arm11_exceptions $(@D)/arm11_exceptions.bin
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) (dev) configuration\""
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="$(title)"
$(dir_build)/patches.o: CFLAGS += -DREVISION=\"$(revision)\" -DCOMMIT_HASH="0x$(commit)"
$(dir_build)/%.o: $(dir_source)/%.c $(bundled)

View File

@ -30,6 +30,10 @@ LDFLAGS := -Xlinker --defsym="__start__=0x14000000" -specs=3dsx.specs $(ASFLAGS)
objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c))
ifeq ($(strip $(BUILD)),DEV)
CFLAGS += -DDEV
endif
.PHONY: all
all: ../$(dir_build)/$(name).cxi

View File

@ -495,6 +495,7 @@ void patchCode(u64 progId, u8 *code, u32 size)
break;
}
#ifdef DEV
case 0x0004003000008A02LL: // ErrDisp
{
if(CONFIG_DEVOPTIONS == 0)
@ -528,6 +529,7 @@ void patchCode(u64 progId, u8 *code, u32 size)
break;
}
#endif
default:
if(CONFIG_USELANGEMUANDCODE)

View File

@ -74,16 +74,22 @@ void configMenu(bool oldPinStatus)
const char *multiOptionsText[] = { "Default EmuNAND: 1( ) 2( ) 3( ) 4( )",
"Screen brightness: 4( ) 3( ) 2( ) 1( )",
"PIN lock: Off( ) 4( ) 6( ) 8( ) digits",
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )",
"Dev. features: ErrDisp( ) UNITINFO( ) None( )" };
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )"
#ifdef DEV
, "Dev. features: ErrDisp( ) UNITINFO( ) None( )"
#endif
};
const char *singleOptionsText[] = { "( ) Autoboot SysNAND",
"( ) Use SysNAND FIRM if booting with R (A9LH)",
"( ) Enable region/language emu. and ext. .code",
"( ) Show current NAND in System Settings",
"( ) Show GBA boot screen in patched AGB_FIRM",
"( ) Display splash screen before payloads",
"( ) Patch SVC/service/archive/ARM9 access" };
"( ) Display splash screen before payloads"
#ifdef DEV
, "( ) Patch SVC/service/archive/ARM9 access"
#endif
};
struct multiOption {
int posXs[4];
@ -93,8 +99,10 @@ void configMenu(bool oldPinStatus)
{ .posXs = {19, 24, 29, 34} },
{ .posXs = {21, 26, 31, 36} },
{ .posXs = {14, 19, 24, 29} },
{ .posXs = {17, 26, 32, 44} },
{ .posXs = {23, 35, 43, 0} }
{ .posXs = {17, 26, 32, 44} }
#ifdef DEV
, { .posXs = {23, 35, 43, 0} }
#endif
};
//Calculate the amount of the various kinds of options and pre-select the first single one

View File

@ -40,12 +40,15 @@
#define CONFIG_DEFAULTEMU MULTICONFIG(0)
#define CONFIG_BRIGHTNESS MULTICONFIG(1)
#define CONFIG_PIN MULTICONFIG(2)
#define CONFIG_DEVOPTIONS MULTICONFIG(4)
#define CONFIG_AUTOBOOTSYS CONFIG(0)
#define CONFIG_USESYSFIRM CONFIG(1)
#define CONFIG_SHOWGBABOOT CONFIG(4)
#define CONFIG_PAYLOADSPLASH CONFIG(5)
#ifdef DEV
#define CONFIG_DEVOPTIONS MULTICONFIG(4)
#define CONFIG_PATCHACCESS CONFIG(6)
#endif
typedef struct __attribute__((packed))
{

View File

@ -20,6 +20,7 @@
* Notices displayed by works containing it.
*/
#ifdef DEV
#include "exceptions.h"
#include "fs.h"
#include "strings.h"
@ -186,4 +187,5 @@ void detectAndProcessExceptionDumps(void)
waitInput();
mcuPowerOff();
}
}
}
#endif

View File

@ -20,6 +20,7 @@
* Notices displayed by works containing it.
*/
#ifdef DEV
#pragma once
#include "types.h"
@ -44,4 +45,5 @@ typedef struct __attribute__((packed))
void installArm9Handlers(void);
void installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset);
void detectAndProcessExceptionDumps(void);
void detectAndProcessExceptionDumps(void);
#endif

View File

@ -30,13 +30,16 @@
#include "cache.h"
#include "emunand.h"
#include "crypto.h"
#include "exceptions.h"
#include "draw.h"
#include "screen.h"
#include "buttons.h"
#include "pin.h"
#include "../build/injector.h"
#ifdef DEV
#include "exceptions.h"
#endif
extern u16 launchedFirmTidLow[8]; //Defined in start.s
static firmHeader *const firm = (firmHeader *)0x24000000;
@ -70,7 +73,9 @@ void main(void)
//Attempt to read the configuration file
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
#ifdef DEV
detectAndProcessExceptionDumps();
#endif
//Determine if this is a firmlaunch boot
if(launchedFirmTidLow[5] != 0)
@ -86,7 +91,9 @@ void main(void)
firmSource = (FirmwareSource)BOOTCFG_FIRM;
isA9lh = BOOTCFG_A9LH != 0;
#ifdef DEV
if(isA9lh) installArm9Handlers();
#endif
}
else
{
@ -96,7 +103,9 @@ void main(void)
//Determine if booting with A9LH
isA9lh = !PDN_SPI_CNT;
#ifdef DEV
if(isA9lh) installArm9Handlers();
#endif
//Get pressed buttons
u32 pressed = HID_PAD;
@ -250,6 +259,7 @@ void main(void)
launchFirm(firmType);
}
#ifdef DEV
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
{
section = firm->section;
@ -294,6 +304,43 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
return firmVersion;
}
#else
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
{
section = firm->section;
//Load FIRM from CTRNAND
u32 firmVersion = firmRead(firm, (u32)*firmType);
if(!isN3DS && *firmType == NATIVE_FIRM)
{
if(firmVersion < 0x18)
{
//We can't boot < 3.x EmuNANDs
if(firmSource != FIRMWARE_SYSNAND)
error("An old unsupported EmuNAND has been detected.\nLuma3DS is unable to boot it");
if(BOOTCFG_SAFEMODE != 0) error("SAFE_MODE is not supported on 1.x/2.x FIRM");
*firmType = NATIVE_FIRM1X2X;
}
//We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD
else if(firmVersion < 0x25)
{
if(!fileRead(firm, "/luma/firmware.bin") || section[2].address != (u8 *)0x8006800)
error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot");
//No assumption regarding FIRM version
firmVersion = 0xFFFFFFFF;
}
}
if(firmVersion != 0xFFFFFFFF) decryptExeFs((u8 *)firm);
return firmVersion;
}
#endif
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh)
{
@ -315,11 +362,17 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
process9MemAddr;
u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &process9MemAddr);
#ifdef DEV
//Find Kernel11 SVC table and handler, exceptions page and free space locations
u8 *freeK11Space;
u32 *arm11SvcHandler,
*arm11ExceptionsPage,
*arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage);
#else
//Find Kernel11 SVC table and free space locations
u8 *freeK11Space;
u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space);
#endif
//Apply signature patches
patchSignatureChecks(process9Offset, process9Size);
@ -349,6 +402,7 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, &freeK11Space);
#ifdef DEV
//Apply UNITINFO patch
if(CONFIG_DEVOPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[2].size);
@ -377,6 +431,7 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
patchK11ModuleChecks(arm11Section1, section[1].size, &freeK11Space);
patchP9AccessChecks(process9Offset, process9Size);
}
#endif
}
static inline void patchLegacyFirm(FirmwareType firmType)
@ -390,10 +445,12 @@ static inline void patchLegacyFirm(FirmwareType firmType)
firm->arm9Entry = (u8 *)0x801301C;
}
applyLegacyFirmPatches((u8 *)firm, firmType);
#ifdef DEV
//Apply UNITINFO patch
if(CONFIG_DEVOPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[3].size);
applyLegacyFirmPatches((u8 *)firm, firmType);
#endif
}
static inline void patch1x2xNativeAndSafeFirm(void)
@ -410,14 +467,17 @@ static inline void patch1x2xNativeAndSafeFirm(void)
}
else patchOldFirmWrites(arm9Section, section[2].size);
#ifdef DEV
if(CONFIG_DEVOPTIONS != 2)
{
//Kernel9/Process9 debugging
patchArm9ExceptionHandlersInstall(arm9Section, section[2].size);
patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address);
}
#endif
}
#ifdef DEV
static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
{
u32 srcModuleSize,
@ -457,14 +517,51 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
}
}
}
#else
static inline void copySection0AndInjectSystemModules(void)
{
u32 srcModuleSize,
dstModuleSize;
for(u8 *src = (u8 *)firm + section[0].offset, *srcEnd = src + section[0].size, *dst = section[0].address;
src < srcEnd; src += srcModuleSize, dst += dstModuleSize)
{
srcModuleSize = *(u32 *)(src + 0x104) * 0x200;
char *moduleName = (char *)(src + 0x200);
void *module;
if(memcmp(moduleName, "loader", 6) == 0)
{
module = (void *)injector;
dstModuleSize = injector_size;
}
else
{
module = src;
dstModuleSize = srcModuleSize;
}
memcpy(dst, module, dstModuleSize);
}
}
#endif
static inline void launchFirm(FirmwareType firmType)
{
#ifdef DEV
//Allow module injection and/or inject 3ds_injector on new NATIVE_FIRMs and LGY FIRMs
u32 sectionNum;
if(firmType != SAFE_FIRM && firmType != NATIVE_FIRM1X2X)
{
copySection0AndInjectSystemModules(firmType);
#else
//If we're booting NATIVE_FIRM, section0 needs to be copied separately to inject 3ds_injector
u32 sectionNum;
if(firmType == NATIVE_FIRM)
{
copySection0AndInjectSystemModules();
#endif
sectionNum = 1;
}
else sectionNum = 0;

View File

@ -51,5 +51,9 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource);
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh);
static inline void patchLegacyFirm(FirmwareType firmType);
static inline void patch1x2xNativeAndSafeFirm(void);
#ifdef DEV
static inline void copySection0AndInjectSystemModules(FirmwareType firmType);
#else
static inline void copySection0AndInjectSystemModules(void);
#endif
static inline void launchFirm(FirmwareType firmType);

View File

@ -192,6 +192,7 @@ u32 firmRead(void *dest, u32 firmType)
return firmVersion;
}
#ifdef DEV
void findDumpFile(const char *path, char *fileName)
{
DIR dir;
@ -203,7 +204,7 @@ void findDumpFile(const char *path, char *fileName)
u32 i = 18,
tmp = ++n;
while(tmp)
while(tmp > 0)
{
fileName[i--] = '0' + (tmp % 10);
tmp /= 10;
@ -211,4 +212,5 @@ void findDumpFile(const char *path, char *fileName)
}
f_closedir(&dir);
}
}
#endif

View File

@ -36,4 +36,6 @@ void fileDelete(const char *path);
void loadPayload(u32 pressed);
u32 firmRead(void *dest, u32 firmType);
#ifdef DEV
void findDumpFile(const char *path, char *fileName);
#endif

View File

@ -25,7 +25,10 @@
#include "config.h"
#include "../build/rebootpatch.h"
#include "../build/svcGetCFWInfopatch.h"
#ifdef DEV
#include "../build/k11modulespatch.h"
#endif
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
{
@ -38,6 +41,7 @@ u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
}
#ifdef DEV
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage)
{
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
@ -54,6 +58,23 @@ u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler
return arm11SvcTable;
}
#else
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space)
{
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
u32 *arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, sizeof(pattern)) - 0xB;
u32 svcOffset = (-((arm11ExceptionsPage[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch
u32 *arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address
while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL)
const u8 pattern2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
*freeK11Space = memsearch(pos, pattern2, size, sizeof(pattern2)) + 1;
return arm11SvcTable;
}
#endif
void patchSignatureChecks(u8 *pos, u32 size)
{
@ -155,7 +176,12 @@ void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
}
else isRelease = rev[4] == 0;
info->flags = 1 /* dev branch */ | ((isRelease ? 1 : 0) << 1) /* is release */;
#ifdef DEV
info->flags = 1 /* dev branch */ |
#else
info->flags = 0 /* master branch */ |
#endif
((isRelease ? 1 : 0) << 1) /* is release */;
arm11SvcTable[0x2E] = 0xFFF00000 + *freeK11Space - pos; //Stubbed svc
*freeK11Space += svcGetCFWInfo_size;
@ -211,6 +237,7 @@ void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType)
}
}
#ifdef DEV
void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size)
{
const u8 pattern[] = {0x03, 0xA0, 0xE3, 0x18};
@ -337,4 +364,5 @@ void patchUnitInfoValueSet(u8 *pos, u32 size)
off[0] = isDevUnit ? 0 : 1;
off[3] = 0xE3;
}
}
#endif

View File

@ -50,7 +50,6 @@ typedef struct __attribute__((packed))
extern bool isN3DS, isDevUnit;
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage);
void patchSignatureChecks(u8 *pos, u32 size);
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
@ -60,6 +59,8 @@ void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType);
#ifdef DEV
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage);
void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size);
u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset);
void patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address);
@ -69,4 +70,7 @@ void patchKernel11Panic(u8 *pos, u32 size);
void patchP9AccessChecks(u8 *pos, u32 size);
void patchArm11SvcAccessChecks(u32 *arm11SvcHandler);
void patchK11ModuleChecks(u8 *pos, u32 size, u8 **freeK11Space);
void patchUnitInfoValueSet(u8 *pos, u32 size);
void patchUnitInfoValueSet(u8 *pos, u32 size);
#else
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space);
#endif