Compare commits

...

19 Commits

Author SHA1 Message Date
Aurora
5a9d0e2569 Fail 2016-04-27 16:16:25 +02:00
Aurora
041ca8451e Use the older cxi, should fix NANDs with incomplete background updates 2016-04-27 15:37:13 +02:00
Aurora
2382e6d82c Fixed oversight in the injector 2016-04-27 04:52:23 +02:00
Aurora
f9a1f1a79b Move the UNITINFO patch to the developer version 2016-04-26 21:51:57 +02:00
Aurora
a736e4602a Cleanup 2016-04-26 20:10:20 +02:00
Aurora
5202ba8826 Update ReadME 2016-04-26 14:33:01 +02:00
Aurora
0f1bc98bb7 Rename "Use SysNAND FIRM as default" to "SysNAND is updated" 2016-04-26 14:11:34 +02:00
Aurora
d40722af53 Apply the eShop update skipping patch only if the updated NAND was not booted (depends on the "Use SysNAND FIRM as default" option) 2016-04-26 14:05:48 +02:00
Aurora
c9781ab626 Added python implementation of the path changer from @TuxSH 2016-04-26 03:39:36 +02:00
Aurora
4cbf4e93e7 Minor stuff 2016-04-26 01:30:03 +02:00
Aurora
1f68c2da42 Update ReadME 2016-04-24 20:19:35 +02:00
Aurora
d786c292f3 Update submodules 2016-04-24 19:49:09 +02:00
Aurora
ada3e09784 Added L+A payload 2016-04-24 19:46:33 +02:00
Aurora
c928b3b68b New icon 2016-04-23 15:39:40 +02:00
Aurora
ae9c29629c Wrong name in the Makefile 2016-04-23 03:50:04 +02:00
Aurora
3fd4603553 Welcome Luma3DS 2016-04-23 01:43:36 +02:00
Aurora
c14526068a Minor stuff 2016-04-21 23:39:05 +02:00
Aurora
180b2a6f4d Bye bye fileSize! 2016-04-21 05:08:42 +02:00
Aurora
19d8861d27 Give 3ds_injector a sane makefile 2016-04-19 20:51:00 +02:00
37 changed files with 156 additions and 222 deletions

Submodule CakeHax updated: 6b8fca0b37...5245c7b9dc

View File

