Do the same for romfs redit => get rid of armips; update README.md
This commit is contained in:
parent
0c9365bcb7
commit
6bd7070d38
11
README.md
11
README.md
@ -13,12 +13,11 @@ Since Luma3DS v8.0, Luma3DS has its own in-game menu, triggerable by `L+Down+Sel
|
|||||||
|
|
||||||
## Compiling
|
## Compiling
|
||||||
|
|
||||||
First you need to clone the repository with: `git clone https://github.com/AuroraWright/Luma3DS.git`
|
First you need to clone the repository with: `git clone https://github.com/AuroraWright/Luma3DS.git`
|
||||||
To compile, you'll need [armips](https://github.com/Kingcom/armips) and a build of a recent commit of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. You'll also need to install [firmtool](https://github.com/TuxSH/firmtool), its README contains installation instructions.
|
To compile, you'll need a recent commit of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. You'll also need to install [firmtool](https://github.com/TuxSH/firmtool), its README contains installation instructions.
|
||||||
You'll also need to update your [libctru](https://github.com/smealum/ctrulib) install, building from the latest commit.
|
You'll also need to update your libctru and devkitARM installation to their latest releases.
|
||||||
Here are [Windows](https://buildbot.orphis.net/armips/) and [Linux](https://ev1l0rd.s-ul.eu/mEIk4atQ) builds of armips (thanks to who compiled them!).
|
Then, run `make`.
|
||||||
Run `make` and everything should work!
|
The produced file is called `boot.firm` and is meant to be copied to the root of your SD card, for usage with boot9strap.
|
||||||
You can find the compiled files in the `out` folder.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ include $(DEVKITARM)/3ds_rules
|
|||||||
name := $(shell basename $(CURDIR))
|
name := $(shell basename $(CURDIR))
|
||||||
|
|
||||||
dir_source := source
|
dir_source := source
|
||||||
dir_patches := patches
|
|
||||||
dir_build := build
|
dir_build := build
|
||||||
dir_out := ../../$(dir_build)
|
dir_out := ../../$(dir_build)
|
||||||
|
|
||||||
@ -26,12 +25,6 @@ LDFLAGS := -specs=3dsx.specs $(ASFLAGS) -Wl,--section-start,.text=0x14000000
|
|||||||
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))
|
||||||
|
|
||||||
bundled = $(dir_build)/romfsredir.bin.o
|
|
||||||
|
|
||||||
define bin2o
|
|
||||||
bin2s $< | $(AS) -o $(@)
|
|
||||||
endef
|
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: $(dir_out)/$(name).cxi
|
all: $(dir_out)/$(name).cxi
|
||||||
|
|
||||||
@ -47,22 +40,9 @@ $(dir_out)/$(name).cxi: $(dir_build)/$(name).elf
|
|||||||
$(dir_build)/$(name).elf: $(bundled) $(objects)
|
$(dir_build)/$(name).elf: $(bundled) $(objects)
|
||||||
$(LINK.o) $(OUTPUT_OPTION) $^ $(LIBPATHS) $(LIBS)
|
$(LINK.o) $(OUTPUT_OPTION) $^ $(LIBPATHS) $(LIBS)
|
||||||
|
|
||||||
$(dir_build)/%.bin.o: $(dir_build)/%.bin
|
|
||||||
@$(bin2o)
|
|
||||||
|
|
||||||
$(dir_build)/%.bin: $(dir_patches)/%.s
|
|
||||||
@mkdir -p "$(@D)"
|
|
||||||
@armips $<
|
|
||||||
|
|
||||||
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
|
$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3
|
||||||
|
|
||||||
$(dir_build)/bundled.h: $(bundled)
|
$(dir_build)/%.o: $(dir_source)/%.c
|
||||||
@$(foreach f, $(bundled),\
|
|
||||||
echo "extern const u8" `(echo $(basename $(notdir $(f))) | sed -e 's/^\([0-9]\)/_\1/' | tr . _)`"[];" >> $@;\
|
|
||||||
echo "extern const u32" `(echo $(basename $(notdir $(f)))| sed -e 's/^\([0-9]\)/_\1/' | tr . _)`_size";" >> $@;\
|
|
||||||
)
|
|
||||||
|
|
||||||
$(dir_build)/%.o: $(dir_source)/%.c $(dir_build)/bundled.h
|
|
||||||
@mkdir -p "$(@D)"
|
@mkdir -p "$(@D)"
|
||||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||||
|
|
||||||
|
@ -1,117 +0,0 @@
|
|||||||
.arm.little
|
|
||||||
.create "build/romfsredir.bin", 0
|
|
||||||
|
|
||||||
.macro addr, reg, func
|
|
||||||
add reg, pc, #func-.-8
|
|
||||||
.endmacro
|
|
||||||
.macro load, reg, func
|
|
||||||
ldr reg, [pc, #func-.-8]
|
|
||||||
.endmacro
|
|
||||||
|
|
||||||
; Patch by delebile
|
|
||||||
|
|
||||||
.arm
|
|
||||||
_start:
|
|
||||||
|
|
||||||
; Jumps here before the fsOpenFileDirectly call
|
|
||||||
_mountArchive:
|
|
||||||
b mountArchive
|
|
||||||
.word 0xdead0000 ; Substituted opcode
|
|
||||||
.word 0xdead0001 ; Branch to hooked function
|
|
||||||
|
|
||||||
; Jumps here before every iFileOpen call
|
|
||||||
_fsRedir:
|
|
||||||
b fsRedir
|
|
||||||
.word 0xdead0002 ; Substituted opcode
|
|
||||||
.word 0xdead0003 ; Branch to hooked function
|
|
||||||
|
|
||||||
; Mounts the archive and registers it as 'lf:'
|
|
||||||
mountArchive:
|
|
||||||
cmp r3, #3
|
|
||||||
bne _mountArchive + 4
|
|
||||||
stmfd sp!, {r0-r4, lr}
|
|
||||||
sub sp, sp, #4
|
|
||||||
load r1, archiveId
|
|
||||||
mov r0, sp
|
|
||||||
load r4, fsMountArchive
|
|
||||||
blx r4
|
|
||||||
mov r3, #0
|
|
||||||
mov r2, #0
|
|
||||||
ldr r1, [sp]
|
|
||||||
addr r0, archiveName
|
|
||||||
load r4, fsRegisterArchive
|
|
||||||
blx r4
|
|
||||||
add sp, sp, #4
|
|
||||||
ldmfd sp!, {r0-r4, lr}
|
|
||||||
b _mountArchive + 4
|
|
||||||
|
|
||||||
; Check the path passed to iFileOpen.
|
|
||||||
; If it is trying to access a RomFS file, we try to
|
|
||||||
; open it from the LayeredFS folder.
|
|
||||||
; If the file cannot be opened, we just open
|
|
||||||
; it from its original archive like nothing happened
|
|
||||||
fsRedir:
|
|
||||||
stmfd sp!, {r0-r12, lr}
|
|
||||||
addr r3, romFsMount
|
|
||||||
bl compare
|
|
||||||
addne r3, pc, #updateRomFsMount-.-8
|
|
||||||
blne compare
|
|
||||||
bne endRedir
|
|
||||||
sub sp, sp, #0x400
|
|
||||||
pathRedir:
|
|
||||||
stmfd sp!, {r0-r3}
|
|
||||||
add r0, sp, #0x10
|
|
||||||
load r3, customPath
|
|
||||||
pathRedir_1:
|
|
||||||
ldrb r2, [r3], #1
|
|
||||||
cmp r2, #0
|
|
||||||
strneh r2, [r0], #2
|
|
||||||
bne pathRedir_1
|
|
||||||
pathRedir_2:
|
|
||||||
ldrh r2, [r1], #2
|
|
||||||
cmp r2, #0x3A ; ':'
|
|
||||||
bne pathRedir_2
|
|
||||||
; Skip a slash if there are two after the mountpoint,
|
|
||||||
; as some games mistakenly have those
|
|
||||||
ldrh r3, [r1, #2]
|
|
||||||
cmp r3, #0x2F ; '/'
|
|
||||||
pathRedir_3:
|
|
||||||
ldrh r2, [r1], #2
|
|
||||||
strneh r2, [r0], #2
|
|
||||||
cmp r2, #0
|
|
||||||
bne pathRedir_3
|
|
||||||
ldmfd sp!, {r0-r3}
|
|
||||||
mov r1, sp
|
|
||||||
bl _fsRedir + 4
|
|
||||||
add sp, sp, #0x400
|
|
||||||
cmp r0, #0
|
|
||||||
|
|
||||||
endRedir:
|
|
||||||
ldmfd sp!, {r0-r12, lr}
|
|
||||||
moveq r0, #0
|
|
||||||
bxeq lr
|
|
||||||
b _fsRedir + 4
|
|
||||||
|
|
||||||
compare:
|
|
||||||
mov r9, r1
|
|
||||||
add r10, r3, #4
|
|
||||||
loop:
|
|
||||||
ldrb r12, [r3], #1
|
|
||||||
ldrb r11, [r9], #2
|
|
||||||
cmp r11, r12
|
|
||||||
bxne lr
|
|
||||||
cmp r10, r3
|
|
||||||
bne loop
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.pool
|
|
||||||
.align 4
|
|
||||||
archiveName : .dcb "lf:", 0
|
|
||||||
fsMountArchive : .word 0xdead0005
|
|
||||||
fsRegisterArchive : .word 0xdead0006
|
|
||||||
archiveId : .word 0xdead0007
|
|
||||||
romFsMount : .dcb "rom:"
|
|
||||||
updateRomFsMount : .word 0xdead0008
|
|
||||||
customPath : .word 0xdead0004
|
|
||||||
|
|
||||||
.close
|
|
@ -3,7 +3,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
#include "fsldr.h"
|
#include "fsldr.h"
|
||||||
#include "../build/bundled.h"
|
#include "romfsredir.h"
|
||||||
|
|
||||||
static u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, s32 offset, const void *replace, u32 repSize, u32 count)
|
static u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, s32 offset, const void *replace, u32 repSize, u32 count)
|
||||||
{
|
{
|
||||||
@ -204,7 +204,7 @@ static inline bool findLayeredFsPayloadOffset(u8 *code, u32 size, u32 roSize, u3
|
|||||||
roundedDataSize = ((dataSize + 4095) & 0xFFFFF000);
|
roundedDataSize = ((dataSize + 4095) & 0xFFFFF000);
|
||||||
|
|
||||||
//First check for sufficient padding at the end of the .text segment
|
//First check for sufficient padding at the end of the .text segment
|
||||||
if(roundedTextSize - size >= romfsredir_bin_size) *payloadOffset = size;
|
if(roundedTextSize - size >= romfsRedirPatchSize) *payloadOffset = size;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//If there isn't enough padding look for the "throwFatalError" function to replace
|
//If there isn't enough padding look for the "throwFatalError" function to replace
|
||||||
@ -528,43 +528,18 @@ static inline bool patchLayeredFs(u64 progId, u8 *code, u32 size, u32 textSize,
|
|||||||
|
|
||||||
//Setup the payload
|
//Setup the payload
|
||||||
u8 *payload = code + payloadOffset;
|
u8 *payload = code + payloadOffset;
|
||||||
memcpy(payload, romfsredir_bin, romfsredir_bin_size);
|
|
||||||
|
|
||||||
//Insert symbols in the payload
|
romfsRedirPatchSubstituted1 = *(u32 *)(code + fsOpenFileDirectly);
|
||||||
u32 *payload32 = (u32 *)payload;
|
romfsRedirPatchHook1 = MAKE_BRANCH(payloadOffset + (u32)&romfsRedirPatchHook1 - (u32)romfsRedirPatch, fsOpenFileDirectly + 4);
|
||||||
for(u32 i = 0; i < romfsredir_bin_size / 4; i++)
|
romfsRedirPatchSubstituted1 = *(u32 *)(code + fsTryOpenFile);
|
||||||
{
|
romfsRedirPatchHook2 = MAKE_BRANCH(payloadOffset + (u32)&romfsRedirPatchHook2 - (u32)romfsRedirPatch, fsTryOpenFile + 4);
|
||||||
switch(payload32[i])
|
romfsRedirPatchCustomPath = pathAddress;
|
||||||
{
|
romfsRedirPatchFsMountArchive = 0x100000 + fsMountArchive;
|
||||||
case 0xdead0000:
|
romfsRedirPatchFsRegisterArchive = 0x100000 + fsRegisterArchive;
|
||||||
payload32[i] = *(u32 *)(code + fsOpenFileDirectly);
|
romfsRedirPatchArchiveId = archiveId;
|
||||||
break;
|
memcpy(&romfsRedirPatchRomFsMount, updateRomFsMounts[updateRomFsIndex], 4);
|
||||||
case 0xdead0001:
|
|
||||||
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsOpenFileDirectly + 4);
|
memcpy(payload, romfsRedirPatch, romfsRedirPatchSize);
|
||||||
break;
|
|
||||||
case 0xdead0002:
|
|
||||||
payload32[i] = *(u32 *)(code + fsTryOpenFile);
|
|
||||||
break;
|
|
||||||
case 0xdead0003:
|
|
||||||
payload32[i] = MAKE_BRANCH(payloadOffset + i * 4, fsTryOpenFile + 4);
|
|
||||||
break;
|
|
||||||
case 0xdead0004:
|
|
||||||
payload32[i] = pathAddress;
|
|
||||||
break;
|
|
||||||
case 0xdead0005:
|
|
||||||
payload32[i] = 0x100000 + fsMountArchive;
|
|
||||||
break;
|
|
||||||
case 0xdead0006:
|
|
||||||
payload32[i] = 0x100000 + fsRegisterArchive;
|
|
||||||
break;
|
|
||||||
case 0xdead0007:
|
|
||||||
payload32[i] = archiveId;
|
|
||||||
break;
|
|
||||||
case 0xdead0008:
|
|
||||||
memcpy(payload32 + i, updateRomFsMounts[updateRomFsIndex], 4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(code + pathOffset, "lf:", 3);
|
memcpy(code + pathOffset, "lf:", 3);
|
||||||
memcpy(code + pathOffset + 3, path, sizeof(path));
|
memcpy(code + pathOffset + 3, path, sizeof(path));
|
||||||
|
17
sysmodules/loader/source/romfsredir.h
Normal file
17
sysmodules/loader/source/romfsredir.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <3ds/types.h>
|
||||||
|
|
||||||
|
extern const u8 romfsRedirPatch[];
|
||||||
|
extern const u32 romfsRedirPatchSize;
|
||||||
|
|
||||||
|
extern u32 romfsRedirPatchSubstituted1, romfsRedirPatchHook1;
|
||||||
|
extern u32 romfsRedirPatchSubstituted2, romfsRedirPatchHook2;
|
||||||
|
|
||||||
|
extern u32 romfsRedirPatchArchiveName;
|
||||||
|
extern u32 romfsRedirPatchFsMountArchive;
|
||||||
|
extern u32 romfsRedirPatchFsRegisterArchive;
|
||||||
|
extern u32 romfsRedirPatchArchiveId;
|
||||||
|
extern u32 romfsRedirPatchRomFsMount;
|
||||||
|
extern u32 romfsRedirPatchUpdateRomFsMount;
|
||||||
|
extern u32 romfsRedirPatchCustomPath;
|
130
sysmodules/loader/source/romfsredir.s
Normal file
130
sysmodules/loader/source/romfsredir.s
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
@ Patch by delebile
|
||||||
|
|
||||||
|
.section .data.romfsRedirPatch, "aw", %progbits
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
.global romfsRedirPatch
|
||||||
|
romfsRedirPatch:
|
||||||
|
@ Jumps here before the fsOpenFileDirectly call
|
||||||
|
_mountArchive:
|
||||||
|
b mountArchive
|
||||||
|
.global romfsRedirPatchSubstituted1
|
||||||
|
romfsRedirPatchSubstituted1:
|
||||||
|
.word 0xdead0000 @ Substituted opcode
|
||||||
|
.global romfsRedirPatchHook1
|
||||||
|
romfsRedirPatchHook1:
|
||||||
|
.word 0xdead0001 @ Branch to hooked function
|
||||||
|
|
||||||
|
@ Jumps here before every iFileOpen call
|
||||||
|
_fsRedir:
|
||||||
|
b fsRedir
|
||||||
|
.global romfsRedirPatchSubstituted2
|
||||||
|
romfsRedirPatchSubstituted2:
|
||||||
|
.word 0xdead0002 @ Substituted opcode
|
||||||
|
.global romfsRedirPatchHook2
|
||||||
|
romfsRedirPatchHook2:
|
||||||
|
.word 0xdead0002 @ Branch to hooked function
|
||||||
|
|
||||||
|
@ Mounts the archive and registers it as 'lf:'
|
||||||
|
mountArchive:
|
||||||
|
cmp r3, #3
|
||||||
|
bne romfsRedirPatchSubstituted1
|
||||||
|
stmfd sp!, {r0-r4, lr}
|
||||||
|
sub sp, sp, #4
|
||||||
|
adr r1, romfsRedirPatchArchiveId
|
||||||
|
mov r0, sp
|
||||||
|
ldr r4, romfsRedirPatchFsMountArchive
|
||||||
|
blx r4
|
||||||
|
mov r3, #0
|
||||||
|
mov r2, #0
|
||||||
|
ldr r1, [sp]
|
||||||
|
adr r0, romfsRedirPatchArchiveName
|
||||||
|
ldr r4, romfsRedirPatchFsRegisterArchive
|
||||||
|
blx r4
|
||||||
|
add sp, sp, #4
|
||||||
|
ldmfd sp!, {r0-r4, lr}
|
||||||
|
b romfsRedirPatchSubstituted1
|
||||||
|
|
||||||
|
@ Check the path passed to iFileOpen.
|
||||||
|
@ If it is trying to access a RomFS file, we try to
|
||||||
|
@ open it from the LayeredFS folder.
|
||||||
|
@ If the file cannot be opened, we just open
|
||||||
|
@ it from its original archive like nothing happened
|
||||||
|
fsRedir:
|
||||||
|
stmfd sp!, {r0-r12, lr}
|
||||||
|
adr r3, romfsRedirPatchRomFsMount
|
||||||
|
bl compare
|
||||||
|
adrne r3, romfsRedirPatchUpdateRomFsMount
|
||||||
|
blne compare
|
||||||
|
bne endRedir
|
||||||
|
sub sp, sp, #0x400
|
||||||
|
pathRedir:
|
||||||
|
stmfd sp!, {r0-r3}
|
||||||
|
add r0, sp, #0x10
|
||||||
|
ldr r3, romfsRedirPatchCustomPath
|
||||||
|
pathRedir_1:
|
||||||
|
ldrb r2, [r3], #1
|
||||||
|
cmp r2, #0
|
||||||
|
strneh r2, [r0], #2
|
||||||
|
bne pathRedir_1
|
||||||
|
pathRedir_2:
|
||||||
|
ldrh r2, [r1], #2
|
||||||
|
cmp r2, #0x3A @ ':'
|
||||||
|
bne pathRedir_2
|
||||||
|
@ Skip a slash if there are two after the mountpoint,
|
||||||
|
@ as some games mistakenly have those
|
||||||
|
ldrh r3, [r1, #2]
|
||||||
|
cmp r3, #0x2F @ '/'
|
||||||
|
pathRedir_3:
|
||||||
|
ldrh r2, [r1], #2
|
||||||
|
strneh r2, [r0], #2
|
||||||
|
cmp r2, #0
|
||||||
|
bne pathRedir_3
|
||||||
|
ldmfd sp!, {r0-r3}
|
||||||
|
mov r1, sp
|
||||||
|
bl romfsRedirPatchSubstituted2
|
||||||
|
add sp, sp, #0x400
|
||||||
|
cmp r0, #0
|
||||||
|
|
||||||
|
endRedir:
|
||||||
|
ldmfd sp!, {r0-r12, lr}
|
||||||
|
moveq r0, #0
|
||||||
|
bxeq lr
|
||||||
|
b romfsRedirPatchSubstituted2
|
||||||
|
|
||||||
|
compare:
|
||||||
|
mov r9, r1
|
||||||
|
add r10, r3, #4
|
||||||
|
loop:
|
||||||
|
ldrb r12, [r3], #1
|
||||||
|
ldrb r11, [r9], #2
|
||||||
|
cmp r11, r12
|
||||||
|
bxne lr
|
||||||
|
cmp r10, r3
|
||||||
|
bne loop
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.pool
|
||||||
|
.balign 4
|
||||||
|
|
||||||
|
.global romfsRedirPatchArchiveName
|
||||||
|
.global romfsRedirPatchFsMountArchive
|
||||||
|
.global romfsRedirPatchFsRegisterArchive
|
||||||
|
.global romfsRedirPatchArchiveId
|
||||||
|
.global romfsRedirPatchRomFsMount
|
||||||
|
.global romfsRedirPatchUpdateRomFsMount
|
||||||
|
.global romfsRedirPatchCustomPath
|
||||||
|
|
||||||
|
romfsRedirPatchArchiveName : .ascii "lf:\0"
|
||||||
|
romfsRedirPatchFsMountArchive : .word 0xdead0005
|
||||||
|
romfsRedirPatchFsRegisterArchive : .word 0xdead0006
|
||||||
|
romfsRedirPatchArchiveId : .word 0xdead0007
|
||||||
|
romfsRedirPatchRomFsMount : .ascii "rom:"
|
||||||
|
romfsRedirPatchUpdateRomFsMount : .word 0xdead0008
|
||||||
|
romfsRedirPatchCustomPath : .word 0xdead0004
|
||||||
|
|
||||||
|
_romfsRedirPatchEnd:
|
||||||
|
|
||||||
|
.global romfsRedirPatchSize
|
||||||
|
romfsRedirPatchSize:
|
||||||
|
.word _romfsRedirPatchEnd - romfsRedirPatch
|
Reference in New Issue
Block a user