diff --git a/fusee/fusee-secondary/src/kernel_patches.c b/fusee/fusee-secondary/src/kernel_patches.c index 6408c14c1..f61bf7e95 100644 --- a/fusee/fusee-secondary/src/kernel_patches.c +++ b/fusee/fusee-secondary/src/kernel_patches.c @@ -971,12 +971,6 @@ void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel const uint32_t kernel_ldr_offset = *((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr + 8)); memcpy((void *)((uintptr_t)_kernel + kernel_ldr_offset), kernel_ldr_bin, kernel_ldr_bin_size); - /* Set target firmware for our kernel loader. */ - uint32_t *kldr_u32 = (uint32_t *)((uintptr_t)_kernel + kernel_ldr_offset); - if (kldr_u32[1] == 0x30444C4D) { - kldr_u32[2] = target_firmware; - } - /* Update size. */ *kernel_size = kernel_ldr_offset + kernel_ldr_bin_size; diff --git a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp index 7ee9e3b29..e50c9b7f4 100644 --- a/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp +++ b/libraries/libmesosphere/source/board/nintendo/nx/kern_k_device_page_table.cpp @@ -640,15 +640,10 @@ namespace ams::kern::board::nintendo::nx { } bool KDevicePageTable::Compare(const KPageGroup &compare_pg, KDeviceVirtualAddress device_address) const { - bool same_pages = false; - - /* Make a page group. */ + /* Check whether the page group we expect for the virtual address matches the page group we're validating. */ KPageGroup calc_pg(std::addressof(Kernel::GetBlockInfoManager())); - if (R_SUCCEEDED(this->MakePageGroup(std::addressof(calc_pg), device_address, compare_pg.GetNumPages() * PageSize))) { - same_pages = calc_pg.IsEquivalentTo(compare_pg); - } - - return same_pages; + return (R_SUCCEEDED(this->MakePageGroup(std::addressof(calc_pg), device_address, compare_pg.GetNumPages() * PageSize))) && + calc_pg.IsEquivalentTo(compare_pg); } Result KDevicePageTable::Map(size_t *out_mapped_size, const KPageGroup &pg, KDeviceVirtualAddress device_address, ams::svc::MemoryPermission device_perm, bool refresh_mappings) { diff --git a/mesosphere/kernel/source/arch/arm64/init/start.s b/mesosphere/kernel/source/arch/arm64/init/start.s index 4114cc300..f4a6d1bde 100644 --- a/mesosphere/kernel/source/arch/arm64/init/start.s +++ b/mesosphere/kernel/source/arch/arm64/init/start.s @@ -94,6 +94,18 @@ core0_el2: core0_el1: bl _ZN3ams4kern4init19DisableMmuAndCachesEv + /* Get the target firmware from exosphere. */ + LOAD_IMMEDIATE_32(w0, 0xC3000004) + mov w1, #65000 + smc #1 + cmp x0, #0 +0: + b.ne 0b + + /* Store the target firmware. */ + adr x0, __metadata_target_firmware + str w1, [x0] + /* We want to invoke kernel loader. */ adr x0, _start adr x1, __metadata_kernel_layout @@ -102,14 +114,7 @@ core0_el1: LOAD_FROM_LABEL(x3, __metadata_kernelldr_offset) add x3, x0, x3 - /* If kernelldr is ours, set its target firmware. */ - ldr w4, [x3, #4] - LOAD_IMMEDIATE_32(w5, 0x30444C4D) - cmp w4, w5 - b.ne 1f - LOAD_FROM_LABEL(x4, __metadata_target_firmware) - str w4, [x3, #8] -1: + /* Invoke kernel loader. */ blr x3 /* At this point kernelldr has been invoked, and we are relocated at a random virtual address. */ diff --git a/mesosphere/kernel_ldr/source/arch/arm64/start.s b/mesosphere/kernel_ldr/source/arch/arm64/start.s index 3a27f40c3..29efffa5c 100644 --- a/mesosphere/kernel_ldr/source/arch/arm64/start.s +++ b/mesosphere/kernel_ldr/source/arch/arm64/start.s @@ -18,6 +18,10 @@ #define cpuactlr_el1 s3_1_c15_c2_0 #define cpuectlr_el1 s3_1_c15_c2_1 +#define LOAD_IMMEDIATE_32(reg, val) \ + mov reg, #(((val) >> 0x00) & 0xFFFF); \ + movk reg, #(((val) >> 0x10) & 0xFFFF), lsl#16 + .section .crt0.text.start, "ax", %progbits .global _start _start: @@ -46,12 +50,25 @@ _main: ldr x17, [x17, #0x10] /* stack top */ add sp, x17, x18 - /* Stack is now set up. */ - /* Apply relocations and call init array for KernelLdr. */ + /* Stack is now set up, so save important state. */ sub sp, sp, #0x30 stp x0, x1, [sp, #0x00] stp x2, x30, [sp, #0x10] stp xzr, xzr, [sp, #0x20] + + /* Get the target firmware from exosphere. */ + LOAD_IMMEDIATE_32(w0, 0xC3000004) + mov w1, #65000 + smc #1 + cmp x0, #0 +0: + b.ne 0b + + /* Store the target firmware. */ + adr x0, __metadata_target_firmware + str w1, [x0] + + /* Apply relocations and call init array for KernelLdr. */ adr x0, _start adr x1, __external_references ldr x1, [x1, #0x18] /* .dynamic. */