diff --git a/ee/elf-loader/Makefile b/ee/elf-loader/Makefile index 70a9f5a63577..e9038d7b64ab 100644 --- a/ee/elf-loader/Makefile +++ b/ee/elf-loader/Makefile @@ -6,7 +6,7 @@ # Licenced under Academic Free License version 2.0 # Review ps2sdk README & LICENSE files for further details. -EE_OBJS = elf.o loader.o +EE_OBJS = elf.o loader.o loader_noreset.o include $(PS2SDKSRC)/Defs.make include $(PS2SDKSRC)/ee/Rules.lib.make @@ -19,16 +19,28 @@ $(PS2SDKSRC)/tools/bin2c/bin/bin2c: $(PS2SDKSRC)/tools/bin2c src/loader/bin/loader.elf: $(MAKEREC) src/loader +src/loader/bin_noreset/loader.elf: + $(MAKEREC) src/loader EE_BIN_DIR=bin_noreset/ EE_OBJS_DIR=obj_noreset/ LOADER_SKIP_IOP_RESET=1 + $(EE_OBJS_DIR)loader.c: src/loader/bin/loader.elf $(PS2SDKSRC)/tools/bin2c/bin/bin2c $(PS2SDKSRC)/tools/bin2c/bin/bin2c $< $@ loader_elf +$(EE_OBJS_DIR)loader_noreset.c: src/loader/bin_noreset/loader.elf $(PS2SDKSRC)/tools/bin2c/bin/bin2c + $(PS2SDKSRC)/tools/bin2c/bin/bin2c $< $@ loader_noreset_elf + $(EE_OBJS_DIR)loader.o: $(EE_OBJS_DIR)loader.c $(DIR_GUARD) $(EE_C_COMPILE) $< -c -o $@ +$(EE_OBJS_DIR)loader_noreset.o: $(EE_OBJS_DIR)loader_noreset.c + $(DIR_GUARD) + $(EE_C_COMPILE) $< -c -o $@ + clean:: $(MAKEREC) src/loader clean + $(MAKEREC) src/loader EE_BIN_DIR=bin_noreset/ EE_OBJS_DIR=obj_noreset/ clean .NOTPARALLEL:: \ $(PS2SDKSRC)/tools/bin2c/bin/bin2c \ - src/loader/bin/loader.elf + src/loader/bin/loader.elf \ + src/loader/bin_noreset/loader.elf diff --git a/ee/elf-loader/include/elf-loader.h b/ee/elf-loader/include/elf-loader.h index f3fea4ea3409..22e735c04965 100644 --- a/ee/elf-loader/include/elf-loader.h +++ b/ee/elf-loader/include/elf-loader.h @@ -50,6 +50,13 @@ extern int LoadELFFromFile(const char *filename, int argc, char *argv[]); */ extern int LoadELFFromFileWithPartition(const char *filename, const char *partition, int argc, char *argv[]); +/** As LoadELFFromFileWithPartition, but the loader does NOT reset the IOP + * before handing off. Storage modules stay resident, so the launched ELF's + * own loader can read from the device it was booted from. The launched ELF + * is responsible for any IOP reset it needs. + */ +extern int LoadELFFromFileWithPartitionNoReset(const char *filename, const char *partition, int argc, char *argv[]); + #ifdef __cplusplus } #endif diff --git a/ee/elf-loader/src/elf.c b/ee/elf-loader/src/elf.c index 18f178446687..d324d2fefac9 100644 --- a/ee/elf-loader/src/elf.c +++ b/ee/elf-loader/src/elf.c @@ -21,6 +21,9 @@ extern u8 loader_elf[]; extern int size_loader_elf; +extern u8 loader_noreset_elf[]; +extern int size_loader_noreset_elf; + // ELF-loading stuff #define ELF_MAGIC 0x464c457f #define ELF_PT_LOAD 1 @@ -54,8 +57,7 @@ static void wipe_bramMem(void) { #endif } -int LoadELFFromFileWithPartition(const char *filename, const char *partition, int argc, char *argv[]) { - u8 *boot_elf; +static int LoadELFFromFileCommon(u8 *boot_elf, const char *filename, const char *partition, int argc, char *argv[]) { elf_header_t *eh; elf_pheader_t *eph; void *pdata; @@ -76,9 +78,8 @@ int LoadELFFromFileWithPartition(const char *filename, const char *partition, in for (i = 0; i < argc; i++) { new_argv[i + 2] = argv[i]; } - - /* NB: LOADER.ELF is embedded */ - boot_elf = (u8 *)loader_elf; + + /* NB: the selected loader stub is embedded */ eh = (elf_header_t *)boot_elf; if (_lw((u32)&eh->ident) != ELF_MAGIC) __builtin_trap(); @@ -105,6 +106,16 @@ int LoadELFFromFileWithPartition(const char *filename, const char *partition, in return ExecPS2((void *)eh->entry, NULL, new_argc, new_argv); } +int LoadELFFromFileWithPartition(const char *filename, const char *partition, int argc, char *argv[]) +{ + return LoadELFFromFileCommon(loader_elf, filename, partition, argc, argv); +} + +int LoadELFFromFileWithPartitionNoReset(const char *filename, const char *partition, int argc, char *argv[]) +{ + return LoadELFFromFileCommon(loader_noreset_elf, filename, partition, argc, argv); +} + int LoadELFFromFile(const char *filename, int argc, char *argv[]) { return LoadELFFromFileWithPartition(filename, NULL, argc, argv); diff --git a/ee/elf-loader/src/loader/Makefile b/ee/elf-loader/src/loader/Makefile index 7ee2e43094c2..88306b12cd60 100644 --- a/ee/elf-loader/src/loader/Makefile +++ b/ee/elf-loader/src/loader/Makefile @@ -21,6 +21,11 @@ ifneq (x$(LOADER_ENABLE_DEBUG_COLORS), x0) EE_CFLAGS += -DLOADER_ENABLE_DEBUG_COLORS endif +# Skip the IOP reset before handing off (keeps storage modules resident so the launched ELF's own loader can still read from the boot device) +ifeq ($(LOADER_SKIP_IOP_RESET), 1) +EE_CFLAGS += -DLOADER_SKIP_IOP_RESET +endif + include $(PS2SDKSRC)/Defs.make include $(PS2SDKSRC)/ee/Rules.bin.make include $(PS2SDKSRC)/ee/Rules.make diff --git a/ee/elf-loader/src/loader/src/loader.c b/ee/elf-loader/src/loader/src/loader.c index 16b6520d098b..c67f14f41a30 100644 --- a/ee/elf-loader/src/loader/src/loader.c +++ b/ee/elf-loader/src/loader/src/loader.c @@ -122,6 +122,7 @@ int main(int argc, char *argv[]) if (ret == 0 && elfdata.epc != 0) { SET_GS_BGCOLOUR(YELLOW_BG); +#ifndef LOADER_SKIP_IOP_RESET // Let's reset IOP because ELF was already loaded in memory while(!SifIopReset(NULL, 0)){}; while (!SifIopSync()) {}; @@ -136,6 +137,7 @@ int main(int argc, char *argv[]) SifLoadModule("rom0:MCSERV", 0, NULL); SifLoadFileExit(); sceSifExitRpc(); +#endif SET_GS_BGCOLOUR(BROWN_BG);