Compare commits

..

6 Commits
v6.1 ... v6.1.1

Author SHA1 Message Date
Aurora
c711ed6253 Added a different error for < 3.x NANDs as they can not be booted currently 2016-08-27 00:34:25 +02:00
Aurora
356268eae5 Welcome back to the 1,25s speed boost 2016-08-26 22:24:23 +02:00
Aurora
2dd64b8a92 Merge branch 'master' of https://github.com/AuroraWright/Luma3DS 2016-08-26 21:38:36 +02:00
Aurora
b5cddedb7d Fix config derp 2016-08-26 21:38:03 +02:00
TuxSH
7afdc2b3b5 "Fix" the twlbg patches and make them optional 2016-08-26 19:09:14 +02:00
Aurora
60c4956290 Fix wrong bootconfig being picked up by 3ds_injector, cleanup 2016-08-26 18:44:39 +02:00
10 changed files with 91 additions and 94 deletions

View File

@@ -3,28 +3,7 @@
#include "patcher.h" #include "patcher.h"
#include "ifile.h" #include "ifile.h"
typedef struct __attribute__((packed)) static CFWInfo info = {0};
{
char magic[4];
u8 versionMajor;
u8 versionMinor;
u8 versionBuild;
u8 flags; /* bit 0: dev branch; bit 1: is release */
u32 commitHash;
u32 config;
} CFWInfo;
CFWInfo info = {0};
#ifndef PATH_MAX
#define PATH_MAX 255
#define CONFIG(a) (((info.config >> (a + 16)) & 1) != 0)
#define MULTICONFIG(a) ((info.config >> (a * 2 + 6)) & 3)
#define BOOTCONFIG(a, b) ((info.config >> a) & b)
#endif
static int memcmp(const void *buf1, const void *buf2, u32 size) static int memcmp(const void *buf1, const void *buf2, u32 size)
{ {
@@ -114,17 +93,19 @@ int __attribute__((naked)) svcGetCFWInfo(CFWInfo __attribute__((unused)) *out)
static void loadCFWInfo(void) static void loadCFWInfo(void)
{ {
static bool infoLoaded = false; static bool infoLoaded = false;
if(!infoLoaded) if(!infoLoaded)
{ {
svcGetCFWInfo(&info); svcGetCFWInfo(&info);
IFile file; IFile file;
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, "/", FS_OPEN_READ))) //init SD card for firmlaunch patches if(BOOTCONFIG(5, 1) && R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, "/", FS_OPEN_READ))) //Init SD card if SAFE_MODE is being booted
{ {
IFile_Close(&file); IFile_Close(&file);
} }
}
infoLoaded = true; infoLoaded = true;
} }
}
static bool secureInfoExists(void) static bool secureInfoExists(void)
{ {
@@ -338,6 +319,7 @@ static void patchCfgGetRegion(u8 *code, u32 size, u8 regionId, u32 CFGUHandleOff
void patchCode(u64 progId, u8 *code, u32 size) void patchCode(u64 progId, u8 *code, u32 size)
{ {
loadCFWInfo(); loadCFWInfo();
switch(progId) switch(progId)
{ {
case 0x0004003000008F02LL: // USA Menu case 0x0004003000008F02LL: // USA Menu

View File

@@ -2,4 +2,24 @@
#include <3ds/types.h> #include <3ds/types.h>
#define PATH_MAX 255
#define CONFIG(a) (((info.config >> (a + 16)) & 1) != 0)
#define MULTICONFIG(a) ((info.config >> (a * 2 + 6)) & 3)
#define BOOTCONFIG(a, b) ((info.config >> a) & b)
typedef struct __attribute__((packed))
{
char magic[4];
u8 versionMajor;
u8 versionMinor;
u8 versionBuild;
u8 flags; /* bit 0: dev branch; bit 1: is release */
u32 commitHash;
u32 config;
} CFWInfo;
void patchCode(u64 progId, u8 *code, u32 size); void patchCode(u64 progId, u8 *code, u32 size);

View File

@@ -135,7 +135,7 @@ patchesStart:
.halfword 1 .halfword 1
.halfword 8 .halfword 8
.byte 0x83, 0x30, 0x2e, 0xa4, 0xb0, 0xe2, 0xc2, 0xd6 ; (decrypted = 0x02, 0x01, 0x1a, 0xe3, 0x08, 0x60, 0x87, 0x05) .byte 0x83, 0x30, 0x2e, 0xa4, 0xb0, 0xe2, 0xc2, 0xd6 ; (decrypted = 0x02, 0x01, 0x1a, 0xe3, 0x08, 0x60, 0x87, 0x05)
.byte 0x89, 0x53, 0xb2, 0xa4, 0xb0, 0xe2, 0xc2, 0xd6 ; (decrypted = 0x08, 0x62, 0x86, 0xe3, 0x08, 0x60, 0x87, 0xe5) .byte 0x83, 0x50, 0xf2, 0xa4, 0xb0, 0xe2, 0xc2, 0xd6 ; (decrypted = 0x02, 0x61, 0xc6, 0xe3, 0x08, 0x60, 0x87, 0xe5)
patchesEnd: patchesEnd:

View File

@@ -24,10 +24,9 @@
#include "utils.h" #include "utils.h"
#include "screen.h" #include "screen.h"
#include "draw.h" #include "draw.h"
#include "fs.h"
#include "buttons.h" #include "buttons.h"
void configureCFW(const char *configPath) void configureCFW(void)
{ {
initScreens(); initScreens();
@@ -44,7 +43,8 @@ void configureCFW(const char *configPath)
"( ) Show current NAND in System Settings", "( ) Show current NAND in System Settings",
"( ) Show GBA boot screen in patched AGB_FIRM", "( ) Show GBA boot screen in patched AGB_FIRM",
"( ) Display splash screen before payloads", "( ) Display splash screen before payloads",
"( ) Use a PIN" }; "( ) Use a PIN",
"( ) Enable experimental TwlBg patches" };
struct multiOption { struct multiOption {
int posXs[4]; int posXs[4];
@@ -193,13 +193,6 @@ void configureCFW(const char *configPath)
for(u32 i = 0; i < singleOptionsAmount; i++) for(u32 i = 0; i < singleOptionsAmount; i++)
config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16); config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16);
if(!fileWrite(&config, configPath, 4))
{
createDirectory("luma");
if(!fileWrite(&config, configPath, 4))
error("Error writing the configuration file");
}
//Wait for the pressed buttons to change //Wait for the pressed buttons to change
while(HID_PAD == BUTTON_START); while(HID_PAD == BUTTON_START);
} }

View File

@@ -30,4 +30,4 @@
extern u32 config; extern u32 config;
void configureCFW(const char *configPath); void configureCFW(void);

View File

@@ -43,7 +43,9 @@ static const firmSectionHeader *section;
u32 config, u32 config,
emuOffset; emuOffset;
bool isN3DS, isDevUnit, isFirmlaunch; bool isN3DS,
isDevUnit,
isFirmlaunch;
FirmwareSource firmSource; FirmwareSource firmSource;
@@ -51,7 +53,7 @@ void main(void)
{ {
bool isA9lh; bool isA9lh;
u32 newConfig, u32 configTemp,
emuHeader; emuHeader;
FirmwareType firmType; FirmwareType firmType;
@@ -100,7 +102,8 @@ void main(void)
//Determine if the user chose to use the SysNAND FIRM as default for a R boot //Determine if the user chose to use the SysNAND FIRM as default for a R boot
bool useSysAsDefault = isA9lh ? CONFIG(1) : false; bool useSysAsDefault = isA9lh ? CONFIG(1) : false;
newConfig = (u32)isA9lh << 3; //Save old options and begin saving the new boot configuration
configTemp = (config & 0xFFFFFFC0) | ((u32)isA9lh << 3);
//If it's a MCU reboot, try to force boot options //If it's a MCU reboot, try to force boot options
if(isA9lh && CFG_BOOTENV) if(isA9lh && CFG_BOOTENV)
@@ -113,7 +116,7 @@ void main(void)
needConfig = DONT_CONFIGURE; needConfig = DONT_CONFIGURE;
//Flag to prevent multiple boot options-forcing //Flag to prevent multiple boot options-forcing
newConfig |= 1 << 4; configTemp |= 1 << 4;
} }
/* Else, force the last used boot options unless a button is pressed /* Else, force the last used boot options unless a button is pressed
@@ -141,7 +144,7 @@ void main(void)
if(shouldLoadConfigurationMenu) if(shouldLoadConfigurationMenu)
{ {
configureCFW(configPath); configureCFW();
if(!pinExists && CONFIG(7)) newPin(); if(!pinExists && CONFIG(7)) newPin();
@@ -155,6 +158,9 @@ void main(void)
{ {
nandType = FIRMWARE_SYSNAND; nandType = FIRMWARE_SYSNAND;
firmSource = FIRMWARE_SYSNAND; firmSource = FIRMWARE_SYSNAND;
//Flag to tell loader to init SD
configTemp |= 1 << 5;
} }
else else
{ {
@@ -203,19 +209,23 @@ void main(void)
if(!isFirmlaunch) if(!isFirmlaunch)
{ {
newConfig |= (u32)nandType | ((u32)firmSource << 2); configTemp |= (u32)nandType | ((u32)firmSource << 2);
/* If the boot configuration is different from previously, overwrite it. /* If the configuration is different from previously, overwrite it.
Just the no-forcing flag being set is not enough */ Just the no-forcing flag being set is not enough */
if((newConfig & 0x2F) != (config & 0x3F)) if((configTemp & 0xFFFFFFEF) != config)
{ {
//Preserve user settings (last 26 bits) //Merge the new options and new boot configuration
newConfig |= config & 0xFFFFFFC0; config = (config & 0xFFFFFFC0) | (configTemp & 0x3F);
if(!fileWrite(&newConfig, configPath, 4)) if(!fileWrite(&config, configPath, 4))
{
createDirectory("luma");
if(!fileWrite(&config, configPath, 4))
error("Error writing the configuration file"); error("Error writing the configuration file");
} }
} }
}
u32 firmVersion = loadFirm(firmType); u32 firmVersion = loadFirm(firmType);
@@ -245,6 +255,11 @@ static inline u32 loadFirm(FirmwareType firmType)
if(!isN3DS && firmType == NATIVE_FIRM && firmVersion < 0x25) if(!isN3DS && firmType == NATIVE_FIRM && firmVersion < 0x25)
{ {
//We can't boot < 3.x NANDs
if(firmVersion < 0x18)
error("An old unsupported NAND has been detected.\nLuma3DS is unable to boot it.");
//We can't boot a 4.x NATIVE_FIRM, load one from SD
if(!fileRead(firm, "/luma/firmware.bin") || (((u32)section[2].address >> 8) & 0xFF) != 0x68) if(!fileRead(firm, "/luma/firmware.bin") || (((u32)section[2].address >> 8) & 0xFF) != 0x68)
error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot"); error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot");
@@ -316,7 +331,7 @@ static inline void patchLegacyFirm(FirmwareType firmType)
applyLegacyFirmPatches((u8 *)firm, firmType); applyLegacyFirmPatches((u8 *)firm, firmType);
if(firmType == TWL_FIRM) if(firmType == TWL_FIRM && CONFIG(8))
patchTwlBg((u8 *)firm + section[1].offset); patchTwlBg((u8 *)firm + section[1].offset);
} }
@@ -335,56 +350,44 @@ static inline void patchSafeFirm(void)
else patchFirmWriteSafe(arm9Section, section[2].size); else patchFirmWriteSafe(arm9Section, section[2].size);
} }
static inline void copySection0AndInjectSystemModules(FirmwareType firmType) static inline void copySection0AndInjectSystemModules(void)
{ {
u8 *arm11Section0 = (u8 *)firm + section[0].offset; u8 *arm11Section0 = (u8 *)firm + section[0].offset;
struct struct
{ {
u32 size; u32 size;
char name[8];
const u8 *addr; const u8 *addr;
} modules[5] = {{0}}; } modules[5];
u8 *pos = arm11Section0, *end = pos + section[0].size; u32 n = 0,
u32 n = 0; loaderIndex;
u8 *pos = arm11Section0;
u32 loaderIndex = 0; for(u8 *end = pos + section[0].size; pos < end; pos += modules[n++].size)
while(pos < end)
{ {
modules[n].addr = pos; modules[n].addr = pos;
modules[n].size = *(u32 *)(pos + 0x104) * 0x200; modules[n].size = *(u32 *)(pos + 0x104) * 0x200;
memcpy(modules[n].name, pos + 0x200, 8); if(memcmp(modules[n].addr + 0x200, "loader", 7) == 0) loaderIndex = n;
pos += modules[n].size;
if(firmType == NATIVE_FIRM && memcmp(modules[n].name, "loader", 7) == 0) loaderIndex = n;
n++;
} }
if(firmType == NATIVE_FIRM)
{
modules[loaderIndex].size = injector_size;
modules[loaderIndex].addr = injector; modules[loaderIndex].addr = injector;
} modules[loaderIndex].size = injector_size;
pos = section[0].address; pos = section[0].address;
for(u32 i = 0; i < n; i++)
{
memcpy(pos, modules[i].addr, modules[i].size);
pos += modules[i].size;
}
for(u32 i = 0; i < n; pos += modules[i++].size)
memcpy(pos, modules[i].addr, modules[i].size);
} }
static inline void launchFirm(FirmwareType firmType) static inline void launchFirm(FirmwareType firmType)
{ {
//If we're booting NATIVE_FIRM, section0 needs to be copied separately to inject 3ds_injector //If we're booting NATIVE_FIRM, section0 needs to be copied separately to inject 3ds_injector
u32 sectionNum; u32 sectionNum;
if(firmType != SAFE_FIRM) if(firmType == NATIVE_FIRM)
{ {
copySection0AndInjectSystemModules(firmType); copySection0AndInjectSystemModules();
sectionNum = 1; sectionNum = 1;
} }
else sectionNum = 0; else sectionNum = 0;

View File

@@ -53,5 +53,5 @@ static inline u32 loadFirm(FirmwareType firmType);
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh); static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh);
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 copySection0AndInjectSystemModules(FirmwareType firmType); static inline void copySection0AndInjectSystemModules(void);
static inline void launchFirm(FirmwareType firmType); static inline void launchFirm(FirmwareType firmType);

