Refactor k11 main hook
Much less error-prone now.
This commit is contained in:
parent
43f3c84316
commit
a16d1ebe33
18
Makefile
18
Makefile
@ -12,16 +12,31 @@ include $(DEVKITARM)/base_tools
|
|||||||
|
|
||||||
name := Luma3DS
|
name := Luma3DS
|
||||||
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/i')
|
revision := $(shell git describe --tags --match v[0-9]* --abbrev=8 | sed 's/-[0-9]*-g/-/i')
|
||||||
|
version_major := $(shell git describe --tags --match v[0-9]* | cut -c2- | cut -f1 -d- | cut -f1 -d.)
|
||||||
|
version_minor := $(shell git describe --tags --match v[0-9]* | cut -c2- | cut -f1 -d- | cut -f2 -d.)
|
||||||
|
version_build := $(shell git describe --tags --match v[0-9]* | cut -c2- | cut -f1 -d- | cut -f3 -d.)
|
||||||
commit := $(shell git rev-parse --short=8 HEAD)
|
commit := $(shell git rev-parse --short=8 HEAD)
|
||||||
|
is_release := 0
|
||||||
|
|
||||||
ifeq ($(strip $(revision)),)
|
ifeq ($(strip $(revision)),)
|
||||||
revision := v0.0.0-0
|
revision := v0.0.0-0
|
||||||
|
version_major := 0
|
||||||
|
version_minor := 0
|
||||||
|
version_build := 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(strip $(commit)),)
|
ifeq ($(strip $(commit)),)
|
||||||
commit := 0
|
commit := 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(version_build)),)
|
||||||
|
version_build := 0
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(shell git describe --tags --match v[0-9]* | grep -)),)
|
||||||
|
is_release := 1
|
||||||
|
endif
|
||||||
|
|
||||||
dir_source := source
|
dir_source := source
|
||||||
dir_patches := patches
|
dir_patches := patches
|
||||||
dir_arm11 := arm11
|
dir_arm11 := arm11
|
||||||
@ -121,7 +136,8 @@ $(dir_build)/%.bin: $(dir_patches)/%.s
|
|||||||
|
|
||||||
$(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="\"$(name) $(revision) configuration\""
|
$(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 += -DVERSION_MAJOR="$(version_major)" -DVERSION_MINOR="$(version_minor)"\
|
||||||
|
-DVERSION_BUILD="$(version_build)" -DISRELEASE="$(is_release)" -DCOMMIT_HASH="0x$(commit)"
|
||||||
$(dir_build)/firm.o: $(dir_build)/modules.bin
|
$(dir_build)/firm.o: $(dir_build)/modules.bin
|
||||||
$(dir_build)/firm.o: CFLAGS += -DLUMA_SECTION0_SIZE="$(shell du -b $(dir_build)/modules.bin | cut -f1)"
|
$(dir_build)/firm.o: CFLAGS += -DLUMA_SECTION0_SIZE="$(shell du -b $(dir_build)/modules.bin | cut -f1)"
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ bindSGI0:
|
|||||||
; hook __kernel_main to bind SGI0 for own purposes
|
; hook __kernel_main to bind SGI0 for own purposes
|
||||||
push {r0-r4, lr}
|
push {r0-r4, lr}
|
||||||
sub sp, #16 ; 3 args passed through the stack + alignment
|
sub sp, #16 ; 3 args passed through the stack + alignment
|
||||||
ldr r0, [interruptManager]
|
adr r0, parameters
|
||||||
|
ldr r0, [r0, #4]
|
||||||
adr r1, interruptEvent
|
adr r1, interruptEvent
|
||||||
mov r2, #0
|
mov r2, #0
|
||||||
mrc p15, 0, r3, c0, c0, 5
|
mrc p15, 0, r3, c0, c0, 5
|
||||||
@ -17,7 +18,7 @@ bindSGI0:
|
|||||||
str r4, [sp, #4]
|
str r4, [sp, #4]
|
||||||
str r4, [sp, #8]
|
str r4, [sp, #8]
|
||||||
|
|
||||||
ldr r12, [InterruptManager_mapInterrupt]
|
ldr r12, [InterruptManager_MapInterrupt]
|
||||||
blx r12
|
blx r12
|
||||||
cmp r0, #0
|
cmp r0, #0
|
||||||
blt .
|
blt .
|
||||||
@ -28,7 +29,7 @@ bindSGI0:
|
|||||||
executeCustomHandler:
|
executeCustomHandler:
|
||||||
push {r4, lr}
|
push {r4, lr}
|
||||||
mrs r4, cpsr
|
mrs r4, cpsr
|
||||||
adr r0, customHandler
|
adr r0, parameters
|
||||||
bl convertVAToPA
|
bl convertVAToPA
|
||||||
orr r0, #(1 << 31)
|
orr r0, #(1 << 31)
|
||||||
ldr r12, [r0]
|
ldr r12, [r0]
|
||||||
@ -54,20 +55,12 @@ convertVAToPA:
|
|||||||
|
|
||||||
.pool
|
.pool
|
||||||
|
|
||||||
; Result InterruptManager::mapInterrupt(InterruptManager *this, InterruptEvent *iEvent, u32 interruptID, u32 coreID, s32 priority, bool willBeMasked, bool isLevelHighActive);
|
; Result InterruptManager::MapInterrupt(InterruptManager *this, InterruptEvent *iEvent, u32 interruptID, u32 coreID, s32 priority, bool willBeMasked, bool isLevelHighActive);
|
||||||
InterruptManager_mapInterrupt: .ascii "bind"
|
InterruptManager_MapInterrupt: .ascii "bind"
|
||||||
|
|
||||||
_vtable: .word executeCustomHandler
|
_vtable: .word executeCustomHandler
|
||||||
interruptEvent: .word _vtable
|
interruptEvent: .word _vtable
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
customHandler: .ascii "hdlr"
|
|
||||||
interruptManager: .word 0
|
|
||||||
L2MMUTable: .word 0
|
|
||||||
funcs: .word 0,0,0
|
|
||||||
TTBCR: .word 0
|
|
||||||
L1MMUTableAddrs: .word 0,0,0,0
|
|
||||||
kernelVersion: .word 0
|
|
||||||
CFWInfo: .word 0,0,0,0
|
|
||||||
|
|
||||||
.close
|
.close
|
||||||
|
@ -92,6 +92,38 @@ void installMMUHook(u8 *pos, u32 size, u8 **freeK11Space)
|
|||||||
|
|
||||||
void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space)
|
void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space)
|
||||||
{
|
{
|
||||||
|
//The parameters to be passed on to the kernel ext
|
||||||
|
//Please keep that in sync with the definition in kernel_extension_setup.c and kernel_extension/main.c
|
||||||
|
struct KExtParameters
|
||||||
|
{
|
||||||
|
void (*SGI0HandlerCallback)(struct KExtParameters *, u32 *);
|
||||||
|
void *interruptManager;
|
||||||
|
u32 *L2MMUTable; //bit31 mapping
|
||||||
|
|
||||||
|
void (*initFPU)(void);
|
||||||
|
void (*mcuReboot)(void);
|
||||||
|
void (*coreBarrier)(void);
|
||||||
|
|
||||||
|
u32 TTBCR;
|
||||||
|
u32 L1MMUTableAddrs[4];
|
||||||
|
|
||||||
|
u32 kernelVersion;
|
||||||
|
|
||||||
|
struct CfwInfo
|
||||||
|
{
|
||||||
|
char magic[4];
|
||||||
|
|
||||||
|
u8 versionMajor;
|
||||||
|
u8 versionMinor;
|
||||||
|
u8 versionBuild;
|
||||||
|
u8 flags;
|
||||||
|
|
||||||
|
u32 commitHash;
|
||||||
|
|
||||||
|
u32 config;
|
||||||
|
} __attribute__((packed)) info;
|
||||||
|
};
|
||||||
|
|
||||||
const u8 pattern[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA};
|
const u8 pattern[] = {0x00, 0x00, 0xA0, 0xE1, 0x03, 0xF0, 0x20, 0xE3, 0xFD, 0xFF, 0xFF, 0xEA};
|
||||||
|
|
||||||
u32 *off = (u32 *)memsearch(pos, pattern, size, 12);
|
u32 *off = (u32 *)memsearch(pos, pattern, size, 12);
|
||||||
@ -112,55 +144,38 @@ void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 *
|
|||||||
offset = offset << 6 >> 6; //sign extend
|
offset = offset << 6 >> 6; //sign extend
|
||||||
offset += 8;
|
offset += 8;
|
||||||
|
|
||||||
u32 InterruptManager_mapInterrupt = baseK11VA + ((u8 *)off - pos) + offset;
|
u32 InterruptManager_MapInterrupt = baseK11VA + ((u8 *)off - pos) + offset;
|
||||||
u32 interruptManager = *(u32 *)(off - 4 + (*(off - 6) & 0xFFF) / 4);
|
u32 interruptManager = *(u32 *)(off - 4 + (*(off - 6) & 0xFFF) / 4);
|
||||||
|
|
||||||
off = (u32 *)memsearch(*freeK11Space, "bind", k11MainHook_bin_size, 4);
|
off = (u32 *)memsearch(*freeK11Space, "bind", k11MainHook_bin_size, 4);
|
||||||
|
|
||||||
*off++ = InterruptManager_mapInterrupt;
|
off[0] = InterruptManager_MapInterrupt;
|
||||||
|
|
||||||
//Relocate stuff
|
//Relocate stuff
|
||||||
*off++ += relocBase;
|
off[1] += relocBase;
|
||||||
*off++ += relocBase;
|
off[2] += relocBase;
|
||||||
off++;
|
|
||||||
*off++ = interruptManager;
|
|
||||||
|
|
||||||
off += 10;
|
struct KExtParameters *p = (struct KExtParameters *)(off + 3);
|
||||||
|
memset(p, 0, sizeof(struct KExtParameters));
|
||||||
|
memcpy((void *)&p->SGI0HandlerCallback, "hdlr", 4);
|
||||||
|
|
||||||
struct CfwInfo
|
p->interruptManager = (void *)interruptManager;
|
||||||
{
|
|
||||||
char magic[4];
|
|
||||||
|
|
||||||
u8 versionMajor;
|
struct CfwInfo *info = &p->info;
|
||||||
u8 versionMinor;
|
|
||||||
u8 versionBuild;
|
|
||||||
u8 flags;
|
|
||||||
|
|
||||||
u32 commitHash;
|
|
||||||
|
|
||||||
u32 config;
|
|
||||||
} __attribute__((packed)) *info = (struct CfwInfo *)off;
|
|
||||||
|
|
||||||
const char *rev = REVISION;
|
|
||||||
memcpy(&info->magic, "LUMA", 4);
|
memcpy(&info->magic, "LUMA", 4);
|
||||||
info->commitHash = COMMIT_HASH;
|
info->commitHash = COMMIT_HASH;
|
||||||
info->config = configData.config;
|
info->config = configData.config;
|
||||||
info->versionMajor = (u8)(rev[1] - '0');
|
info->versionMajor = VERSION_MAJOR;
|
||||||
info->versionMinor = (u8)(rev[3] - '0');
|
info->versionMinor = VERSION_MINOR;
|
||||||
|
info->versionBuild = VERSION_BUILD;
|
||||||
|
|
||||||
if(rev[4] == '.')
|
if(ISRELEASE) info->flags = 1;
|
||||||
info->versionBuild = (u8)(rev[5] - '0');
|
|
||||||
|
|
||||||
const char *revpos;
|
|
||||||
for(revpos = rev + 4; *revpos != 0 && *revpos != '-'; revpos++);
|
|
||||||
bool isRelease = *revpos != '-';
|
|
||||||
|
|
||||||
if(isRelease) info->flags = 1;
|
|
||||||
if(ISN3DS) info->flags |= 1 << 4;
|
if(ISN3DS) info->flags |= 1 << 4;
|
||||||
if(isSafeMode) info->flags |= 1 << 5;
|
if(isSafeMode) info->flags |= 1 << 5;
|
||||||
if(isSdMode) info->flags |= 1 << 6;
|
if(isSdMode) info->flags |= 1 << 6;
|
||||||
|
|
||||||
(*freeK11Space) += k11MainHook_bin_size;
|
(*freeK11Space) += (k11MainHook_bin_size + sizeof(struct KExtParameters));
|
||||||
|
(*freeK11Space) += 4 - ((u32)(*freeK11Space) % 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void installSvcConnectToPortInitHook(u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space)
|
void installSvcConnectToPortInitHook(u32 *arm11SvcTable, u32 *arm11ExceptionsPage, u8 **freeK11Space)
|
||||||
|
Reference in New Issue
Block a user