From ff9b9fc5ff9316ab1393778e07d78f2717a205f5 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Thu, 20 Aug 2020 14:52:24 -0700 Subject: [PATCH] fusee: change meso loading to parse INI from Nintendo's kernel --- fusee/fusee-secondary/Makefile | 4 ++-- fusee/fusee-secondary/src/kernel_patches.c | 5 ----- fusee/fusee-secondary/src/nxboot.c | 26 +++++++++++++++++++++- fusee/fusee-secondary/src/package2.c | 13 ++++++++++- fusee/fusee-secondary/src/package2.h | 2 +- 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/fusee/fusee-secondary/Makefile b/fusee/fusee-secondary/Makefile index 51a408be4..c8caba6ce 100644 --- a/fusee/fusee-secondary/Makefile +++ b/fusee/fusee-secondary/Makefile @@ -89,7 +89,7 @@ export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ $(AMS)/exosphere $(AMS)/exosphere/warmboot $(AMS)/exosphere/program/rebootstub \ $(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \ - $(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere/kernel_ldr $(KIPDIRS) + $(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere $(AMS)/mesosphere/kernel_ldr $(KIPDIRS) export DEPSDIR := $(CURDIR)/$(BUILD) @@ -100,7 +100,7 @@ KIPFILES := loader.kip ncm.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \ exosphere.bin warmboot.bin rebootstub.bin thermosphere.bin splash_screen.bmp \ sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \ - sept-secondary_dev_00.enc sept-secondary_dev_01.enc kernel_ldr.bin $(KIPFILES) + sept-secondary_dev_00.enc sept-secondary_dev_01.enc mesosphere.bin kernel_ldr.bin $(KIPFILES) #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C diff --git a/fusee/fusee-secondary/src/kernel_patches.c b/fusee/fusee-secondary/src/kernel_patches.c index fc2451052..f61bf7e95 100644 --- a/fusee/fusee-secondary/src/kernel_patches.c +++ b/fusee/fusee-secondary/src/kernel_patches.c @@ -963,11 +963,6 @@ void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel } if (kernel_info == NULL && is_sd_kernel) { - /* If the kernel is mesosphere, patch it. */ - if (*(volatile uint32_t *)((uintptr_t)_kernel + 4) == 0x3053534D) { - *out_ini1 = (void *)((uintptr_t)_kernel + *(volatile uint32_t *)((uintptr_t)_kernel + 8)); - *(volatile uint64_t *)((uintptr_t)_kernel + 8) = (uint64_t)*kernel_size; - } return; } diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index 7a8519208..b333157c0 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -633,6 +633,8 @@ uint32_t nxboot_main(void) { void *warmboot_memaddr; void *package1loader; size_t package1loader_size; + void *mesosphere; + size_t mesosphere_size; void *emummc; size_t emummc_size; uint32_t available_revision; @@ -928,6 +930,28 @@ uint32_t nxboot_main(void) { pmc->scratch1 = (uint32_t)warmboot_memaddr; } + /* Configure mesosphere. */ + /* TODO: Support non-SD/embedded mesosphere. */ + { + size_t sd_meso_size = get_file_size("atmosphere/mesosphere.bin"); + if (sd_meso_size != 0) { + if (sd_meso_size > PACKAGE2_SIZE_MAX) { + fatal_error("Error: atmosphere/kernel.bin is too large!\n"); + } + mesosphere = malloc(sd_meso_size); + if (mesosphere == NULL) { + fatal_error("Error: failed to allocate mesosphere!\n"); + } + if (read_from_file(mesosphere, sd_meso_size, "atmosphere/mesosphere.bin") != sd_meso_size) { + fatal_error("Error: failed to read atmosphere/mesosphere.bin!\n"); + } + mesosphere_size = sd_meso_size; + } else { + mesosphere = NULL; + mesosphere_size = 0; + } + } + print(SCREEN_LOG_LEVEL_INFO, "[NXBOOT] Rebuilding package2...\n"); /* Parse stratosphere config. */ @@ -936,7 +960,7 @@ uint32_t nxboot_main(void) { print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT] Configured Stratosphere...\n"); /* Patch package2, adding Thermosphère + custom KIPs. */ - package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware, emummc, emummc_size); + package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware, mesosphere, mesosphere_size, emummc, emummc_size); /* Set detected FS version. */ MAILBOX_EXOSPHERE_CONFIGURATION->emummc_cfg.base_cfg.fs_version = stratosphere_get_fs_version(); diff --git a/fusee/fusee-secondary/src/package2.c b/fusee/fusee-secondary/src/package2.c index 5987dd0f1..00417b720 100644 --- a/fusee/fusee-secondary/src/package2.c +++ b/fusee/fusee-secondary/src/package2.c @@ -44,7 +44,7 @@ static inline size_t align_to_4(size_t s) { return ((s + 3) >> 2) << 2; } -void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *emummc, size_t emummc_size) { +void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *mesosphere, size_t mesosphere_size, void *emummc, size_t emummc_size) { package2_header_t *rebuilt_package2; size_t rebuilt_package2_size; void *kernel; @@ -95,6 +95,17 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm fatal_error("Error: inappropriate kernel embedded ini context"); } + /* Use mesosphere instead of Nintendo's kernel when present. */ + if (mesosphere != NULL && mesosphere_size != 0) { + kernel = mesosphere; + kernel_size = mesosphere_size; + + /* Patch mesosphere to use our rebuilt ini. */ + *(volatile uint64_t *)((uintptr_t)mesosphere + 8) = (uint64_t)mesosphere_size; + + print(SCREEN_LOG_LEVEL_DEBUG, "Using Mesosphere...\n"); + } + print(SCREEN_LOG_LEVEL_DEBUG, "Rebuilding the INI1 section...\n"); if (target_firmware < ATMOSPHERE_TARGET_FIRMWARE_8_0_0) { package2_get_src_section((void *)&orig_ini1, package2, PACKAGE2_SECTION_INI1); diff --git a/fusee/fusee-secondary/src/package2.h b/fusee/fusee-secondary/src/package2.h index e2f89f3a4..d77eb2094 100644 --- a/fusee/fusee-secondary/src/package2.h +++ b/fusee/fusee-secondary/src/package2.h @@ -94,6 +94,6 @@ static inline uint8_t package2_meta_get_header_version(const package2_meta_t *me return (uint8_t)((metadata->ctr_dwords[1] ^ (metadata->ctr_dwords[1] >> 16) ^ (metadata->ctr_dwords[1] >> 24)) & 0xFF); } -void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *emummc, size_t emummc_size); +void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firmware, void *mesosphere, size_t mesosphere_size, void *emummc, size_t emummc_size); #endif