@@ -11,7 +11,7 @@ AS := arm-none-eabi-as
LD := arm-none-eabi-ld LD := arm-none-eabi-ld
OC := arm-none-eabi-objcopy OC := arm-none-eabi-objcopy
name := AuReiNand name := Luma3DS
version := $(shell git describe --abbrev=0 --tags) version := $(shell git describe --abbrev=0 --tags)
dir_source := source dir_source := source
@@ -27,7 +27,7 @@ dir_out := out
ASFLAGS := -mcpu=arm946e-s ASFLAGS := -mcpu=arm946e-s
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main -O2 -flto -ffast-math CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -fshort-wchar -std=c11 -Wno-main -O2 -flto -ffast-math
LDFLAGS := -nostartfiles LDFLAGS := -nostartfiles
FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Reisyukaku/Aurora Wright" --no-print-directory FLAGS := name=$(name).dat dir_out=$(abspath $(dir_out)) ICON=$(abspath icon.png) APP_DESCRIPTION="Noob-friendly 3DS CFW." APP_AUTHOR="Aurora Wright" --no-print-directory
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
@@ -48,10 +48,7 @@ a9lh: $(dir_out)/arm9loaderhax.bin
ninjhax: $(dir_out)/3ds/$(name) ninjhax: $(dir_out)/3ds/$(name)
.PHONY: release .PHONY: release
release: $(dir_out)/$(name).zip release: $(dir_out)/$(name)$(version).7z
.PHONY: pathchanger
pathchanger: $(dir_out)/pathchanger
.PHONY: clean .PHONY: clean
clean: clean:
@@ -63,10 +60,7 @@ clean:
@rm -rf $(dir_out) $(dir_build) @rm -rf $(dir_out) $(dir_build)
$(dir_out): $(dir_out):
@mkdir -p "$(dir_out)/aurei/payloads" @mkdir -p "$(dir_out)/luma/payloads"
$(dir_out)/pathchanger: $(dir_out)
@cc pathchanger/pathchanger.c -o out/pathchanger
$(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out) $(dir_out)/$(name).dat: $(dir_build)/main.bin $(dir_out)
@$(MAKE) $(FLAGS) -C $(dir_mset) launcher @$(MAKE) $(FLAGS) -C $(dir_mset) launcher
@@ -80,8 +74,8 @@ $(dir_out)/3ds/$(name): $(dir_out)
@$(MAKE) $(FLAGS) -C $(dir_ninjhax) @$(MAKE) $(FLAGS) -C $(dir_ninjhax)
@mv $(dir_out)/$(name).3dsx $(dir_out)/$(name).smdh $@ @mv $(dir_out)/$(name).3dsx $(dir_out)/$(name).smdh $@
$(dir_out)/$(name).zip: launcher a9lh ninjhax $(dir_out)/$(name)$(version).7z: launcher a9lh ninjhax
@cd "$(@D)" && zip -9 -r $(name) * @7z a -mx $@ ./$(@D)/*
$(dir_build)/main.bin: $(dir_build)/main.elf $(dir_build)/main.bin: $(dir_build)/main.elf
$(OC) -S -O binary $< $@ $(OC) -S -O binary $< $@

View File

@@ -1,16 +1,23 @@
# AuReiNand # Luma3DS
*A modification of the ReiNand custom firmware* *Noob-proof (N)3DS "Custom Firmware"*
**Compiling:** **Compiling:**
You'll need armips, [bin2c](https://sourceforge.net/projects/bin2c/), and a recent build of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. [HERE](http://www91.zippyshare.com/v/ePGpjk9r/file.html) is a pre-compiled version of armips for Windows. First you need to clone the repository recursively with: 'git clone --recursive https://github.com/AuroraWright/Luma3DS.git'
Then, just run "make" and everything should work! 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!).
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.
**Setup / Usage / Features:** **Setup / Usage / Features:**
See https://github.com/AuroraWright/AuReiNand/wiki See https://github.com/AuroraWright/Luma3DS/wiki
**Credits:** **Credits:**
See https://github.com/AuroraWright/AuReiNand/wiki/Credits See https://github.com/AuroraWright/Luma3DS/wiki/Credits
**Licensing:**
This software is licensed under the terms of the GPLv3.
You can find a copy of the license in the LICENSE.txt file.

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -123,7 +123,7 @@ static u32 loadConfig(void)
if(!config) if(!config)
{ {
IFile file; IFile file;
if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, "/aurei/config.bin", FS_OPEN_READ))) if(R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, "/luma/config.bin", FS_OPEN_READ)))
{ {
u64 total; u64 total;
if(R_SUCCEEDED(IFile_Read(&file, &total, &config, 4))) config |= 1 << 4; if(R_SUCCEEDED(IFile_Read(&file, &total, &config, 4))) config |= 1 << 4;
@@ -136,14 +136,14 @@ static u32 loadConfig(void)
static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId) static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
{ {
/* Here we look for "/aurei/locales/[u64 titleID in hex, uppercase].txt" /* Here we look for "/luma/locales/[u64 titleID in hex, uppercase].txt"
If it exists it should contain, for example, "EUR IT" */ If it exists it should contain, for example, "EUR IT" */
char path[] = "/aurei/locales/0000000000000000.txt"; char path[] = "/luma/locales/0000000000000000.txt";
u32 i = 30; u32 i = 29;
while(progId > 0) while(progId)
{ {
static const char hexDigits[] = "0123456789ABCDEF"; static const char hexDigits[] = "0123456789ABCDEF";
path[i--] = hexDigits[(u32)(progId & 0xF)]; path[i--] = hexDigits[(u32)(progId & 0xF)];
@@ -336,12 +336,6 @@ void patchCode(u64 progId, u8 *code, u32 size)
static const u8 blockAutoUpdatesPatch[] = { static const u8 blockAutoUpdatesPatch[] = {
0xE3, 0xA0 0xE3, 0xA0
}; };
static const u8 skipEshopUpdateCheckPattern[] = {
0x30, 0xB5, 0xF1, 0xB0
};
static const u8 skipEshopUpdateCheckPatch[] = {
0x00, 0x20, 0x08, 0x60, 0x70, 0x47
};
//Block silent auto-updates //Block silent auto-updates
patchMemory(code, size, patchMemory(code, size,
@@ -351,13 +345,24 @@ void patchCode(u64 progId, u8 *code, u32 size)
sizeof(blockAutoUpdatesPatch), 1 sizeof(blockAutoUpdatesPatch), 1
); );
//Skip update checks to access the EShop //Apply only if the updated NAND hasn't been booted
patchMemory(code, size, if((BOOTCONFIG(0, 3) != 0) == (BOOTCONFIG(3, 1) && CONFIG(1)))
skipEshopUpdateCheckPattern, {
sizeof(skipEshopUpdateCheckPattern), 0, static const u8 skipEshopUpdateCheckPattern[] = {
skipEshopUpdateCheckPatch, 0x30, 0xB5, 0xF1, 0xB0
sizeof(skipEshopUpdateCheckPatch), 1 };
); static const u8 skipEshopUpdateCheckPatch[] = {
0x00, 0x20, 0x08, 0x60, 0x70, 0x47
};
//Skip update checks to access the EShop
patchMemory(code, size,
skipEshopUpdateCheckPattern,
sizeof(skipEshopUpdateCheckPattern), 0,
skipEshopUpdateCheckPatch,
sizeof(skipEshopUpdateCheckPatch), 1
);
}
break; break;
} }
@@ -388,7 +393,7 @@ void patchCode(u64 progId, u8 *code, u32 size)
case 0x0004001000027000LL: // KOR MSET case 0x0004001000027000LL: // KOR MSET
case 0x0004001000028000LL: // TWN MSET case 0x0004001000028000LL: // TWN MSET
{ {
if(CONFIG(6)) if(CONFIG(5))
{ {
static const u16 verPattern[] = u"Ver."; static const u16 verPattern[] = u"Ver.";
const u32 currentNand = BOOTCONFIG(0, 3); const u32 currentNand = BOOTCONFIG(0, 3);
@@ -504,8 +509,8 @@ void patchCode(u64 progId, u8 *code, u32 size)
} }
} }
} }
}
break; break;
}
} }
} }

