Merge master and dev builds

This commit is contained in:
Aurora 2016-09-19 14:03:55 +02:00
parent eaa4d6323e
commit 420ccdcb82
15 changed files with 123 additions and 303 deletions

View File

@ -38,15 +38,8 @@ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
$(call rwildcard, $(dir_source), *.s *.c))) $(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 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
ifeq ($(strip $(DEV)),TRUE)
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 .PHONY: all
all: launcher a9lh ninjhax menuhax all: launcher a9lh ninjhax menuhax
@ -64,11 +57,7 @@ ninjhax: $(dir_out)/3ds/$(name)
menuhax: $(dir_out)/menuhax/boot.3dsx menuhax: $(dir_out)/menuhax/boot.3dsx
.PHONY: release .PHONY: release
ifeq ($(strip $(DEV)),TRUE)
release: $(dir_out)/$(name)$(revision)-dev.7z
else
release: $(dir_out)/$(name)$(revision).7z release: $(dir_out)/$(name)$(revision).7z
endif
.PHONY: clean .PHONY: clean
clean: clean:
@ -107,9 +96,6 @@ $(dir_out)/pathchanger: $(dir_pathchanger)/pathchanger.py $(dir_pathchanger)/pre
@cp -rfT $(dir_pathchanger)/prebuilt $@ @cp -rfT $(dir_pathchanger)/prebuilt $@
$(dir_out)/$(name)$(revision).7z: all $(dir_out)/pathchanger $(dir_out)/$(name)$(revision).7z: all $(dir_out)/pathchanger
@7z a -mx $@ ./$(@D)/*
$(dir_out)/$(name)$(revision)-dev.7z: all $(dir_out)/pathchanger
@7z a -mx $@ ./$(@D)/* ./$(dir_exceptions)/exception_dump_parser.py @7z a -mx $@ ./$(@D)/* ./$(dir_exceptions)/exception_dump_parser.py
$(dir_build)/main.bin: $(dir_build)/main.elf $(dir_build)/main.bin: $(dir_build)/main.elf
@ -135,7 +121,7 @@ $(dir_build)/svcGetCFWInfopatch.h: $(dir_patches)/svcGetCFWInfo.s
$(dir_build)/injector.h: $(dir_injector)/Makefile $(dir_build)/injector.h: $(dir_injector)/Makefile
@mkdir -p "$(@D)" @mkdir -p "$(@D)"
@$(MAKE) -C $(dir_injector) DEV=$(DEV) @$(MAKE) -C $(dir_injector)
@bin2c -o $@ -n injector $(@D)/injector.cxi @bin2c -o $@ -n injector $(@D)/injector.cxi
$(dir_build)/loader.h: $(dir_loader)/Makefile $(dir_build)/loader.h: $(dir_loader)/Makefile
@ -156,7 +142,7 @@ $(dir_build)/arm11_exceptions.h: $(dir_arm11_exceptions)/Makefile
@bin2c -o $@ -n arm11_exceptions $(@D)/arm11_exceptions.bin @bin2c -o $@ -n arm11_exceptions $(@D)/arm11_exceptions.bin
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3 $(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
$(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="$(title)" $(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) configuration\""
$(dir_build)/patches.o: CFLAGS += -DREVISION=\"$(revision)\" -DCOMMIT_HASH="0x$(commit)" $(dir_build)/patches.o: CFLAGS += -DREVISION=\"$(revision)\" -DCOMMIT_HASH="0x$(commit)"
$(dir_build)/%.o: $(dir_source)/%.c $(bundled) $(dir_build)/%.o: $(dir_source)/%.c $(bundled)

View File

@ -14,7 +14,7 @@ To use it, you will need a console capable of running homebrew software on the A
First you need to clone the repository recursively with: `git clone --recursive https://github.com/AuroraWright/Luma3DS.git` First you need to clone the repository recursively with: `git clone --recursive https://github.com/AuroraWright/Luma3DS.git`
To compile, you'll need [armips](https://github.com/Kingcom/armips), [bin2c](https://sourceforge.net/projects/bin2c/), and a recent build of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. To compile, you'll need [armips](https://github.com/Kingcom/armips), [bin2c](https://sourceforge.net/projects/bin2c/), and a recent build of [makerom](https://github.com/profi200/Project_CTR) added to your PATH.
For your convenience, here are [Windows](http://www91.zippyshare.com/v/ePGpjk9r/file.html) and [Linux](https://mega.nz/#!uQ1T1IAD!Q91O0e12LXKiaXh_YjXD3D5m8_W3FuMI-hEa6KVMRDQ) builds of armips (thanks to who compiled them!). For your convenience, here are [Windows](http://www91.zippyshare.com/v/ePGpjk9r/file.html) and [Linux](https://mega.nz/#!uQ1T1IAD!Q91O0e12LXKiaXh_YjXD3D5m8_W3FuMI-hEa6KVMRDQ) builds of armips (thanks to who compiled them!).
Finally just run `make` (for the regular version) or `make DEV=TRUE` (for the dev version) and everything should work! Finally just run `make` and everything should work!
You can find the compiled files in the `out` folder. You can find the compiled files in the `out` folder.
--- ---

View File

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

View File

@ -582,10 +582,9 @@ void patchCode(u64 progId, u8 *code, u32 size)
break; break;
} }
#ifdef DEV
case 0x0004003000008A02LL: // ErrDisp case 0x0004003000008A02LL: // ErrDisp
{ {
if(MULTICONFIG(DEVOPTIONS) == 0) if(MULTICONFIG(DEVOPTIONS) == 1)
{ {
static const u8 unitinfoCheckPattern1[] = { static const u8 unitinfoCheckPattern1[] = {
0x14, 0x00, 0xD0, 0xE5, 0xDB 0x14, 0x00, 0xD0, 0xE5, 0xDB
@ -616,7 +615,6 @@ void patchCode(u64 progId, u8 *code, u32 size)
break; break;
} }
#endif
default: default:
if(CONFIG(USELANGEMUANDCODE)) if(CONFIG(USELANGEMUANDCODE))

View File

@ -16,24 +16,21 @@ enum multiOptions
{ {
DEFAULTEMU = 0, DEFAULTEMU = 0,
BRIGHTNESS, BRIGHTNESS,
SPLASH,
PIN, PIN,
NEWCPU NEWCPU,
#ifdef DEV DEVOPTIONS
, DEVOPTIONS
#endif
}; };
enum singleOptions enum singleOptions
{ {
AUTOBOOTSYS = 0, AUTOBOOTSYS = 0,
USESYSFIRM, USESYSFIRM,
SDFIRMSANDMODULES,
USELANGEMUANDCODE, USELANGEMUANDCODE,
PATCHVERSTRING, PATCHVERSTRING,
SHOWGBABOOT, SHOWGBABOOT,
PAYLOADSPLASH PATCHACCESS
#ifdef DEV
, PATCHACCESS
#endif
}; };
void patchCode(u64 progId, u8 *code, u32 size); void patchCode(u64 progId, u8 *code, u32 size);

View File

@ -68,22 +68,19 @@ void configMenu(bool oldPinStatus)
{ {
const char *multiOptionsText[] = { "Default EmuNAND: 1( ) 2( ) 3( ) 4( )", const char *multiOptionsText[] = { "Default EmuNAND: 1( ) 2( ) 3( ) 4( )",
"Screen brightness: 4( ) 3( ) 2( ) 1( )", "Screen brightness: 4( ) 3( ) 2( ) 1( )",
"Splash: Off( ) Before( ) After( ) payloads",
"PIN lock: Off( ) 4( ) 6( ) 8( ) digits", "PIN lock: Off( ) 4( ) 6( ) 8( ) digits",
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" "New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )",
#ifdef DEV "Dev. features: Off( ) ErrDisp( ) UNITINFO( )"
, "Dev. features: ErrDisp( ) UNITINFO( ) Off( )"
#endif
}; };
const char *singleOptionsText[] = { "( ) Autoboot SysNAND", const char *singleOptionsText[] = { "( ) Autoboot SysNAND",
"( ) Use SysNAND FIRM if booting with R (A9LH)", "( ) Use SysNAND FIRM if booting with R (A9LH)",
"( ) Enable FIRMs and modules loading from SD",
"( ) Enable region/language emu. and ext. .code", "( ) Enable region/language emu. and ext. .code",
"( ) Show NAND or user string in System Settings", "( ) Show NAND or user string in System Settings",
"( ) Show GBA boot screen in patched AGB_FIRM", "( ) Show GBA boot screen in patched AGB_FIRM",
"( ) Display splash screen before payloads" "( ) Patch SVC/service/archive/ARM9 access"
#ifdef DEV
, "( ) Patch SVC/service/archive/ARM9 access"
#endif
}; };
const char *optionsDescription[] = { "Select the default EmuNAND.\n\n" const char *optionsDescription[] = { "Select the default EmuNAND.\n\n"
@ -92,6 +89,13 @@ void configMenu(bool oldPinStatus)
"Select the screen brightness.", "Select the screen brightness.",
"Enable splash screen support.\n\n"
"\t* 'After payloads' displays it\n"
"before booting payloads.\n\n"
"\t* 'Before payloads' displays it\n"
"afterwards (intended for splashes\n"
"that display button hints).",
"Activate a PIN lock.\n\n" "Activate a PIN lock.\n\n"
"The PIN will be asked each time\n" "The PIN will be asked each time\n"
"Luma3DS boots.\n\n" "Luma3DS boots.\n\n"
@ -103,18 +107,20 @@ void configMenu(bool oldPinStatus)
"It will be always enabled.\n\n" "It will be always enabled.\n\n"
"'Clock+L2' can cause issues with some\n" "'Clock+L2' can cause issues with some\n"
"games.", "games.",
#ifdef DEV
"Select the developer features.\n\n" "Select the developer features.\n\n"
"\t* 'Off' disables exception handlers\n"
"in FIRM.\n"
"\t* 'ErrDisp' displays debug info\n" "\t* 'ErrDisp' displays debug info\n"
"on the 'An error has occurred' screen.\n" "on the 'An error has occurred' screen.\n"
"\t* 'UNITINFO' makes the console be\n" "\t* 'UNITINFO' makes the console be\n"
"always detected as a development unit\n" "always detected as a development unit\n"
"(which breaks online features and\n" "(which breaks online features and\n"
"allows booting some developer\n" "allows booting some developer\n"
"software).\n" "software).\n\n"
"\t* 'Off' disables exception handlers\n" "Only change this if you know what you\n"
"in FIRM.", "are doing!",
#endif
"If enabled SysNAND will be launched on\n" "If enabled SysNAND will be launched on\n"
"boot. Otherwise, an EmuNAND will.\n\n" "boot. Otherwise, an EmuNAND will.\n\n"
"Hold L on boot to switch NAND.\n\n" "Hold L on boot to switch NAND.\n\n"
@ -132,6 +138,11 @@ void configMenu(bool oldPinStatus)
"(Up/Right/Down/Left equal EmuNANDs\n" "(Up/Right/Down/Left equal EmuNANDs\n"
"1/2/3/4).", "1/2/3/4).",
"If enabled, you will be able to load\n"
"FIRMs and system modules from the SD\n"
"card.\n\n"
"This isn't needed in most cases,",
"Enable overriding the region and\n" "Enable overriding the region and\n"
"language configuration and the usage\n" "language configuration and the usage\n"
"of patched code binaries for specific\n" "of patched code binaries for specific\n"
@ -154,16 +165,10 @@ void configMenu(bool oldPinStatus)
"Show the GBA boot screen when booting\n" "Show the GBA boot screen when booting\n"
"GBA games.", "GBA games.",
"If enabled, the splash screen will be\n" "Disable SVC, service, archive and ARM9\n"
"displayed before booting payloads,\n" "exheader access checks.\n\n"
"otherwise it will be displayed\n" "Only change this if you know what you\n"
"afterwards.\n\n" "are doing!",
"Intended for splash screens that\n"
"display button hints."
#ifdef DEV
, "Disable SVC, service, archive and ARM9\n"
"exheader access checks."
#endif
}; };
struct multiOption { struct multiOption {
@ -173,11 +178,10 @@ void configMenu(bool oldPinStatus)
} multiOptions[] = { } multiOptions[] = {
{ .posXs = {19, 24, 29, 34} }, { .posXs = {19, 24, 29, 34} },
{ .posXs = {21, 26, 31, 36} }, { .posXs = {21, 26, 31, 36} },
{ .posXs = {12, 22, 31, 0} },
{ .posXs = {14, 19, 24, 29} }, { .posXs = {14, 19, 24, 29} },
{ .posXs = {17, 26, 32, 44} } { .posXs = {17, 26, 32, 44} },
#ifdef DEV { .posXs = {19, 30, 42, 0} }
, { .posXs = {23, 35, 43, 0} }
#endif
}; };
//Calculate the amount of the various kinds of options and pre-select the first single one //Calculate the amount of the various kinds of options and pre-select the first single one

View File

@ -30,7 +30,7 @@
#define CONFIG_PATH "/luma/config.bin" #define CONFIG_PATH "/luma/config.bin"
#define CONFIG_VERSIONMAJOR 1 #define CONFIG_VERSIONMAJOR 1
#define CONFIG_VERSIONMINOR 4 #define CONFIG_VERSIONMINOR 5
#define BOOTCFG_NAND BOOTCONFIG(0, 7) #define BOOTCFG_NAND BOOTCONFIG(0, 7)
#define BOOTCFG_FIRM BOOTCONFIG(3, 7) #define BOOTCFG_FIRM BOOTCONFIG(3, 7)
@ -42,24 +42,21 @@ enum multiOptions
{ {
DEFAULTEMU = 0, DEFAULTEMU = 0,
BRIGHTNESS, BRIGHTNESS,
SPLASH,
PIN, PIN,
NEWCPU NEWCPU,
#ifdef DEV DEVOPTIONS
, DEVOPTIONS
#endif
}; };
enum singleOptions enum singleOptions
{ {
AUTOBOOTSYS = 0, AUTOBOOTSYS = 0,
USESYSFIRM, USESYSFIRM,
SDFIRMSANDMODULES,
USELANGEMUANDCODE, USELANGEMUANDCODE,
PATCHVERSTRING, PATCHVERSTRING,
SHOWGBABOOT, SHOWGBABOOT,
PAYLOADSPLASH PATCHACCESS
#ifdef DEV
, PATCHACCESS
#endif
}; };
typedef struct __attribute__((packed)) typedef struct __attribute__((packed))

View File

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

View File

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

View File

@ -24,6 +24,7 @@
#include "config.h" #include "config.h"
#include "utils.h" #include "utils.h"
#include "fs.h" #include "fs.h"
#include "exceptions.h"
#include "patches.h" #include "patches.h"
#include "memory.h" #include "memory.h"
#include "strings.h" #include "strings.h"
@ -36,10 +37,6 @@
#include "pin.h" #include "pin.h"
#include "../build/injector.h" #include "../build/injector.h"
#ifdef DEV
#include "exceptions.h"
#endif
extern u16 launchedFirmTidLow[8]; //Defined in start.s extern u16 launchedFirmTidLow[8]; //Defined in start.s
static firmHeader *firm = (firmHeader *)0x24000000; static firmHeader *firm = (firmHeader *)0x24000000;
@ -73,10 +70,6 @@ void main(void)
//Attempt to read the configuration file //Attempt to read the configuration file
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
#ifdef DEV
detectAndProcessExceptionDumps();
#endif
//Determine if this is a firmlaunch boot //Determine if this is a firmlaunch boot
if(launchedFirmTidLow[5] != 0) if(launchedFirmTidLow[5] != 0)
{ {
@ -90,10 +83,6 @@ void main(void)
nandType = (FirmwareSource)BOOTCFG_NAND; nandType = (FirmwareSource)BOOTCFG_NAND;
firmSource = (FirmwareSource)BOOTCFG_FIRM; firmSource = (FirmwareSource)BOOTCFG_FIRM;
isA9lh = BOOTCFG_A9LH != 0; isA9lh = BOOTCFG_A9LH != 0;
#ifdef DEV
if(isA9lh) installArm9Handlers();
#endif
} }
else else
{ {
@ -103,9 +92,7 @@ void main(void)
//Determine if booting with A9LH //Determine if booting with A9LH
isA9lh = !PDN_SPI_CNT; isA9lh = !PDN_SPI_CNT;
#ifdef DEV if(isA9lh) detectAndProcessExceptionDumps();
if(isA9lh) installArm9Handlers();
#endif
//Get pressed buttons //Get pressed buttons
u32 pressed = HID_PAD; u32 pressed = HID_PAD;
@ -137,8 +124,13 @@ void main(void)
} }
} }
if(needConfig == DONT_CONFIGURE)
{
if(MULTICONFIG(DEVOPTIONS) != 0 && isA9lh) installArm9Handlers();
}
//Boot options aren't being forced //Boot options aren't being forced
if(needConfig != DONT_CONFIGURE) else
{ {
bool pinExists = MULTICONFIG(PIN) != 0 && verifyPin(); bool pinExists = MULTICONFIG(PIN) != 0 && verifyPin();
@ -153,6 +145,8 @@ void main(void)
pressed = HID_PAD; pressed = HID_PAD;
} }
if(MULTICONFIG(DEVOPTIONS) != 0 && isA9lh) installArm9Handlers();
if(isA9lh && !CFG_BOOTENV && pressed == SAFE_MODE) if(isA9lh && !CFG_BOOTENV && pressed == SAFE_MODE)
{ {
nandType = FIRMWARE_SYSNAND; nandType = FIRMWARE_SYSNAND;
@ -170,7 +164,7 @@ void main(void)
} }
else else
{ {
if(CONFIG(PAYLOADSPLASH) && loadSplash()) pressed = HID_PAD; if(MULTICONFIG(SPLASH) == 1 && loadSplash()) pressed = HID_PAD;
/* If L and R/A/Select or one of the single payload buttons are pressed, /* If L and R/A/Select or one of the single payload buttons are pressed,
chainload an external payload */ chainload an external payload */
@ -179,7 +173,7 @@ void main(void)
if(shouldLoadPayload) loadPayload(pressed); if(shouldLoadPayload) loadPayload(pressed);
if(!CONFIG(PAYLOADSPLASH)) loadSplash(); if(MULTICONFIG(SPLASH) == 2) loadSplash();
//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(USESYSFIRM) : false; bool useSysAsDefault = isA9lh ? CONFIG(USESYSFIRM) : false;
@ -246,7 +240,8 @@ void main(void)
writeConfig(needConfig, configTemp); writeConfig(needConfig, configTemp);
} }
u32 firmVersion = loadFirm(&firmType, firmSource); bool loadFromSd = CONFIG(SDFIRMSANDMODULES);
u32 firmVersion = loadFirm(&firmType, firmSource, loadFromSd);
switch(firmType) switch(firmType)
{ {
@ -263,11 +258,10 @@ void main(void)
break; break;
} }
launchFirm(firmType); launchFirm(firmType, loadFromSd);
} }
#ifdef DEV static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd)
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
{ {
section = firm->section; section = firm->section;
@ -287,7 +281,7 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
//Load FIRM from CTRNAND //Load FIRM from CTRNAND
u32 firmVersion = firmRead(firm, (u32)*firmType); u32 firmVersion = firmRead(firm, (u32)*firmType);
bool loadFromSd = false; bool mustLoadFromSd = false;
if(!isN3DS && *firmType == NATIVE_FIRM) if(!isN3DS && *firmType == NATIVE_FIRM)
{ {
@ -303,84 +297,39 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource)
} }
//We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD //We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD
else if(firmVersion < 0x25) loadFromSd = true; else if(firmVersion < 0x25) mustLoadFromSd = true;
} }
u32 firmSize = fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType], 0x400000); if(loadFromSd || mustLoadFromSd)
if(firmSize > 0)
{ {
if(memcmp(firm, "FIRM", 4) != 0) u32 firmSize = fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType], 0x400000);
if(firmSize > 0)
{ {
u8 cetk[0xA50]; if(memcmp(firm, "FIRM", 4) != 0)
{
u8 cetk[0xA50];
if(fileRead(cetk, *firmType == NATIVE_FIRM1X2X ? cetkFiles[0] : cetkFiles[(u32)*firmType], sizeof(cetk))) if(fileRead(cetk, *firmType == NATIVE_FIRM1X2X ? cetkFiles[0] : cetkFiles[(u32)*firmType], sizeof(cetk)))
decryptNusFirm(cetk, (u8 *)firm, firmSize); decryptNusFirm(cetk, (u8 *)firm, firmSize);
}
//Check that the SD FIRM is right for the console from the ARM9 section address
if((section[3].offset ? section[3].address : section[2].address) != (isN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))
error("The firmware.bin in /luma is not valid for your\nconsole, or corrupted");
firmVersion = 0xFFFFFFFF;
} }
//Check that the SD FIRM is right for the console from the ARM9 section address
if((section[3].offset ? section[3].address : section[2].address) != (isN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))
error("The firmware.bin in /luma is not valid for your\nconsole, or corrupted");
firmVersion = 0xFFFFFFFF;
} }
if(firmVersion != 0xFFFFFFFF) if(firmVersion != 0xFFFFFFFF)
{ {
if(loadFromSd) error("An old unsupported FIRM has been detected.\nCopy a valid firmware.bin in /luma to boot"); if(mustLoadFromSd) error("An old unsupported FIRM has been detected.\nCopy a firmware.bin in /luma to boot");
decryptExeFs((u8 *)firm); decryptExeFs((u8 *)firm);
} }
return firmVersion; 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)
{
u32 firmSize = fileRead(firm, "/luma/firmware.bin", 0x400000);
if(firmSize > 0)
{
if(memcmp(firm, "FIRM", 4) != 0)
{
u8 cetk[0xA50];
if(fileRead(cetk, "/luma/cetk", sizeof(cetk)))
decryptNusFirm(cetk, (u8 *)firm, firmSize);
}
if(section[2].address != (u8 *)0x8006800) firmVersion = 0xFFFFFFFF;
}
if(firmVersion != 0xFFFFFFFF) error("An old unsupported FIRM has been detected.\nCopy a valid firmware.bin in /luma to boot");
}
}
if(firmVersion != 0xFFFFFFFF) decryptExeFs((u8 *)firm);
return firmVersion;
}
#endif
static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh) static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isA9lh)
{ {
@ -402,19 +351,12 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
process9MemAddr; process9MemAddr;
u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &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 //Find Kernel11 SVC table and handler, exceptions page and free space locations
u32 baseK11VA; u32 baseK11VA;
u8 *freeK11Space; u8 *freeK11Space;
u32 *arm11SvcHandler, u32 *arm11SvcHandler,
*arm11ExceptionsPage, *arm11ExceptionsPage,
*arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &baseK11VA, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage); *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &baseK11VA, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage);
#else
//Find Kernel11 SVC table and free space locations
u32 baseK11VA;
u8 *freeK11Space;
u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &baseK11VA, &freeK11Space);
#endif
//Apply signature patches //Apply signature patches
patchSignatureChecks(process9Offset, process9Size); patchSignatureChecks(process9Offset, process9Size);
@ -444,27 +386,22 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space); implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
#ifdef DEV
//Apply UNITINFO patch //Apply UNITINFO patch
if(MULTICONFIG(DEVOPTIONS) == 1) patchUnitInfoValueSet(arm9Section, section[2].size); if(MULTICONFIG(DEVOPTIONS) == 2) patchUnitInfoValueSet(arm9Section, section[2].size);
if(isA9lh && MULTICONFIG(DEVOPTIONS) != 2) if(isA9lh && MULTICONFIG(DEVOPTIONS) != 0)
{ {
//Install ARM11 exception handlers //ARM11 exception handlers
u32 codeSetOffset; u32 codeSetOffset,
u32 stackAddress = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &codeSetOffset); stackAddress = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &codeSetOffset);
installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset); installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset);
patchSvcBreak11(arm11Section1, arm11SvcTable);
patchKernel11Panic(arm11Section1, section[1].size);
//Kernel9/Process9 debugging //ARM9 exception handlers
patchArm9ExceptionHandlersInstall(arm9Section, section[2].size); patchArm9ExceptionHandlersInstall(arm9Section, section[2].size);
patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address); patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address);
patchKernel9Panic(arm9Section, section[2].size); patchKernel9Panic(arm9Section, section[2].size);
//Stub svcBreak11 with "bkpt 65535"
patchSvcBreak11(arm11Section1, arm11SvcTable);
//Stub kernel11Panic with "bkpt 65534"
patchKernel11Panic(arm11Section1, section[1].size);
} }
if(CONFIG(PATCHACCESS)) if(CONFIG(PATCHACCESS))
@ -473,7 +410,6 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
patchK11ModuleChecks(arm11Section1, section[1].size, &freeK11Space); patchK11ModuleChecks(arm11Section1, section[1].size, &freeK11Space);
patchP9AccessChecks(process9Offset, process9Size); patchP9AccessChecks(process9Offset, process9Size);
} }
#endif
} }
static inline void patchLegacyFirm(FirmwareType firmType) static inline void patchLegacyFirm(FirmwareType firmType)
@ -489,10 +425,8 @@ static inline void patchLegacyFirm(FirmwareType firmType)
applyLegacyFirmPatches((u8 *)firm, firmType); applyLegacyFirmPatches((u8 *)firm, firmType);
#ifdef DEV
//Apply UNITINFO patch //Apply UNITINFO patch
if(MULTICONFIG(DEVOPTIONS) == 1) patchUnitInfoValueSet(arm9Section, section[3].size); if(MULTICONFIG(DEVOPTIONS) == 2) patchUnitInfoValueSet(arm9Section, section[3].size);
#endif
} }
static inline void patch1x2xNativeAndSafeFirm(void) static inline void patch1x2xNativeAndSafeFirm(void)
@ -509,18 +443,15 @@ static inline void patch1x2xNativeAndSafeFirm(void)
} }
else patchOldFirmWrites(arm9Section, section[2].size); else patchOldFirmWrites(arm9Section, section[2].size);
#ifdef DEV if(MULTICONFIG(DEVOPTIONS) != 0)
if(MULTICONFIG(DEVOPTIONS) != 2)
{ {
//Kernel9/Process9 debugging //ARM9 exception handlers
patchArm9ExceptionHandlersInstall(arm9Section, section[2].size); patchArm9ExceptionHandlersInstall(arm9Section, section[2].size);
patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address); patchSvcBreak9(arm9Section, section[2].size, (u32)section[2].address);
} }
#endif
} }
#ifdef DEV static inline void copySection0AndInjectSystemModules(FirmwareType firmType, bool loadFromSd)
static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
{ {
u32 srcModuleSize, u32 srcModuleSize,
dstModuleSize; dstModuleSize;
@ -531,15 +462,22 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
srcModuleSize = *(u32 *)(src + 0x104) * 0x200; srcModuleSize = *(u32 *)(src + 0x104) * 0x200;
const char *moduleName = (char *)(src + 0x200); const char *moduleName = (char *)(src + 0x200);
char fileName[30] = "/luma/sysmodules/"; u32 fileSize;
const char *ext = ".cxi";
//Read modules from files if they exist if(loadFromSd)
concatenateStrings(fileName, moduleName); {
concatenateStrings(fileName, ext); char fileName[30] = "/luma/sysmodules/";
const char *ext = ".cxi";
u32 fileSize = fileRead(dst, fileName, 2 * srcModuleSize); //Read modules from files if they exist
if(fileSize) dstModuleSize = fileSize; concatenateStrings(fileName, moduleName);
concatenateStrings(fileName, ext);
fileSize = fileRead(dst, fileName, 2 * srcModuleSize);
}
else fileSize = 0;
if(fileSize > 0) dstModuleSize = fileSize;
else else
{ {
const void *module; const void *module;
@ -559,57 +497,17 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
} }
} }
} }
#else
static inline void copySection0AndInjectSystemModules(void) static inline void launchFirm(FirmwareType firmType, bool loadFromSd)
{ {
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;
const char *moduleName = (const char *)(src + 0x200);
const void *module;
if(memcmp(moduleName, "loader", 6) == 0)
{
module = 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 //Allow module injection and/or inject 3ds_injector on new NATIVE_FIRMs and LGY FIRMs
u32 sectionNum; u32 sectionNum;
if(firmType != SAFE_FIRM && firmType != NATIVE_FIRM1X2X) if(firmType == NATIVE_FIRM || (loadFromSd && firmType != SAFE_FIRM && firmType != NATIVE_FIRM1X2X))
{ {
copySection0AndInjectSystemModules(firmType); copySection0AndInjectSystemModules(firmType, loadFromSd);
sectionNum = 1; sectionNum = 1;
} }
else sectionNum = 0; else sectionNum = 0;
#else
//If we're booting NATIVE_FIRM, section0 needs to be copied separately to inject 3ds_injector
u32 sectionNum;
if(firmType == NATIVE_FIRM)
{
copySection0AndInjectSystemModules();
sectionNum = 1;
}
else sectionNum = 0;
#endif
//Copy FIRM sections to respective memory locations //Copy FIRM sections to respective memory locations
for(; sectionNum < 4 && section[sectionNum].size != 0; sectionNum++) for(; sectionNum < 4 && section[sectionNum].size != 0; sectionNum++)

View File

@ -47,15 +47,9 @@ typedef struct firmHeader {
firmSectionHeader section[4]; firmSectionHeader section[4];
} firmHeader; } firmHeader;
static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource); static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource, bool loadFromSd);
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 patch1x2xNativeAndSafeFirm(void); static inline void patch1x2xNativeAndSafeFirm(void);
static inline void copySection0AndInjectSystemModules(FirmwareType firmType, bool loadFromSd);
#ifdef DEV static inline void launchFirm(FirmwareType firmType, bool loadFromSd);
static inline void copySection0AndInjectSystemModules(FirmwareType firmType);
#else
static inline void copySection0AndInjectSystemModules(void);
#endif
static inline void launchFirm(FirmwareType firmType);

