fusee: change meso loading to parse INI from Nintendo's kernel

This commit is contained in:
Michael Scire 2020-08-20 14:52:24 -07:00 committed by SciresM
parent 99b5458539
commit ff9b9fc5ff
5 changed files with 40 additions and 10 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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();

View file

@ -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);

View file

@ -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