View File

@@ -167,26 +167,10 @@ void reimplementSvcBackdoor(u8 *pos, u32 size)
} }
} }
extern u32 config;
void implementSvcGetCFWInfo(u8 *pos, u32 size) void implementSvcGetCFWInfo(u8 *pos, u32 size)
{ {
typedef struct __attribute__((packed))
{
char magic[4];
u8 versionMajor;
u8 versionMinor;
u8 versionBuild;
u8 flags;
u32 commitHash;
u32 config;
} CFWInfo;
const char *rev = REVISION; const char *rev = REVISION;
bool isRelease = false; bool isRelease;
findArm11ExceptionsPageAndSvcHandlerAndTable(pos, size); findArm11ExceptionsPageAndSvcHandlerAndTable(pos, size);
findFreeK11Space(pos, size); findFreeK11Space(pos, size);

View File

@@ -33,7 +33,22 @@ typedef struct patchData {
u32 type; u32 type;
} patchData; } patchData;
typedef struct __attribute__((packed))
{
char magic[4];
u8 versionMajor;
u8 versionMinor;
u8 versionBuild;
u8 flags;
u32 commitHash;
u32 config;
} CFWInfo;
extern bool isN3DS; extern bool isN3DS;
extern u32 config;
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr); u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
void patchSignatureChecks(u8 *pos, u32 size); void patchSignatureChecks(u8 *pos, u32 size);