View File

@ -196,7 +196,6 @@ u32 firmRead(void *dest, u32 firmType)
return firmVersion; return firmVersion;
} }
#ifdef DEV
void findDumpFile(const char *path, char *fileName) void findDumpFile(const char *path, char *fileName)
{ {
DIR dir; DIR dir;
@ -217,4 +216,3 @@ void findDumpFile(const char *path, char *fileName)
f_closedir(&dir); f_closedir(&dir);
} }
#endif

View File

@ -35,7 +35,4 @@ bool fileWrite(const void *buffer, const char *path, u32 size);
void fileDelete(const char *path); void fileDelete(const char *path);
void loadPayload(u32 pressed); void loadPayload(u32 pressed);
u32 firmRead(void *dest, u32 firmType); u32 firmRead(void *dest, u32 firmType);
#ifdef DEV
void findDumpFile(const char *path, char *fileName); void findDumpFile(const char *path, char *fileName);
#endif

View File

@ -29,10 +29,7 @@
#include "config.h" #include "config.h"
#include "../build/rebootpatch.h" #include "../build/rebootpatch.h"
#include "../build/svcGetCFWInfopatch.h" #include "../build/svcGetCFWInfopatch.h"
#ifdef DEV
#include "../build/k11modulespatch.h" #include "../build/k11modulespatch.h"
#endif
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr) u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
{ {
@ -45,7 +42,6 @@ u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200; return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
} }
#ifdef DEV
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage) u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage)
{ {
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
@ -65,26 +61,6 @@ u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 *
return arm11SvcTable; return arm11SvcTable;
} }
#else
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, 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 pointedInstructionVA = 0xFFFF0008 - svcOffset;
*baseK11VA = pointedInstructionVA & 0xFFFF0000; //This assumes that the pointed instruction has an offset < 0x10000, iirc that's always the case
u32 *arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + pointedInstructionVA - *baseK11VA + 8) - *baseK11VA); //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) void patchSignatureChecks(u8 *pos, u32 size)
{ {
@ -186,11 +162,7 @@ void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **fre
} }
else isRelease = rev[4] == 0; else isRelease = rev[4] == 0;
#ifdef DEV info->flags = isRelease ? 1 : 0;
info->flags = 1 /* dev build */ | ((isRelease ? 1 : 0) << 1) /* is release */;
#else
info->flags = 0 /* regular build */ | ((isRelease ? 1 : 0) << 1) /* is release */;
#endif
arm11SvcTable[0x2E] = baseK11VA + *freeK11Space - pos; //Stubbed svc arm11SvcTable[0x2E] = baseK11VA + *freeK11Space - pos; //Stubbed svc
*freeK11Space += svcGetCFWInfo_size; *freeK11Space += svcGetCFWInfo_size;
@ -246,7 +218,6 @@ void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType)
} }
} }
#ifdef DEV
void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size) void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size)
{ {
const u8 pattern[] = {0x03, 0xA0, 0xE3, 0x18}; const u8 pattern[] = {0x03, 0xA0, 0xE3, 0x18};
@ -373,4 +344,3 @@ void patchUnitInfoValueSet(u8 *pos, u32 size)
off[0] = isDevUnit ? 0 : 1; off[0] = isDevUnit ? 0 : 1;
off[3] = 0xE3; off[3] = 0xE3;
} }
#endif