View File

@@ -7,6 +7,7 @@
#define BUTTON_LEFT (1 << 5) #define BUTTON_LEFT (1 << 5)
#define BUTTON_UP (1 << 6) #define BUTTON_UP (1 << 6)
#define BUTTON_DOWN (1 << 7) #define BUTTON_DOWN (1 << 7)
#define BUTTON_A 1
#define BUTTON_X (1 << 10) #define BUTTON_X (1 << 10)
#define BUTTON_Y (1 << 11) #define BUTTON_Y (1 << 11)
#define BUTTON_R1 (1 << 8) #define BUTTON_R1 (1 << 8)

View File

@@ -7,7 +7,7 @@
static u32 loadPayload(const char *pattern) static u32 loadPayload(const char *pattern)
{ {
char path[30] = "/aurei/payloads"; char path[30] = "/luma/payloads";
DIR dir; DIR dir;
FILINFO info; FILINFO info;
@@ -19,11 +19,11 @@ static u32 loadPayload(const char *pattern)
if(result != FR_OK || !info.fname[0]) if(result != FR_OK || !info.fname[0])
return 0; return 0;
path[15] = '/'; path[14] = '/';
u32 i; u32 i;
for(i = 0; info.fname[i]; i++) for(i = 0; info.fname[i]; i++)
path[16 + i] = info.fname[i]; path[15 + i] = info.fname[i];
path[16 + i] = '\0'; path[15 + i] = '\0';
FIL payload; FIL payload;
unsigned int br; unsigned int br;
@@ -51,6 +51,7 @@ void main(void)
((pressed & BUTTON_X) && LOAD_PAYLOAD("x")) || ((pressed & BUTTON_X) && LOAD_PAYLOAD("x")) ||
((pressed & BUTTON_Y) && LOAD_PAYLOAD("y")) || ((pressed & BUTTON_Y) && LOAD_PAYLOAD("y")) ||
((pressed & BUTTON_R1) && LOAD_PAYLOAD("r")) || ((pressed & BUTTON_R1) && LOAD_PAYLOAD("r")) ||
((pressed & BUTTON_A) && LOAD_PAYLOAD("a")) ||
((pressed & BUTTON_SELECT) && LOAD_PAYLOAD("sel")) || ((pressed & BUTTON_SELECT) && LOAD_PAYLOAD("sel")) ||
LOAD_PAYLOAD("def")) LOAD_PAYLOAD("def"))
((void (*)())PAYLOAD_ADDRESS)(); ((void (*)())PAYLOAD_ADDRESS)();

View File

@@ -1,9 +1,3 @@
/*
* types.h
* by Reisyukaku
* Copyright (c) 2015 All Rights Reserved
*/
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>

View File

@@ -80,7 +80,7 @@ fopen: .ascii "OPEN"
.pool .pool
bin_fname: .dcw "sdmc:/arm9loaderhax.bin" bin_fname: .dcw "sdmc:/arm9loaderhax.bin"
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
dat_fname: .dcw "sdmc:/AuReiNand.dat" dat_fname: .dcw "sdmc:/Luma3DS.dat"
.word 0 .word 0
.align 4 .align 4

View File

