diff --git a/Makefile b/Makefile index a31c044f8..ce36a022c 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ ifneq (, $(strip $(shell git status --porcelain 2>/dev/null))) AMSREV := $(AMSREV)-dirty endif -COMPONENTS := fusee stratosphere exosphere thermosphere troposphere libraries +COMPONENTS := fusee stratosphere mesosphere exosphere thermosphere troposphere libraries all: $(COMPONENTS) @@ -20,13 +20,16 @@ exosphere: thermosphere stratosphere: exosphere libraries $(MAKE) -C stratosphere all +mesosphere: exosphere libraries + $(MAKE) -C mesosphere all + troposphere: stratosphere $(MAKE) -C troposphere all sept: exosphere $(MAKE) -C sept all -fusee: exosphere stratosphere sept +fusee: exosphere mesosphere stratosphere sept $(MAKE) -C $@ all libraries: diff --git a/fusee/fusee-secondary/Makefile b/fusee/fusee-secondary/Makefile index 243799530..8681bc3cf 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/lp0fw $(AMS)/exosphere/rebootstub \ $(AMS)/thermosphere $(AMS)/fusee/fusee-primary $(AMS)/sept/sept-primary \ - $(AMS)/sept/sept-secondary $(AMS)/emummc $(KIPDIRS) + $(AMS)/sept/sept-secondary $(AMS)/emummc $(AMS)/mesosphere/kernel_ldr $(KIPDIRS) export DEPSDIR := $(CURDIR)/$(BUILD) @@ -100,7 +100,7 @@ KIPFILES := loader.kip pm.kip sm.kip ams_mitm.kip spl.kip boot.kip BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) fusee-primary.bin \ exosphere.bin lp0fw.bin rebootstub.bin thermosphere.bin splash_screen.bmp \ sept-primary.bin sept-secondary_00.enc sept-secondary_01.enc emummc.kip \ - $(KIPFILES) + kernel_ldr.bin $(KIPFILES) #--------------------------------------------------------------------------------- # use CXX for linking C++ projects, CC for standard C @@ -151,11 +151,14 @@ check_thermosphere: check_stratosphere: check_libraries @$(MAKE) -C $(AMS)/stratosphere all +check_mesosphere: check_libraries + @$(MAKE) -C $(AMS)/mesosphere all + check_libraries: @$(MAKE) -C $(AMS)/libraries all -$(BUILD): check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_libraries check_stratosphere +$(BUILD): check_fusee_primary check_exosphere check_sept check_emummc check_thermosphere check_libraries check_stratosphere check_mesosphere @[ -d $@ ] || mkdir -p $@ @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile @@ -166,6 +169,7 @@ clean: @$(MAKE) -C $(AMS)/exosphere clean @$(MAKE) -C $(AMS)/thermosphere clean @$(MAKE) -C $(AMS)/libraries clean + @$(MAKE) -C $(AMS)/mesosphere clean @$(MAKE) -C $(AMS)/stratosphere clean @$(MAKE) -C $(AMS)/sept clean @$(MAKE) -C $(AMS)/emummc clean diff --git a/fusee/fusee-secondary/linker.ld b/fusee/fusee-secondary/linker.ld index 54a44b73d..eac98afcc 100644 --- a/fusee/fusee-secondary/linker.ld +++ b/fusee/fusee-secondary/linker.ld @@ -250,4 +250,6 @@ SECTIONS PROVIDE(__thermosphere_bin_size__ = thermosphere_bin_end - thermosphere_bin); PROVIDE(__emummc_kip_start__ = emummc_kip - __start__); PROVIDE(__emummc_kip_size__ = emummc_kip_end - emummc_kip); + PROVIDE(__kernel_ldr_bin_start__ = kernel_ldr_bin - __start__); + PROVIDE(__kernel_ldr_bin_size__ = kernel_ldr_bin_end - kernel_ldr_bin); } diff --git a/fusee/fusee-secondary/src/kernel_patches.c b/fusee/fusee-secondary/src/kernel_patches.c index a8b3cb54c..40336fcf5 100644 --- a/fusee/fusee-secondary/src/kernel_patches.c +++ b/fusee/fusee-secondary/src/kernel_patches.c @@ -21,6 +21,12 @@ #include "kernel_patches.h" #include "ips.h" +#define u8 uint8_t +#define u32 uint32_t +#include "kernel_ldr_bin.h" +#undef u8 +#undef u32 + #define MAKE_BRANCH(a, o) 0x14000000 | ((((o) - (a)) >> 2) & 0x3FFFFFF) #define MAKE_NOP 0xD503201F @@ -839,12 +845,12 @@ const kernel_info_t *get_kernel_info(void *kernel, size_t size) { return NULL; } -void package2_patch_kernel(void *_kernel, size_t size, bool is_sd_kernel, void **out_ini1) { - const kernel_info_t *kernel_info = get_kernel_info(_kernel, size); +void package2_patch_kernel(void *_kernel, size_t *kernel_size, bool is_sd_kernel, void **out_ini1) { + const kernel_info_t *kernel_info = get_kernel_info(_kernel, *kernel_size); *out_ini1 = NULL; /* Apply IPS patches. */ - apply_kernel_ips_patches(_kernel, size); + apply_kernel_ips_patches(_kernel, *kernel_size); if (kernel_info == NULL && !is_sd_kernel) { /* Should this be fatal? */ @@ -856,8 +862,16 @@ void package2_patch_kernel(void *_kernel, size_t size, bool is_sd_kernel, void * } if (kernel_info->embedded_ini_offset != 0) { + /* Copy in our kernel loader. */ + 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); + + /* Update size. */ + *kernel_size = kernel_ldr_offset + kernel_ldr_bin_size; + + /* Set output INI ptr. */ *out_ini1 = (void *)((uintptr_t)_kernel + kernel_info->embedded_ini_offset); - *((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr)) = (uint64_t)size; + *((volatile uint64_t *)((uintptr_t)_kernel + kernel_info->embedded_ini_ptr)) = (uint64_t)*kernel_size; } /* Apply hooks and patches. */ @@ -882,7 +896,7 @@ void package2_patch_kernel(void *_kernel, size_t size, bool is_sd_kernel, void * fatal_error("kernel_patcher: insufficient space to apply patches!\n"); } - uint8_t *pattern_loc = search_pattern(kernel, size, kernel_info->patches[i].pattern, kernel_info->patches[i].pattern_size); + uint8_t *pattern_loc = search_pattern(kernel, *kernel_size, kernel_info->patches[i].pattern, kernel_info->patches[i].pattern_size); if (pattern_loc == NULL) { /* TODO: Should we print an error/abort here? */ continue; diff --git a/fusee/fusee-secondary/src/kernel_patches.h b/fusee/fusee-secondary/src/kernel_patches.h index 60893aed6..c98bad115 100644 --- a/fusee/fusee-secondary/src/kernel_patches.h +++ b/fusee/fusee-secondary/src/kernel_patches.h @@ -13,12 +13,12 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #ifndef FUSEE_KERNEL_PATCHES_H #define FUSEE_KERNEL_PATCHES_H #include "utils.h" -void package2_patch_kernel(void *kernel, size_t kernel_size, bool is_sd_kernel, void **out_ini1); +void package2_patch_kernel(void *kernel, size_t *kernel_size, bool is_sd_kernel, void **out_ini1); #endif \ No newline at end of file diff --git a/fusee/fusee-secondary/src/package2.c b/fusee/fusee-secondary/src/package2.c index 4750c8d3b..d074249fc 100644 --- a/fusee/fusee-secondary/src/package2.c +++ b/fusee/fusee-secondary/src/package2.c @@ -87,7 +87,7 @@ void package2_rebuild_and_copy(package2_header_t *package2, uint32_t target_firm } /* Perform any patches we want to the NX kernel. */ - package2_patch_kernel(kernel, kernel_size, is_sd_kernel, (void *)&orig_ini1); + package2_patch_kernel(kernel, &kernel_size, is_sd_kernel, (void *)&orig_ini1); /* Ensure we know where embedded INI is if present, and we don't if not. */ if ((target_firmware < ATMOSPHERE_TARGET_FIRMWARE_800 && orig_ini1 != NULL) || diff --git a/fusee/fusee-secondary/src/start.s b/fusee/fusee-secondary/src/start.s index 556e7bbdb..857933f89 100644 --- a/fusee/fusee-secondary/src/start.s +++ b/fusee/fusee-secondary/src/start.s @@ -94,6 +94,8 @@ _metadata: #define CONTENT_TYPE_KIP 6 #define CONTENT_TYPE_BMP 7 #define CONTENT_TYPE_EMC 8 +#define CONTENT_TYPE_KLD 9 +#define CONTENT_TYPE_KRN 10 _content_headers: /* ams_mitm content header */ @@ -208,6 +210,14 @@ _content_headers: .asciz "emummc" .align 5 +/* kernel_ldr content header */ +.word __kernel_ldr_bin_start__ +.word __kernel_ldr_bin_size__ +.word CONTENT_TYPE_KLD +.word 0xCCCCCCCC +.asciz "kernel_ldr" +.align 5 + /* splash_screen content header */ .word __splash_screen_bmp_start__ .word __splash_screen_bmp_size__ diff --git a/mesosphere/Makefile b/mesosphere/Makefile new file mode 100644 index 000000000..a0f8875d3 --- /dev/null +++ b/mesosphere/Makefile @@ -0,0 +1,12 @@ +MODULES := kernel_ldr + +SUBFOLDERS := $(MODULES) + +TOPTARGETS := all clean + +$(TOPTARGETS): $(SUBFOLDERS) + +$(SUBFOLDERS): + $(MAKE) -C $@ $(MAKECMDGOALS) + +.PHONY: $(TOPTARGETS) $(SUBFOLDERS) diff --git a/mesosphere/kernel_ldr/kernel_ldr.ld b/mesosphere/kernel_ldr/kernel_ldr.ld index 2a59db15c..74d739cbd 100644 --- a/mesosphere/kernel_ldr/kernel_ldr.ld +++ b/mesosphere/kernel_ldr/kernel_ldr.ld @@ -151,7 +151,7 @@ SECTIONS *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) - . = ALIGN(8); + . = ALIGN(16); /* Reserve space for the stack */ __stack_start = .;