View File

@ -51,18 +51,10 @@ typedef struct __attribute__((packed))
u32 config; u32 config;
} CFWInfo; } CFWInfo;
#ifdef DEV
extern bool isDevUnit; extern bool isDevUnit;
#endif
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr); u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
#ifdef DEV
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage); u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage);
#else
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space);
#endif
void patchSignatureChecks(u8 *pos, u32 size); void patchSignatureChecks(u8 *pos, u32 size);
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size); void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr); void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
@ -71,8 +63,6 @@ void patchOldFirmWrites(u8 *pos, u32 size);
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space); void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space); void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType); void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType);
#ifdef DEV
void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size); void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size);
u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset); u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset);
void patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address); void patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address);
@ -83,4 +73,3 @@ void patchP9AccessChecks(u8 *pos, u32 size);
void patchArm11SvcAccessChecks(u32 *arm11SvcHandler); void patchArm11SvcAccessChecks(u32 *arm11SvcHandler);
void patchK11ModuleChecks(u8 *pos, u32 size, u8 **freeK11Space); void patchK11ModuleChecks(u8 *pos, u32 size, u8 **freeK11Space);
void patchUnitInfoValueSet(u8 *pos, u32 size); void patchUnitInfoValueSet(u8 *pos, u32 size);
#endif