From a16d1ebe33526eafc4a203fbf867e5897487c0b6 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Wed, 7 Jun 2017 22:13:05 +0200 Subject: [PATCH] Refactor k11 main hook Much less error-prone now. --- Makefile | 18 ++++++++- patches/k11MainHook.s | 19 +++------- source/patches.c | 85 +++++++++++++++++++++++++------------------ 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index bd17bf4..471cdd7 100644 --- a/Makefile +++ b/Makefile @@ -12,16 +12,31 @@ include $(DEVKITARM)/base_tools name := Luma3DS 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) +is_release := 0 ifeq ($(strip $(revision)),) revision := v0.0.0-0 + version_major := 0 + version_minor := 0 + version_build := 0 endif ifeq ($(strip $(commit)),) commit := 0 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_patches := patches 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)/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: CFLAGS += -DLUMA_SECTION0_SIZE="$(shell du -b $(dir_build)/modules.bin | cut -f1)" diff --git a/patches/k11MainHook.s b/patches/k11MainHook.s index 1791c76..e0c5ffa 100644 --- a/patches/k11MainHook.s +++ b/patches/k11MainHook.s @@ -7,7 +7,8 @@ bindSGI0: ; hook __kernel_main to bind SGI0 for own purposes push {r0-r4, lr} sub sp, #16 ; 3 args passed through the stack + alignment - ldr r0, [interruptManager] + adr r0, parameters + ldr r0, [r0, #4] adr r1, interruptEvent mov r2, #0 mrc p15, 0, r3, c0, c0, 5 @@ -17,7 +18,7 @@ bindSGI0: str r4, [sp, #4] str r4, [sp, #8] - ldr r12, [InterruptManager_mapInterrupt] + ldr r12, [InterruptManager_MapInterrupt] blx r12 cmp r0, #0 blt . @@ -28,7 +29,7 @@ bindSGI0: executeCustomHandler: push {r4, lr} mrs r4, cpsr - adr r0, customHandler + adr r0, parameters bl convertVAToPA orr r0, #(1 << 31) ldr r12, [r0] @@ -54,20 +55,12 @@ convertVAToPA: .pool -; Result InterruptManager::mapInterrupt(InterruptManager *this, InterruptEvent *iEvent, u32 interruptID, u32 coreID, s32 priority, bool willBeMasked, bool isLevelHighActive); -InterruptManager_mapInterrupt: .ascii "bind" +; Result InterruptManager::MapInterrupt(InterruptManager *this, InterruptEvent *iEvent, u32 interruptID, u32 coreID, s32 priority, bool willBeMasked, bool isLevelHighActive); +InterruptManager_MapInterrupt: .ascii "bind" _vtable: .word executeCustomHandler interruptEvent: .word _vtable 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 diff --git a/source/patches.c b/source/patches.c index 0336446..df193ee 100644 --- a/source/patches.c +++ b/source/patches.c @@ -92,10 +92,42 @@ void installMMUHook(u8 *pos, u32 size, 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}; u32 *off = (u32 *)memsearch(pos, pattern, size, 12); - // look for cpsie i and place our function call in the nop 2 instructions before + //look for cpsie i and place our function call in the nop 2 instructions before while(*off != 0xF1080080) off--; off -= 2; @@ -109,58 +141,41 @@ void installK11MainHook(u8 *pos, u32 size, bool isSafeMode, u32 baseK11VA, u32 * off--; signed int offset = (*off & 0xFFFFFF) << 2; - offset = offset << 6 >> 6; // sign extend + offset = offset << 6 >> 6; //sign extend 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); off = (u32 *)memsearch(*freeK11Space, "bind", k11MainHook_bin_size, 4); - *off++ = InterruptManager_mapInterrupt; + off[0] = InterruptManager_MapInterrupt; - // Relocate stuff - *off++ += relocBase; - *off++ += relocBase; - off++; - *off++ = interruptManager; + //Relocate stuff + off[1] += relocBase; + off[2] += relocBase; - off += 10; + struct KExtParameters *p = (struct KExtParameters *)(off + 3); + memset(p, 0, sizeof(struct KExtParameters)); + memcpy((void *)&p->SGI0HandlerCallback, "hdlr", 4); - struct CfwInfo - { - char magic[4]; + p->interruptManager = (void *)interruptManager; - u8 versionMajor; - u8 versionMinor; - u8 versionBuild; - u8 flags; - - u32 commitHash; - - u32 config; - } __attribute__((packed)) *info = (struct CfwInfo *)off; - - const char *rev = REVISION; + struct CfwInfo *info = &p->info; memcpy(&info->magic, "LUMA", 4); info->commitHash = COMMIT_HASH; info->config = configData.config; - info->versionMajor = (u8)(rev[1] - '0'); - info->versionMinor = (u8)(rev[3] - '0'); + info->versionMajor = VERSION_MAJOR; + info->versionMinor = VERSION_MINOR; + info->versionBuild = VERSION_BUILD; - if(rev[4] == '.') - 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(ISRELEASE) info->flags = 1; if(ISN3DS) info->flags |= 1 << 4; if(isSafeMode) info->flags |= 1 << 5; 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)