@@ -43,7 +43,7 @@ static int fsize(FILE *fp)
static void error(FILE *payload, const char *message) static void error(FILE *payload, const char *message)
{ {
fclose(payload); fclose(payload);
printf("%s, are you sure you're using an AuReiNand payload?\n", message); printf("%s, are you sure you're using a Luma3DS payload?\n", message);
exit(0); exit(0);
} }
@@ -51,7 +51,7 @@ int main(int argc, char **argv)
{ {
if(argc == 1) if(argc == 1)
{ {
printf("Usage: %s <AuReiNand payload path>\n", argv[0]); printf("Usage: %s <Luma3DS payload path>\n", argv[0]);
exit(0); exit(0);
} }

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env python
# Requires Python >= 3.2 or >= 2.7
# This is part of Luma3DS
__author__ = "TuxSH"
__copyright__ = "Copyright (c) 2016 TuxSH"
__license__ = "GPLv3"
__version__ = "v1.0"
import argparse
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Changes the path to Luma3DS for reboot patches")
parser.add_argument("payload", help="Path to the Luma3DS payload")
parser.add_argument("new_path", help="New Luma3DS payload path")
args = parser.parse_args()
data = b""
if len(args.new_path) > 37:
raise SystemExit("The new payload path is too large (37 characters max.)")
with open(args.payload, "rb") as f: data = bytearray(f.read())
if len(data) == 0: raise SystemExit("Could not read {0}".format(args.payload))
if len(data) > 0x20000:
raise SystemExit("The input file is too large, are you sure you're using a Luma3DS payload?")
found_index = data.find("sdmc:/".encode("utf-16-le"))
if found_index == -1:
raise SystemExit("The pattern was not found, are you sure you're usinga a Luma3DS payload?")
namebuf = args.new_path.encode("utf-16-le")
namebuf += b'\x00' * (74 - len(namebuf))
data[found_index + 12 : found_index + 12 + 74] = namebuf
with open(args.payload, "wb+") as f: f.write(data)

View File

@@ -1,9 +1,3 @@
/*
* types.h
* by Reisyukaku
* Copyright (c) 2015 All Rights Reserved
*/
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>

View File

@@ -1,7 +1,5 @@
/* /*
* buttons.h * buttons.h
* by Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once
@@ -21,9 +19,8 @@
#define BUTTON_LEFT (1 << 5) #define BUTTON_LEFT (1 << 5)
#define BUTTON_UP (1 << 6) #define BUTTON_UP (1 << 6)
#define BUTTON_DOWN (1 << 7) #define BUTTON_DOWN (1 << 7)
#define BUTTON_L1R1 (BUTTON_R1 | BUTTON_L1) #define SAFE_MODE (BUTTON_R1 | BUTTON_L1 | BUTTON_A | BUTTON_UP)
#define SAFE_MODE (BUTTON_L1R1 | BUTTON_A | BUTTON_UP)
#define OVERRIDE_BUTTONS (BUTTON_B ^ 0xFFF) #define OVERRIDE_BUTTONS (BUTTON_B ^ 0xFFF)
#define SINGLE_PAYLOAD_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_START | BUTTON_X | BUTTON_Y) #define SINGLE_PAYLOAD_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_START | BUTTON_X | BUTTON_Y)
#define L_PAYLOAD_BUTTONS (BUTTON_R1 | BUTTON_SELECT) #define L_PAYLOAD_BUTTONS (BUTTON_R1 | BUTTON_A | BUTTON_SELECT)
#define MENU_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_A | BUTTON_START) #define MENU_BUTTONS (BUTTON_LEFT | BUTTON_RIGHT | BUTTON_UP | BUTTON_DOWN | BUTTON_A | BUTTON_START)

View File

@@ -1,7 +1,5 @@
/* /*
* config.c * config.c
* by Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "config.h" #include "config.h"
@@ -22,11 +20,10 @@ void configureCFW(const char *configPath)
"New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" }; "New 3DS CPU: Off( ) Clock( ) L2( ) Clock+L2( )" };
const char *singleOptionsText[] = { "( ) Autoboot SysNAND", const char *singleOptionsText[] = { "( ) Autoboot SysNAND",
"( ) Use SysNAND FIRM as default (A9LH-only)", "( ) SysNAND is updated (A9LH-only)",
"( ) Force A9LH detection", "( ) Force A9LH detection",
"( ) Use second EmuNAND as default", "( ) Use second EmuNAND as default",
"( ) Enable region/language emulation", "( ) Enable region/language emulation",
"( ) Use developer UNITINFO",
"( ) 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",
"( ) Enable splash screen with no screen-init" }; "( ) Enable splash screen with no screen-init" };

View File

@@ -1,7 +1,5 @@
/* /*
* config.h * config.h
* by Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once
@@ -14,6 +12,6 @@
#define MULTICONFIG(a) ((config >> (a * 2 + 6)) & 3) #define MULTICONFIG(a) ((config >> (a * 2 + 6)) & 3)
#define BOOTCONFIG(a, b) ((config >> a) & b) #define BOOTCONFIG(a, b) ((config >> a) & b)
extern u32 config; extern u32 config;
void configureCFW(const char *configPath); void configureCFW(const char *configPath);

View File

@@ -1,9 +1,7 @@
/* /*
* crypto.c * crypto.c
* by Reisyukaku / Aurora Wright
* Crypto libs from http://github.com/b1l1s/ctr
* *
* Copyright (c) 2016 All Rights Reserved * Crypto libs from http://github.com/b1l1s/ctr
*/ */
#include "crypto.h" #include "crypto.h"
@@ -11,7 +9,7 @@
#include "fatfs/sdmmc/sdmmc.h" #include "fatfs/sdmmc/sdmmc.h"
/**************************************************************** /****************************************************************
* Crypto Libs * Crypto libs
****************************************************************/ ****************************************************************/
/* original version by megazig */ /* original version by megazig */
@@ -273,7 +271,7 @@ static void sha(void *res, const void *src, u32 size, u32 mode)
} }
/**************************************************************** /****************************************************************
* Nand/FIRM Crypto stuff * NAND/FIRM crypto
****************************************************************/ ****************************************************************/
static u8 nandCTR[0x10], static u8 nandCTR[0x10],
@@ -350,9 +348,9 @@ void decryptExeFs(u8 *inbuf)
void arm9Loader(u8 *arm9Section, u32 mode) void arm9Loader(u8 *arm9Section, u32 mode)
{ {
//Firm keys //Firm keys
u8 keyY[0x10]; u8 keyY[0x10],
u8 arm9BinCTR[0x10]; arm9BinCTR[0x10],
u8 arm9BinSlot = mode ? 0x16 : 0x15; arm9BinSlot = mode ? 0x16 : 0x15;
//Setup keys needed for arm9bin decryption //Setup keys needed for arm9bin decryption
memcpy(keyY, arm9Section + 0x10, 0x10); memcpy(keyY, arm9Section + 0x10, 0x10);
@@ -386,8 +384,8 @@ void arm9Loader(u8 *arm9Section, u32 mode)
//Set >=9.6 KeyXs //Set >=9.6 KeyXs
if(mode) if(mode)
{ {
u8 keyData[] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98}; u8 keyData[0x10] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98},
u8 decKey[0x10]; decKey[0x10];
//Set keys 0x19..0x1F keyXs //Set keys 0x19..0x1F keyXs
aes_use_keyslot(0x11); aes_use_keyslot(0x11);

View File

@@ -1,9 +1,7 @@
/* /*
* crypto.h * crypto.h
* by Reisyukaku / Aurora Wright
* Crypto libs from http://github.com/b1l1s/ctr
* *
* Copyright (c) 2016 All Rights Reserved * Crypto libs from http://github.com/b1l1s/ctr
*/ */
#pragma once #pragma once

View File

@@ -1,9 +1,7 @@
/* /*
* draw.c * draw.c
* by Reisyukaku / Aurora Wright
* Code to print to the screen by mid-kid @CakesFW
* *
* Copyright (c) 2016 All Rights Reserved * Code to print to the screen by mid-kid @CakesFW
*/ */
#include "draw.h" #include "draw.h"
@@ -24,6 +22,7 @@ static const struct fb {
static inline int strlen(const char *string) static inline int strlen(const char *string)
{ {
char *stringEnd = (char *)string; char *stringEnd = (char *)string;
while(*stringEnd) stringEnd++; while(*stringEnd) stringEnd++;
return stringEnd - string; return stringEnd - string;
@@ -41,11 +40,11 @@ void loadSplash(void)
initScreens(); initScreens();
//Don't delay boot if no splash image is on the SD //Don't delay boot if no splash image is on the SD
if(fileRead(fb->top_left, "/aurei/splash.bin", 0x46500) + if(fileRead(fb->top_left, "/luma/splash.bin", 0x46500) +
fileRead(fb->bottom, "/aurei/splashbottom.bin", 0x38400)) fileRead(fb->bottom, "/luma/splashbottom.bin", 0x38400))
{ {
u64 i = 0x1400000; u64 i = 0x1400000;
while(--i) __asm("mov r0, r0"); //Less Ghetto sleep func while(i--) __asm("mov r0, r0"); //Less Ghetto sleep func
} }
} }

View File

@@ -1,9 +1,7 @@
/* /*
* draw.h * draw.h
* by Reisyukaku / Aurora Wright
* Code to print to the screen by mid-kid @CakesFW
* *
* Copyright (c) 2016 All Rights Reserved * Code to print to the screen by mid-kid @CakesFW
*/ */
#pragma once #pragma once

View File

@@ -1,7 +1,5 @@
/* /*
* emunand.c * emunand.c
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "emunand.h" #include "emunand.h"

View File

@@ -1,14 +1,12 @@
/* /*
* emunand.h * emunand.h
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once
#include "types.h" #include "types.h"
#define NCSD_MAGIC (0x4453434E) #define NCSD_MAGIC 0x4453434E
void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND); void getEmunandSect(u32 *off, u32 *head, u32 *emuNAND);
u32 getSDMMC(u8 *pos, u32 size); u32 getSDMMC(u8 *pos, u32 size);

View File

@@ -1,7 +1,5 @@
/* /*
* firm.c * firm.c
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "firm.h" #include "firm.h"
@@ -44,7 +42,7 @@ void main(void)
mountFs(); mountFs();
//Attempt to read the configuration file //Attempt to read the configuration file
const char configPath[] = "/aurei/config.bin"; const char configPath[] = "/luma/config.bin";
if(fileRead(&config, configPath, 4)) needConfig = 1; if(fileRead(&config, configPath, 4)) needConfig = 1;
else else
{ {
@@ -80,9 +78,6 @@ void main(void)
//Get pressed buttons //Get pressed buttons
u32 pressed = HID_PAD; u32 pressed = HID_PAD;
//Determine if we need to autoboot sysNAND
u32 autoBootSys = CONFIG(0);
//Determine if A9LH is installed and the user has an updated sysNAND //Determine if A9LH is installed and the user has an updated sysNAND
if(a9lhBoot || CONFIG(2)) if(a9lhBoot || CONFIG(2))
@@ -141,7 +136,9 @@ void main(void)
configureCFW(configPath); configureCFW(configPath);
//If screens are inited or the corresponding option is set, load splash screen //If screens are inited or the corresponding option is set, load splash screen
if(PDN_GPU_CNT != 1 || CONFIG(8)) loadSplash(); if(PDN_GPU_CNT != 1 || CONFIG(7)) loadSplash();
u32 autoBootSys = CONFIG(0);
//Determine if we need to boot an emuNAND or sysNAND //Determine if we need to boot an emuNAND or sysNAND
nandType = (pressed & BUTTON_L1) ? autoBootSys : ((pressed & BUTTON_R1) ? updatedSys : !autoBootSys); nandType = (pressed & BUTTON_L1) ? autoBootSys : ((pressed & BUTTON_R1) ? updatedSys : !autoBootSys);
@@ -189,29 +186,14 @@ void main(void)
launchFirm(bootType); launchFirm(bootType);
} }
//Load FIRM into FCRAM
static inline void loadFirm(u32 firmType, u32 externalFirm) static inline void loadFirm(u32 firmType, u32 externalFirm)
{ {
section = firm->section; section = firm->section;
u32 firmSize; /* If the conditions to load the external FIRM aren't met, or reading fails, or the FIRM
doesn't match the console, load it from CTRNAND */
if(externalFirm) if(!externalFirm || !fileRead(firm, "/luma/firmware.bin", 0) ||
{ (((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68))
const char path[] = "/aurei/firmware.bin";
firmSize = fileSize(path);
if(firmSize)
{
fileRead(firm, path, firmSize);
//Check that the loaded FIRM matches the console
if((((u32)section[2].address >> 8) & 0xFF) != (console ? 0x60 : 0x68)) firmSize = 0;
}
}
else firmSize = 0;
if(!firmSize)
{ {
const char *firmFolders[3][2] = {{ "00000002", "20000002" }, const char *firmFolders[3][2] = {{ "00000002", "20000002" },
{ "00000102", "20000102" }, { "00000102", "20000102" },
@@ -273,13 +255,6 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhInstalle
*(u16 *)sigOffset2 = sigPatch[0]; *(u16 *)sigOffset2 = sigPatch[0];
*((u16 *)sigOffset2 + 1) = sigPatch[1]; *((u16 *)sigOffset2 + 1) = sigPatch[1];
if(CONFIG(5))
{
//Apply UNITINFO patch
u8 *unitInfoOffset = getUnitInfoValueSet(arm9Section, section[2].size);
*unitInfoOffset = unitInfoPatch;
}
//Replace the FIRM loader with the injector //Replace the FIRM loader with the injector
injectLoader(); injectLoader();
} }
@@ -383,7 +358,8 @@ static inline void patchTwlAgbFirm(u32 firmType)
/* Calculate the amount of patches to apply. Only count the boot screen patch for AGB_FIRM /* Calculate the amount of patches to apply. Only count the boot screen patch for AGB_FIRM
if the matching option was enabled (keep it as last) */ if the matching option was enabled (keep it as last) */
u32 numPatches = firmType == 1 ? (sizeof(twlPatches) / sizeof(patchData)) : (sizeof(agbPatches) / sizeof(patchData) - !CONFIG(7)); u32 numPatches = firmType == 1 ? (sizeof(twlPatches) / sizeof(patchData)) :
(sizeof(agbPatches) / sizeof(patchData) - !CONFIG(6));
const patchData *patches = firmType == 1 ? twlPatches : agbPatches; const patchData *patches = firmType == 1 ? twlPatches : agbPatches;
//Patch //Patch
@@ -405,7 +381,7 @@ static inline void patchTwlAgbFirm(u32 firmType)
static inline void launchFirm(u32 bootType) static inline void launchFirm(u32 bootType)
{ {
//Copy firm partitions to respective memory locations //Copy FIRM sections to respective memory locations
for(u32 i = 0; i < 4 && section[i].size; i++) for(u32 i = 0; i < 4 && section[i].size; i++)
memcpy(section[i].address, (u8 *)firm + section[i].offset, section[i].size); memcpy(section[i].address, (u8 *)firm + section[i].offset, section[i].size);
@@ -421,6 +397,6 @@ static inline void launchFirm(u32 bootType)
//Set ARM11 kernel entrypoint //Set ARM11 kernel entrypoint
*arm11 = (u32)firm->arm11Entry; *arm11 = (u32)firm->arm11Entry;
//Final jump to arm9 kernel //Final jump to ARM9 kernel
((void (*)())firm->arm9Entry)(); ((void (*)())firm->arm9Entry)();
} }

View File

@@ -1,7 +1,5 @@
/* /*
* firm.h * firm.h
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once

View File

@@ -1,7 +1,5 @@
/* /*
* fs.c * fs.c
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "fs.h" #include "fs.h"
@@ -51,25 +49,12 @@ u32 fileWrite(const void *buffer, const char *path, u32 size)
return fr ? 0 : 1; return fr ? 0 : 1;
} }
u32 fileSize(const char *path)
{
FIL fp;
u32 size = 0;
if(f_open(&fp, path, FA_READ) == FR_OK)
size = f_size(&fp);
f_close(&fp);
return size;
}
u32 defPayloadExists(void) u32 defPayloadExists(void)
{ {
DIR dir; DIR dir;
FILINFO info; FILINFO info;
FRESULT result = f_findfirst(&dir, &info, "/aurei/payloads", "def_*.bin"); FRESULT result = f_findfirst(&dir, &info, "/luma/payloads", "def_*.bin");
f_closedir(&dir); f_closedir(&dir);
@@ -86,14 +71,11 @@ void firmRead(void *dest, const char *firmFolder)
f_opendir(&dir, path); f_opendir(&dir, path);
u32 id = 0; u32 id = 0xFFFFFFFF;
//Parse the target directory //Parse the target directory
while(f_readdir(&dir, &info) == FR_OK) while(f_readdir(&dir, &info) == FR_OK && info.fname[0])
{ {
//We've parsed the whole folder
if(!info.fname[0]) break;
//Not a cxi //Not a cxi
if(info.altname[9] != 'A') continue; if(info.altname[9] != 'A') continue;
@@ -105,8 +87,8 @@ void firmRead(void *dest, const char *firmFolder)
tempId += *tmp > '9' ? *tmp - 'A' + 10 : *tmp - '0'; tempId += *tmp > '9' ? *tmp - 'A' + 10 : *tmp - '0';
} }
//Found a newer cxi //Found an older cxi
if(tempId > id) id = tempId; if(tempId < id) id = tempId;
} }
f_closedir(&dir); f_closedir(&dir);
@@ -114,12 +96,12 @@ void firmRead(void *dest, const char *firmFolder)
//Complete the string with the .app name //Complete the string with the .app name
memcpy(&path[34], "/00000000.app", 14); memcpy(&path[34], "/00000000.app", 14);
//Last digit of the .app
u32 i = 42; u32 i = 42;
//Convert back the .app name from integer to array //Convert back the .app name from integer to array
while(id > 0) while(id)
{ {
//Last digit of the .app
static const char hexDigits[] = "0123456789ABCDEF"; static const char hexDigits[] = "0123456789ABCDEF";
path[i--] = hexDigits[id & 0xF]; path[i--] = hexDigits[id & 0xF];
id >>= 4; id >>= 4;

View File

@@ -1,7 +1,5 @@
/* /*
* fs.h * fs.h
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once
@@ -11,6 +9,5 @@
u32 mountFs(void); u32 mountFs(void);
u32 fileRead(void *dest, const char *path, u32 size); u32 fileRead(void *dest, const char *path, u32 size);
u32 fileWrite(const void *buffer, const char *path, u32 size); u32 fileWrite(const void *buffer, const char *path, u32 size);
u32 fileSize(const char *path);
u32 defPayloadExists(void); u32 defPayloadExists(void);
void firmRead(void *dest, const char *firmFolder); void firmRead(void *dest, const char *firmFolder);

View File

@@ -22,26 +22,26 @@ static inline u8 i2cGetDeviceRegAddr(u8 device_id)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static vu8* reg_data_addrs[] = { static vu8 *reg_data_addrs[] = {
(vu8*)(I2C1_REG_OFF + I2C_REG_DATA), (vu8 *)(I2C1_REG_OFF + I2C_REG_DATA),
(vu8*)(I2C2_REG_OFF + I2C_REG_DATA), (vu8 *)(I2C2_REG_OFF + I2C_REG_DATA),
(vu8*)(I2C3_REG_OFF + I2C_REG_DATA), (vu8 *)(I2C3_REG_OFF + I2C_REG_DATA),
}; };
static inline vu8* i2cGetDataReg(u8 bus_id) static inline vu8 *i2cGetDataReg(u8 bus_id)
{ {
return reg_data_addrs[bus_id]; return reg_data_addrs[bus_id];
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static vu8* reg_cnt_addrs[] = { static vu8 *reg_cnt_addrs[] = {
(vu8*)(I2C1_REG_OFF + I2C_REG_CNT), (vu8 *)(I2C1_REG_OFF + I2C_REG_CNT),
(vu8*)(I2C2_REG_OFF + I2C_REG_CNT), (vu8 *)(I2C2_REG_OFF + I2C_REG_CNT),
(vu8*)(I2C3_REG_OFF + I2C_REG_CNT), (vu8 *)(I2C3_REG_OFF + I2C_REG_CNT),
}; };
static inline vu8* i2cGetCntReg(u8 bus_id) static inline vu8 *i2cGetCntReg(u8 bus_id)
{ {
return reg_cnt_addrs[bus_id]; return reg_cnt_addrs[bus_id];
} }
@@ -94,16 +94,16 @@ u32 i2cWriteRegister(u8 dev_id, u8 reg, u8 data)
u8 bus_id = i2cGetDeviceBusId(dev_id); u8 bus_id = i2cGetDeviceBusId(dev_id);
u8 dev_addr = i2cGetDeviceRegAddr(dev_id); u8 dev_addr = i2cGetDeviceRegAddr(dev_id);
for (u32 i = 0; i < 8; i++) for(u32 i = 0; i < 8; i++)
{ {
if (i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg)) if(i2cSelectDevice(bus_id, dev_addr) && i2cSelectRegister(bus_id, reg))
{ {
i2cWaitBusy(bus_id); i2cWaitBusy(bus_id);
*i2cGetDataReg(bus_id) = data; *i2cGetDataReg(bus_id) = data;
*i2cGetCntReg(bus_id) = 0xC1; *i2cGetCntReg(bus_id) = 0xC1;
i2cStop(bus_id, 0); i2cStop(bus_id, 0);
if (i2cGetResult(bus_id)) if(i2cGetResult(bus_id))
return 1; return 1;
} }
*i2cGetCntReg(bus_id) = 0xC5; *i2cGetCntReg(bus_id) = 0xC5;

View File

@@ -1,7 +1,5 @@
/* /*
* loader.c * loader.c
* by Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "loader.h" #include "loader.h"

View File

@@ -1,7 +1,5 @@
/* /*
* loader.h * loader.h
* by Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once

View File

@@ -1,7 +1,5 @@
/* /*
* memory.c * memory.c
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
* *
* Quick Search algorithm adapted from http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190 * Quick Search algorithm adapted from http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190
*/ */

View File

@@ -1,7 +1,5 @@
/* /*
* memory.h * memory.h
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
* *
* Quick Search algorithm adapted from http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190 * Quick Search algorithm adapted from http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190
*/ */

View File

@@ -1,7 +1,5 @@
/* /*
* patches.c * patches.c
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "patches.h" #include "patches.h"
@@ -13,13 +11,9 @@
const u32 mpuPatch[3] = {0x00360003, 0x00200603, 0x001C0603}; const u32 mpuPatch[3] = {0x00360003, 0x00200603, 0x001C0603};
const u16 nandRedir[2] = {0x4C00, 0x47A0}; const u16 nandRedir[2] = {0x4C00, 0x47A0},
sigPatch[2] = {0x2000, 0x4770},
const u16 sigPatch[2] = {0x2000, 0x4770}; writeBlock[2] = {0x2000, 0x46C0};
const u16 writeBlock[2] = {0x2000, 0x46C0};
const u8 unitInfoPatch = 0xE3;
/************************************************** /**************************************************
* Functions * Functions
@@ -69,14 +63,6 @@ u16 *getFirmWrite(u8 *pos, u32 size)
return (u16 *)memsearch(off - 0x100, pattern, 0x100, 4); return (u16 *)memsearch(off - 0x100, pattern, 0x100, 4);
} }
u8 *getUnitInfoValueSet(u8 *pos, u32 size)
{
//Look for UNITINFO value being set
const u8 pattern[] = {0x01, 0x10, 0xA0, 0x13};
return memsearch(pos, pattern, size, 4) + 3;
}
void *getLoader(u8 *pos, u32 size, u32 *loaderSize) void *getLoader(u8 *pos, u32 size, u32 *loaderSize)
{ {
u8 *const off = memsearch(pos, "loade", size, 5); u8 *const off = memsearch(pos, "loade", size, 5);

View File

@@ -1,7 +1,5 @@
/* /*
* patches.h * patches.h
* by Reisyukaku / Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once
@@ -12,10 +10,9 @@
* Patches * Patches
**************************************************/ **************************************************/
const u32 mpuPatch[3]; const u32 mpuPatch[3];
const u16 nandRedir[2]; const u16 nandRedir[2],
const u16 sigPatch[2]; sigPatch[2],
const u16 writeBlock[2]; writeBlock[2];
const u8 unitInfoPatch;
/************************************************** /**************************************************
* Functions * Functions
@@ -25,5 +22,4 @@ void getSigChecks(u8 *pos, u32 size, u32 *off, u32 *off2);
void *getReboot(u8 *pos, u32 size); void *getReboot(u8 *pos, u32 size);
u32 getfOpen(u8 *proc9Offset, void *rebootOffset); u32 getfOpen(u8 *proc9Offset, void *rebootOffset);
u16 *getFirmWrite(u8 *pos, u32 size); u16 *getFirmWrite(u8 *pos, u32 size);
u8 *getUnitInfoValueSet(u8 *pos, u32 size);
void *getLoader(u8 *pos, u32 size, u32 *loaderSize); void *getLoader(u8 *pos, u32 size, u32 *loaderSize);

View File

@@ -1,10 +1,8 @@
/* /*
* screeninit.c * screeninit.c
* by Aurora Wright *
* Screen init code by dark_samus, bil1s, Normmatt, delebile and others. * Screen init code by dark_samus, bil1s, Normmatt, delebile and others.
* Screen deinit code by tiniVi. * Screen deinit code by tiniVi.
*
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "screeninit.h" #include "screeninit.h"

View File

@@ -1,10 +1,8 @@
/* /*
* screeninit.h * screeninit.h
* by Aurora Wright *
* Screen init code by dark_samus, bil1s, Normmatt, delebile and others. * Screen init code by dark_samus, bil1s, Normmatt, delebile and others.
* Screen deinit code by tiniVi. * Screen deinit code by tiniVi.
*
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once

View File

@@ -1,7 +1,5 @@
/* /*
* types.h * types.h
* by Reisyukaku
* Copyright (c) 2015 All Rights Reserved
*/ */
#pragma once #pragma once

View File

@@ -1,7 +1,5 @@
/* /*
* utils.c * utils.c
* by Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#include "utils.h" #include "utils.h"

View File

@@ -1,7 +1,5 @@
/* /*
* utils.h * utils.h
* by Aurora Wright
* Copyright (c) 2016 All Rights Reserved
*/ */
#pragma once #pragma once