diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index d0b41fe..1db9ba8 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -63,6 +63,10 @@ jobs: run: | make release COMMIT_HASH=${GITHUB_SHA::7} BINDIR=PS2_HDD/ HDD=1 ${{ env.DEBUG }} PRINTF=${{ github.event.inputs.name }} + - name: Compile PS2 MBR build + run: | + make release COMMIT_HASH=${GITHUB_SHA::7} BINDIR=PS2_HDD/MBR/ HDD=1 BUILDING_MBR=1 HOMEBREW_IRX=1 ${{ env.DEBUG }} PRINTF=${{ github.event.inputs.name }} + - name: list run: | git ls-files -i --exclude-standard -c diff --git a/.gitignore b/.gitignore index b04b34f..38cf6d1 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ asm/ *.XLF *.dat bin/CONFIG.INI +*.DUMMY +*.RAW +bin/MBR.RAW diff --git a/Makefile b/Makefile index 9b99fc5..0e13842 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,9 @@ BASENAME ?= PS2BBL EE_BIN = $(BINDIR)$(BASENAME).ELF EE_BIN_STRIPPED = $(BINDIR)stripped_$(BASENAME).ELF EE_BIN_PACKED = $(BINDIR)COMPRESSED_$(BASENAME).ELF +MBR_BOOTSTRAP_STRIPPED = $(BINDIR)MBR.ELF +MBR_BOOTSTRAP_HEADERLESS = $(BINDIR)MBR.RAW +MBR_BOOTSTRAP_FINAL = $(BINDIR)MBR.KELF KELFTYPE ?= MC EE_BIN_ENCRYPTED = $(BINDIR)$(BASENAME)_$(KELFTYPE).KELF @@ -69,7 +72,7 @@ EE_LDFLAGS += -Wl,--gc-sections -Wno-sign-compare EE_LIBS += -ldebug -lmc -lpatches EE_INCS += -Iinclude -I$(PS2SDK)/ports/include EE_CFLAGS += -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DPATCHLEVEL=\"$(PATCHLEVEL)\" -DSTATUS=\"$(STATUS)\" - +MBR_KELF_LOAD_ADDR = 0x00100000# DONT TOUCH! # ---{ CONDITIONS }--- # ifneq ($(VERBOSE), 1) @@ -155,6 +158,15 @@ ifeq ($(HDD), 1) KELFTYPE = HDD endif +ifeq ($(BUILDING_MBR), 1) + $(info --- compiling PS2BBL as MBR BOOSTRAP) + HDD=1 + HOMEBREW_IRX=1 + DEV9_NEED=1 + EE_CFLAGS += -DMBR_KELF -G0 + EE_LDFLAGS += -Wl,--gc-sections -Wl,-Ttext -Wl,$(MBR_KELF_LOAD_ADDR) +endif + ifeq ($(UDPTTY), 1) $(info --- UDPTTY enabled) EE_CFLAGS += -DUDPTTY @@ -220,7 +232,7 @@ ifeq ($(PROHBIT_DVD_0100),1) endif # ---{ RECIPES }--- # -.PHONY: greeting debug all clean kelf packed release +.PHONY: greeting debug all clean kelf packed release banner mbr all: $(EE_BIN) ifeq (DEBUG, 1) @@ -248,6 +260,9 @@ clean: @rm -rf $(EE_BIN) $(EE_BIN_STRIPPED) $(EE_BIN_ENCRYPTED) $(EE_BIN_PACKED) @echo - Object folders @rm -rf $(EE_OBJS_DIR) $(EE_ASM_DIR) +ifeq ($(BUILDING_MBR), 1) + @rm -rf $(MBR_GARBAGE) $(MBR_BOOTSTRAP_STRIPPED) $(MBR_BOOTSTRAP_HEADERLESS) $(MBR_BOOTSTRAP_FINAL) +endif @echo "\n" $(EE_BIN_STRIPPED): $(EE_BIN) @@ -265,9 +280,9 @@ endif $(EE_BIN_ENCRYPTED): $(EE_BIN_PACKED) @echo " -- Encrypting ($(KELFTYPE))" ifeq ($(KELFTYPE), MC) - thirdparty/kelftool_dnasload.exe encrypt dnasload $< $@ + $(KELFTOOL_DNAS) encrypt dnasload $< $@ else ifeq ($(KELFTYPE), HDD) - thirdparty/kelftool_dnasload.exe encrypt fhdb $< $@ + $(KELFTOOL_DNAS) encrypt fhdb $< $@ else $(error UNKNOWN KELF TYPE: '$(KELFTYPE)') endif @@ -310,6 +325,27 @@ analize: celan: clean # a repetitive typo when quicktyping kelf: $(EE_BIN_ENCRYPTED) # alias of KELF creation +mbr: +ifneq ($(BUILDING_MBR), 1) + $(error define BUILDING_MBR=1 on make) +endif + @$(MAKE) HDD=1 HOMEBREW_IRX=1 DEV9_NEED=1 $(MBR_BOOTSTRAP_FINAL) banner + +mbr_info: mbr + @echo "--- MBR ELF info: (load adress must be $(MBR_KELF_LOAD_ADDR))" + mips64r5900el-ps2-elf-readelf -l '$(EE_BIN)' | grep "Program Headers:" -A 3 | grep --color=always -e "^" -e "$(MBR_KELF_LOAD_ADDR)" + @echo "--- MBR KELF info:" + $(KELFTOOL_DNAS) decrypt $(MBR_BOOTSTRAP_FINAL) $(MBR_BOOTSTRAP_FINAL).DUMMY + @rm -f $(MBR_BOOTSTRAP_FINAL).DUMMY + +$(MBR_BOOTSTRAP_STRIPPED): $(EE_BIN) + $(EE_STRIP) -s -R .comment -R .gnu.version --strip-unneeded -o $@ $< + +$(MBR_BOOTSTRAP_HEADERLESS): $(MBR_BOOTSTRAP_STRIPPED) + $(EE_OBJCOPY) -O binary -v $< $@ + +$(MBR_BOOTSTRAP_FINAL): $(MBR_BOOTSTRAP_HEADERLESS) + $(KELFTOOL_DNAS) encrypt mbr $< $@ banner: @echo "$$HEADER" @@ -318,3 +354,7 @@ banner: include $(PS2SDK)/samples/Makefile.pref include $(PS2SDK)/samples/Makefile.eeglobal include embed.make + +KELFTOOL_DNAS = thirdparty/kelftool_dnasload.exe +update_kelftool: + wget -q "https://github.com/ps2homebrew/kelftool/releases/download/latest/kelftool.exe" -O $(KELFTOOL_DNAS) \ No newline at end of file diff --git a/include/common.h b/include/common.h index d814f62..3319f87 100644 --- a/include/common.h +++ b/include/common.h @@ -1,5 +1,9 @@ #ifndef COMMONDEF #define COMMONDEF +#define BGR_RED 0x0000FF +#define BGR_WHITE 0xFFFFFF +#define BGR_GREEN 0x00FF00 +#define BGR_YELLOW 0x00FFFF enum { SOURCE_MC0 = 0, diff --git a/mk_kelf.sh b/mk_kelf.sh index ed10665..a4f50e5 100644 --- a/mk_kelf.sh +++ b/mk_kelf.sh @@ -8,6 +8,7 @@ TARGET="PS2BBL_KELF-[$DATE]-[$SHA8]" rm -rf kelf rm -f PS2BBL_KELF.7z mkdir -p kelf/MX4SIO +mkdir -p kelf/MBR echo -- PS2 make clean kelf $* --silent @@ -34,6 +35,11 @@ make clean kelf PSX=1 MX4SIO=1 $* --silent mv bin/PSXBBL_MC.KELF kelf/MX4SIO/XSYSTEM.XLF make clean PSX=1 $* --silent +echo -- MBR +make mbr_info $* --silent +mv bin/MBR.KELF kelf/MBR/MBR.XLF +make clean BUILDING_MBR=1 $* --silent + cp LICENSE kelf/LICENSE.TXT cp README.md kelf/README.md mv kelf/ $TARGET diff --git a/src/main.c b/src/main.c index ae74ed5..b856a3d 100644 --- a/src/main.c +++ b/src/main.c @@ -34,7 +34,12 @@ int HDD_USABLE = 0; int LoadHDDIRX(void); // Load HDD IRXes int MountParty(const char* path); ///processes strings in the format `hdd0:/$PARTITION:pfs:$PATH_TO_FILE/` to mount partition int mnt(const char* path); ///mount partition specified on path -void HDDChecker(); + +/** @brief performs the same integrity checks to the HDD than sony MBR Bootstrap would + * @param verbose wether to run on verbose or not. non verbose only prints the test results that fail + * +*/ +void HDDChecker(int verbose); void poweroffCallback(void *arg); #else //this ensures that when HDD support is not available, loaded ELFs dont have any extra arg... #define MPART NULL @@ -78,8 +83,7 @@ int loadDEV9(void); void loadUDPTTY(); #endif -// For avoiding define NEWLIB_AWARE -void fioInit(); +void fioInit(); // For avoiding define NEWLIB_AWARE #define RBG2INT(R, G, B) ((0 << 24) + (R << 16) + (G << 8) + B) #define IMPORT_BIN2C(_n) \ @@ -152,6 +156,7 @@ void credits(void); void CleanUp(void); int LoadUSBIRX(void); void runOSDNoUpdate(void); +void PrintTemperature(); #ifdef PSX static void InitPSX(); #endif @@ -244,9 +249,9 @@ int main(int argc, char *argv[]) j = LoadUSBIRX(); if (j != 0) { - scr_setfontcolor(0x0000ff); + scr_setfontcolor(BGR_RED); scr_printf("ERROR: could not load USB modules (%d)\n", j); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); #ifdef HAS_EMBEDDED_IRX //we have embedded IRX... something bad is going on if this condition executes. add a wait time for user to know something is wrong sleep(1); #endif @@ -264,7 +269,7 @@ int main(int argc, char *argv[]) #ifdef HDD else if (LoadHDDIRX() < 0) // only load HDD crap if filexio and iomanx are up and running - {scr_setbgcolor(0x0000ff); scr_clear(); sleep(4);} + {scr_setbgcolor(BGR_RED); scr_clear(); sleep(4);} #endif if ((fd = open("rom0:ROMVER", O_RDONLY)) >= 0) { @@ -297,9 +302,9 @@ int main(int argc, char *argv[]) if (OSDConfigLoad() != 0) // Load OSD configuration { // OSD configuration not initialized. Defaults loaded. - scr_setfontcolor(0x00ffff); + scr_setfontcolor(BGR_YELLOW); DPRINTF("OSD Configuration not initialized. Defaults loaded.\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); } DPRINTF("Saving OSD configuration\n"); OSDConfigApply(); @@ -331,6 +336,9 @@ int main(int argc, char *argv[]) EMERGENCY(); } TimerEnd(); +#ifdef MBR_KELF + HDDChecker(0); +#endif DPRINTF("load default settings\n"); SetDefaultSettings(); FILE *fp; @@ -405,15 +413,15 @@ int main(int argc, char *argv[]) fclose(fp); DPRINTF("\tERROR: could not read %d bytes of config file, only %d readed\n", cnf_size, temp); #ifdef REPORT_FATAL_ERRORS - scr_setfontcolor(0x0000ff); + scr_setfontcolor(BGR_RED); scr_printf("\tERROR: could not read %d bytes of config file, only %d readed\n", cnf_size, temp); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); #endif } } else { DPRINTF("\tFailed to allocate %d+1 bytes!\n", cnf_size); #ifdef REPORT_FATAL_ERRORS - scr_setbgcolor(0x0000ff); + scr_setbgcolor(BGR_RED); scr_clear(); scr_printf("\tFailed to allocate %d+1 bytes!\n", cnf_size); sleep(3); @@ -476,7 +484,7 @@ int main(int argc, char *argv[]) scr_clear(); if (GLOBCFG.LOGO_DISP > 1) scr_printf("\n\n\n\n%s", BANNER); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); if (GLOBCFG.LOGO_DISP > 1) scr_printf(BANNER_FOOTER); if (GLOBCFG.LOGO_DISP > 0) { @@ -505,15 +513,15 @@ int main(int argc, char *argv[]) for (j = 0; j < 3; j++) { EXECPATHS[j] = CheckPath(GLOBCFG.KEYPATHS[x + 1][j]); if (exist(EXECPATHS[j])) { - scr_setfontcolor(0x00ff00); + scr_setfontcolor(BGR_GREEN); scr_printf("\tLoading %s\n", EXECPATHS[j]); if (!is_PCMCIA) PadDeinitPads(); RunLoaderElf(EXECPATHS[j], MPART); } else { - scr_setfontcolor(0x00ffff); + scr_setfontcolor(BGR_YELLOW); DPRINTF("%s not found\n", EXECPATHS[j]); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); } } break; @@ -526,7 +534,7 @@ int main(int argc, char *argv[]) for (j = 0; j < 3; j++) { EXECPATHS[j] = CheckPath(GLOBCFG.KEYPATHS[0][j]); if (exist(EXECPATHS[j])) { - scr_setfontcolor(0x00ff00); + scr_setfontcolor(BGR_GREEN); scr_printf("\tLoading %s\n", EXECPATHS[j]); if (!is_PCMCIA) PadDeinitPads(); @@ -537,9 +545,9 @@ int main(int argc, char *argv[]) } scr_clear(); - scr_setfontcolor(0x00ffff); + scr_setfontcolor(BGR_YELLOW); scr_printf("\n\n\tEND OF EXECUTION REACHED\nCould not find any of the default applications\nCheck your config file for the LK_AUTO_E# entries\nOr press a key while logo displays to run the bound application\npress R1+START to enter emergency mode"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); while (1) { sleep(1); PAD = ReadCombinedPadStatus_raw(); @@ -554,7 +562,7 @@ void EMERGENCY(void) { scr_clear(); scr_printf("\n\n\n\tEmergency mode\n\n\t doing infinite attempts to boot\n\t\tmass:/RESCUE.ELF\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); while (1) { scr_printf("."); sleep(1); @@ -587,7 +595,7 @@ char *CheckPath(char *path) } #ifdef HDD if (!strcmp("$HDDCHECKER", path)) - HDDChecker(); + HDDChecker(1); #endif if (!strcmp("$CREDITS", path)) credits(); @@ -874,40 +882,78 @@ int mnt(const char* path) } else DPRINTF("mount successfull on first attemp\n"); return 0; } - -void HDDChecker() +#define HDDCHECKER_PRINTF(x...) scr_printf(x); +void HDDChecker(int verbose) { char ErrorPartName[64]; const char* HEADING = "HDD Diagnosis routine"; int ret = -1; + int success; +#ifdef MBR_KELF + int found_at_least_1_err = 0; +#define ERR_FOUND() if (!verbose) found_at_least_1_err = 1 +#else +#define ERR_FOUND() +#endif scr_clear(); - scr_printf("\n\n%*s%s\n", ((80 - strlen(HEADING)) / 2), "", HEADING); - scr_setfontcolor(0x0000FF); + if (verbose) { + HDDCHECKER_PRINTF("\n\n%*s%s\n", ((80 - strlen(HEADING)) / 2), "", HEADING); + } + scr_setfontcolor(BGR_RED); ret = fileXioDevctl("hdd0:", HDIOC_STATUS, NULL, 0, NULL, 0); - if (ret == 0 || ret == 1) scr_setfontcolor(0x00FF00); - if (ret != 3) + DPRINTF("\t\t - HDD CONNECTION STATUS: %d\n", ret); + success = (ret == 0 || ret == 1); + if (success) {scr_setfontcolor(BGR_GREEN);} else if (ret == 3) {scr_setfontcolor(BGR_YELLOW);} else {scr_setfontcolor(BGR_RED);} + if (verbose || !success) { + DPRINTF("\t\t - HDD CONNECTION STATUS: %d\n", ret); + ERR_FOUND(); + } + if (ret == 0) { - scr_printf("\t\t - HDD CONNECTION STATUS: %d\n", ret); /* Check ATA device S.M.A.R.T. status. */ ret = fileXioDevctl("hdd0:", HDIOC_SMARTSTAT, NULL, 0, NULL, 0); - if (ret != 0) scr_setfontcolor(0x0000ff); else scr_setfontcolor(0x00FF00); - scr_printf("\t\t - S.M.A.R.T STATUS: %d\n", ret); + DPRINTF(" - S.M.A.R.T STATUS: %d\n", ret); + success = ret == 0; + if (success) scr_setfontcolor(BGR_GREEN); else scr_setfontcolor(BGR_RED); + if (verbose || !success) { + HDDCHECKER_PRINTF("\t\t - S.M.A.R.T STATUS: %d\n", ret); + ERR_FOUND(); + } /* Check for unrecoverable I/O errors on sectors. */ ret = fileXioDevctl("hdd0:", HDIOC_GETSECTORERROR, NULL, 0, NULL, 0); - if (ret != 0) scr_setfontcolor(0x0000ff); else scr_setfontcolor(0x00FF00); - scr_printf("\t\t - SECTOR ERRORS: %d\n", ret); + DPRINTF(" - SECTOR ERRORS: %d\n", ret); + success = ret == 0; + if (success) scr_setfontcolor(BGR_GREEN); else scr_setfontcolor(BGR_RED); + if (verbose || !success) { + HDDCHECKER_PRINTF("\t\t - SECTOR ERRORS: %d\n", ret); + ERR_FOUND(); + } /* Check for partitions that have errors. */ ret = fileXioDevctl("hdd0:", HDIOC_GETERRORPARTNAME, NULL, 0, ErrorPartName, sizeof(ErrorPartName)); - if (ret != 0) scr_setfontcolor(0x0000ff); else scr_setfontcolor(0x00FF00); - scr_printf("\t\t - CORRUPTED PARTITIONS: %d\n", ret); - if (ret != 0) + DPRINTF(" - CORRUPTED PARTITIONS: %d\n", ret); + success = ret == 0; + if (success) scr_setfontcolor(BGR_GREEN); else scr_setfontcolor(BGR_RED); + if (verbose || !success) { + HDDCHECKER_PRINTF(" - CORRUPTED PARTITIONS: %d\n", ret); + ERR_FOUND(); + } + if (!success) { - scr_printf("\t\tpartition: %s\n", ErrorPartName); + HDDCHECKER_PRINTF("\t\tpartition: %s\n", ErrorPartName); + DPRINTF(" partition: %s\n", ErrorPartName); } - } else scr_setfontcolor(0x00FFFF), scr_printf("Skipping test, HDD is not connected\n"); - scr_setfontcolor(0xFFFFFF); - scr_printf("\t\tWaiting for 10 seconds...\n"); - sleep(10); + } else { + HDDCHECKER_PRINTF("Skipping HDD diagnosis, HDD is not usable\n"); + ERR_FOUND(); + } + scr_setfontcolor(BGR_WHITE); +#ifdef MBR_KELF // when building MBR, we have two behaviours... + if (found_at_least_1_err || verbose) sleep(5);// verbose waits anyway, so user can read, because he manually asked for this! + // if not verbose, we only wait if something is wrong +#else + sleep(5); +#endif + if (verbose) scr_clear(); } /// @brief poweroff callback function /// @note only expansion bay models will properly make use of this. the other models will run the callback but will poweroff themselves before reaching function end... @@ -953,9 +999,9 @@ int dischandler() sceCdTrayReq(0, NULL); first_run = 0; } - scr_setfontcolor(0x0000ff); + scr_setfontcolor(BGR_RED); scr_printf("No Disc\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); break; case SCECdDETCT: @@ -967,37 +1013,37 @@ int dischandler() case SCECdPSCD: case SCECdPSCDDA: - scr_setfontcolor(0x00ff00); + scr_setfontcolor(BGR_GREEN); scr_printf("PlayStation\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); ValidDiscInserted = 1; break; case SCECdPS2CD: case SCECdPS2CDDA: case SCECdPS2DVD: - scr_setfontcolor(0x00ff00); + scr_setfontcolor(BGR_GREEN); scr_printf("PlayStation 2\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); ValidDiscInserted = 1; break; case SCECdCDDA: scr_setfontcolor(0xffff00); scr_printf("Audio Disc (not supported by this program)\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); break; case SCECdDVDV: - scr_setfontcolor(0x00ff00); + scr_setfontcolor(BGR_GREEN); scr_printf("DVD Video\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); ValidDiscInserted = 1; break; default: - scr_setfontcolor(0x0000ff); + scr_setfontcolor(BGR_RED); scr_printf("Unknown (%d)\n", DiscType); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); } } @@ -1106,9 +1152,9 @@ void CDVDBootCertify(u8 romver[16]) // Do not check for success/failure. Early consoles do not support (and do not require) boot-certification. sceCdBootCertify(RomName); } else { - scr_setfontcolor(0x0000ff); + scr_setfontcolor(BGR_RED); scr_printf("\tERROR: Could not certify CDVD Boot. ROMVER was NULL\n"); - scr_setfontcolor(0xffffff); + scr_setfontcolor(BGR_WHITE); } // This disables DVD Video Disc playback. This functionality is restored by loading a DVD Player KELF. diff --git a/thirdparty/kelftool_dnasload.exe b/thirdparty/kelftool_dnasload.exe index 46124dd..477e09d 100644 Binary files a/thirdparty/kelftool_dnasload.exe and b/thirdparty/kelftool_dnasload.exe differ