├── .github └── workflows │ └── compile.yml ├── Makefile ├── README.md ├── installer ├── INSTALL │ ├── FHDB_MBR.XIN │ ├── OPNPS2LD.ELF │ └── ULE.ELF ├── Makefile ├── gui.c ├── include │ ├── gui.h │ ├── iop.h │ ├── pad.h │ └── textures.h ├── install.c ├── iop.c ├── linkfile ├── main.c ├── pad.c ├── resources │ ├── bg.png │ ├── bg_error.png │ ├── bg_success.png │ ├── button_circle.png │ ├── button_cross.png │ ├── button_square.png │ ├── button_triangle.png │ ├── dot.png │ └── logo.png └── textures.c ├── kelftool └── kelftool.elf └── launcher-hdd ├── elf-loader ├── Makefile └── loader.c └── payload ├── Makefile ├── main.c ├── pad.c └── pad.h /.github/workflows/compile.yml: -------------------------------------------------------------------------------- 1 | name: Build ELF 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | paths: 7 | pull_request: 8 | 9 | jobs: 10 | build-packages: 11 | runs-on: ubuntu-latest 12 | container: ps2dev/ps2dev:latest 13 | steps: 14 | - name: Install dependencies 15 | run: | 16 | apk add build-base git zip 17 | - uses: actions/checkout@v2 18 | - run: | 19 | git fetch --prune --unshallow 20 | 21 | - name: Compile 22 | run: | 23 | make -C launcher-hdd/payload/ 24 | 25 | - name: Get short SHA 26 | id: slug 27 | run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)" 28 | 29 | 30 | - name: Upload artifacts 31 | if: ${{ success() }} 32 | uses: actions/upload-artifact@v2 33 | with: 34 | name: SoftDev2-Launcher 35 | path: | 36 | launcher-hdd/payload/payload-stripped.elf 37 | launcher-hdd/payload/payload.bin 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(MAKE) -C installer 3 | 4 | clean: 5 | 6 | 7 | $(MAKE) -C installer clean 8 | 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SOFTDEV2 BY alexparrado (2021) 2 | 3 | 4 | SoftDev2 automatically boots from __mbr partition in PS2 fat models with internal HDD. 5 | 6 | 7 | # Installation instructions: 8 | 9 | 10 | Run SoftDev2Installer.elf from your USB pendrive to install SoftDev MBR program (MBR.XIN) on your HDD. 11 | 12 | 13 | # Usage: 14 | 15 | 16 | SoftDev2 should automatically boot from your HDD. 17 | 18 | On boot SoftDev2 will launch OPL (hdd0:__sysconf/softdev2/OPNPS2LD.ELF) by default. In addition hot keys were added which will launch corresponding application if hot key is held during boot: 19 | 20 | - CIRCLE button: uLaunchELF (hdd0:__sysconf/softdev2/ULE.ELF). 21 | - TRIANGLE button: OSD ROM browser (rom0:OSDSYS), FreeHDBoot (hdd0:__system/osd/osdmain.elf) or HDD-OSD browser (hdd0:__system/osd/hosdsys.elf or hdd0:__system/osd100/hosdsys.elf) if any installed. 22 | 23 | # Credits 24 | ps2-browser launch feature is based on the FreeMCBoot 1.8 source code for OSDSYS patching, so credits go to Neme & jimmikaelkael. 25 | -------------------------------------------------------------------------------- /installer/INSTALL/FHDB_MBR.XIN: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/INSTALL/FHDB_MBR.XIN -------------------------------------------------------------------------------- /installer/INSTALL/OPNPS2LD.ELF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/INSTALL/OPNPS2LD.ELF -------------------------------------------------------------------------------- /installer/INSTALL/ULE.ELF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/INSTALL/ULE.ELF -------------------------------------------------------------------------------- /installer/Makefile: -------------------------------------------------------------------------------- 1 | EE_BIN = main.elf 2 | EE_BIN_PACKED = ../SoftDev2Installer.elf 3 | EE_BIN_STRIPPED = main-stripped.ELF 4 | 5 | #IOP modules 6 | EE_IOP_OBJS = FILEXIO_irx.o IOMANX_irx.o SIO2MAN_irx.o PADMAN_irx.o DEV9_irx.o ATAD_irx.o HDD_irx.o PFS_irx.o 7 | 8 | EE_OBJS = main.o iop.o pad.o install.o OPL_elf.o ULE_elf.o MBR_xin.o FHDB_MBR_xin.o gui.o textures.o background_png.o background_success_png.o background_error_png.o logo_png.o cross_png.o circle_png.o square_png.o triangle_png.o $(EE_IOP_OBJS) 9 | 10 | EE_INCS := -I$(PS2SDK)/ports/include -I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include -I$(PS2SDK)/ports/include -I$(PS2SDK)/sbv/include -I$(GSKIT)/include -I$(GSKIT)/ee/dma/include -I$(GSKIT)/ee/gs/include -I$(GSKIT)/ee/toolkit/include 11 | EE_LDFLAGS := -L$(PS2SDK)/ports/lib -L$(PS2SDK)/ee/lib -L$(PS2DEV)/ee/ee/lib -L$(GSKIT)/lib 12 | EE_LIBS = -lpadx -lpatches -lc -lkernel -lfileXio -lhdd -lgskit -ldmakit -lgskit_toolkit -L$(PS2SDK)/ports/lib -lpng -lz 13 | EE_GPVAL = -G0 14 | EE_CFLAGS += -Os -mgpopt $(EE_GPVAL) -DNEWLIB_PORT_AWARE -D_EE 15 | 16 | %.o : %.c 17 | $(EE_CC) $(EE_CFLAGS) $(EE_INCS) -c $< -o $@ 18 | 19 | %.o : %.S 20 | $(EE_CC) $(EE_CFLAGS) $(EE_INCS) -c $< -o $@ 21 | 22 | %.o : %.s 23 | $(EE_AS) $(EE_ASFLAGS) $< -o $@ 24 | 25 | 26 | all: 27 | $(MAKE) -C ../launcher-hdd/payload 28 | ../kelftool/kelftool.elf encrypt mbr ../launcher-hdd/payload/payload.bin INSTALL/MBR.XIN 29 | $(MAKE) $(EE_BIN_PACKED) 30 | 31 | 32 | clean: 33 | $(MAKE) -C ../launcher-hdd/payload clean 34 | rm -f $(EE_BIN) $(EE_BIN_STRIPPED) $(EE_BIN_PACKED)$(EE_BIN_REL) $(EE_OBJS) *_irx.c *_elf.c *_xin.c *_png.s *_ttf.s INSTALL/MBR.XIN 35 | 36 | 37 | $(EE_BIN_STRIPPED): $(EE_BIN) 38 | $(EE_STRIP) -s -R .comment -R .gnu.version --strip-unneeded -o $@ $< 39 | 40 | $(EE_BIN_PACKED): $(EE_BIN_STRIPPED) 41 | ps2-packer -v $< $@ 42 | SIO2MAN_irx.c: $(PS2SDK)/iop/irx/freesio2.irx 43 | bin2c $(PS2SDK)/iop/irx/freesio2.irx SIO2MAN_irx.c SIO2MAN_irx 44 | 45 | PADMAN_irx.c: $(PS2SDK)/iop/irx/freepad.irx 46 | bin2c $(PS2SDK)/iop/irx/freepad.irx PADMAN_irx.c PADMAN_irx 47 | 48 | 49 | ATAD_irx.c: $(PS2SDK)/iop/irx/ps2atad.irx 50 | bin2c $(PS2SDK)/iop/irx/ps2atad.irx ATAD_irx.c ATAD_irx 51 | 52 | HDD_irx.c: $(PS2SDK)/iop/irx/ps2hdd-osd.irx 53 | bin2c $(PS2SDK)/iop/irx/ps2hdd-osd.irx HDD_irx.c HDD_irx 54 | 55 | PFS_irx.c: $(PS2SDK)/iop/irx/ps2fs.irx 56 | bin2c $(PS2SDK)/iop/irx/ps2fs.irx PFS_irx.c PFS_irx 57 | 58 | DEV9_irx.c: $(PS2SDK)/iop/irx/ps2dev9.irx 59 | bin2c $(PS2SDK)/iop/irx/ps2dev9.irx DEV9_irx.c DEV9_irx 60 | 61 | IOMANX_irx.c: $(PS2SDK)/iop/irx/iomanX.irx 62 | bin2c $(PS2SDK)/iop/irx/iomanX.irx IOMANX_irx.c IOMANX_irx 63 | 64 | FILEXIO_irx.c: $(PS2SDK)/iop/irx/fileXio.irx 65 | bin2c $(PS2SDK)/iop/irx/fileXio.irx FILEXIO_irx.c FILEXIO_irx 66 | 67 | OPL_elf.c: 68 | bin2c INSTALL/OPNPS2LD.ELF OPL_elf.c OPL_elf 69 | 70 | ULE_elf.c: 71 | bin2c INSTALL/ULE.ELF ULE_elf.c ULE_elf 72 | 73 | MBR_xin.c: 74 | bin2c INSTALL/MBR.XIN MBR_xin.c MBR_xin 75 | 76 | FHDB_MBR_xin.c: 77 | bin2c INSTALL/FHDB_MBR.XIN FHDB_MBR_xin.c FHDB_MBR_xin 78 | 79 | background_png.s: resources/bg.png 80 | bin2s $< $@ background_png 81 | 82 | background_success_png.s: resources/bg_success.png 83 | bin2s $< $@ background_success_png 84 | 85 | background_error_png.s: resources/bg_error.png 86 | bin2s $< $@ background_error_png 87 | 88 | 89 | logo_png.s: resources/logo.png 90 | bin2s $< $@ logo_png 91 | 92 | cross_png.s: resources/button_cross.png 93 | bin2s $< $@ cross_png 94 | 95 | circle_png.s: resources/button_circle.png 96 | bin2s $< $@ circle_png 97 | 98 | triangle_png.s: resources/button_triangle.png 99 | bin2s $< $@ triangle_png 100 | 101 | square_png.s: resources/button_square.png 102 | bin2s $< $@ square_png 103 | 104 | include $(PS2SDK)/samples/Makefile.pref 105 | include $(PS2SDK)/samples/Makefile.eeglobal 106 | -------------------------------------------------------------------------------- /installer/gui.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | #include "include/gui.h" 8 | 9 | GSGLOBAL *gsGlobal; 10 | GSFONTM *gsFontM ; 11 | GSTEXTURE gsTextures[TEXTURES_COUNT]; 12 | 13 | 14 | extern uint8_t font_ttf; 15 | extern int size_font_ttf; 16 | 17 | 18 | 19 | 20 | 21 | void drawFont(int x, int y, float scale, u64 color, const char *format, ...) 22 | { 23 | char buffer[256]; 24 | 25 | va_list args; 26 | va_start(args, format); 27 | vsprintf(buffer, format, args); 28 | gsKit_fontm_print_scaled(gsGlobal, gsFontM, x, y, 0, scale, color, buffer); 29 | va_end(args); 30 | 31 | } 32 | 33 | void draw() 34 | { 35 | gsKit_queue_exec(gsGlobal); 36 | 37 | gsKit_sync_flip(gsGlobal); 38 | 39 | gsKit_TexManager_nextFrame(gsGlobal); 40 | } 41 | 42 | void drawBackground(internal_texture_t tex) 43 | { 44 | u64 texCol = GS_SETREG_RGBAQ(0x80, 0x80, 0x80, 0x80, 0x00); 45 | 46 | gsKit_TexManager_bind(gsGlobal, &gsTextures[tex]); 47 | 48 | gsKit_prim_sprite_texture(gsGlobal, &gsTextures[tex], 49 | 0.0f, // X1 50 | 0.0f, // Y2 51 | 0.0f, // U1 52 | 0.0f, // V1 53 | gsTextures[tex].Width, // X2 54 | gsTextures[tex].Height, // Y2 55 | gsTextures[tex].Width, // U2 56 | gsTextures[tex].Height, // V2 57 | 2, 58 | texCol); 59 | } 60 | 61 | void drawTexture(internal_texture_t tex, float fx, float fy) 62 | { 63 | u64 texCol = GS_SETREG_RGBAQ(0x80, 0x80, 0x80, 0x80, 0x00); 64 | 65 | gsKit_TexManager_bind(gsGlobal, &gsTextures[tex]); 66 | 67 | gsKit_prim_sprite_texture(gsGlobal, &gsTextures[tex], 68 | fx, // X1 69 | fy, // Y1 70 | 0.0f, // U1 71 | 0.0f, // V1 72 | fx + gsTextures[tex].Width, // X2 73 | fy + gsTextures[tex].Height, // Y2 74 | gsTextures[tex].Width, // U2 75 | gsTextures[tex].Height, // V2 76 | 2, 77 | texCol); 78 | } 79 | 80 | void clearScreen(){ 81 | u64 Black = GS_SETREG_RGBAQ(0x00, 0x00, 0x00, 0x00, 0x00); 82 | gsKit_clear(gsGlobal, Black); 83 | 84 | } 85 | 86 | void gui_init(float spacing) 87 | { 88 | 89 | u64 Black = GS_SETREG_RGBAQ(0x00, 0x00, 0x00, 0x00, 0x00); 90 | gsGlobal = gsKit_init_global(); 91 | gsFontM = gsKit_init_fontm(); 92 | 93 | dmaKit_init(D_CTRL_RELE_OFF, D_CTRL_MFD_OFF, D_CTRL_STS_UNSPEC, 94 | D_CTRL_STD_OFF, D_CTRL_RCYC_8, 1 << DMA_CHANNEL_GIF); 95 | 96 | // Initialize the DMAC 97 | dmaKit_chan_init(DMA_CHANNEL_GIF); 98 | 99 | gsGlobal->DoubleBuffering = GS_SETTING_OFF; 100 | gsGlobal->ZBuffering = GS_SETTING_OFF; 101 | 102 | gsKit_init_screen(gsGlobal); 103 | gsKit_mode_switch(gsGlobal, GS_PERSISTENT); 104 | 105 | gsKit_fontm_upload(gsGlobal, gsFontM); 106 | gsFontM->Spacing = spacing; 107 | 108 | gsKit_clear(gsGlobal, Black); 109 | 110 | // Clear static loaded textures, use texture manager instead 111 | gsKit_vram_clear(gsGlobal); 112 | 113 | gsGlobal->PSM = GS_PSM_CT32; 114 | gsGlobal->PSMZ = GS_PSMZ_32; 115 | gsGlobal->PrimAlphaEnable = GS_SETTING_ON; 116 | 117 | // Load all textures 118 | int i; 119 | for (i = 0; i < TEXTURES_COUNT; i++) 120 | { 121 | gsTextures[i].Delayed = 1; 122 | texPngLoad(&gsTextures[i], i); 123 | gsTextures[i].Filter = GS_FILTER_NEAREST; 124 | } 125 | 126 | gsKit_set_primalpha(gsGlobal, GS_SETREG_ALPHA(0, 1, 0, 1, 0), 0); 127 | 128 | } 129 | -------------------------------------------------------------------------------- /installer/include/gui.h: -------------------------------------------------------------------------------- 1 | #ifndef __GUI_H 2 | #define __GUI_H 3 | 4 | #include "textures.h" 5 | 6 | void drawBackground(internal_texture_t tex); 7 | void drawTexture(internal_texture_t tex, float fx, float fy); 8 | void drawFont(int x, int y, float scale, u64 color, const char *format, ...); 9 | void gui_init(float spacing); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /installer/include/iop.h: -------------------------------------------------------------------------------- 1 | int InitPS2(); 2 | void DeInitPS2(void); 3 | -------------------------------------------------------------------------------- /installer/include/pad.h: -------------------------------------------------------------------------------- 1 | void PadInitPads(void); 2 | void PadDeinitPads(void); 3 | 4 | int ReadPadStatus_raw(int port, int slot); 5 | int ReadCombinedPadStatus_raw(void); 6 | int ReadPadStatus(int port, int slot); 7 | int ReadCombinedPadStatus(void); 8 | -------------------------------------------------------------------------------- /installer/include/textures.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEXTURES_H 2 | #define __TEXTURES_H 3 | 4 | 5 | typedef enum { 6 | BACKGROUND = 0, 7 | BACKGROUND_SUCCESS, 8 | BACKGROUND_ERROR, 9 | LOGO, 10 | CROSS, 11 | SQUARE, 12 | TRIANGLE, 13 | CIRCLE, 14 | TEXTURES_COUNT 15 | } internal_texture_t; 16 | 17 | int texPngLoad(GSTEXTURE *texture, int texID); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /installer/install.c: -------------------------------------------------------------------------------- 1 | //SoftDev2 Installer by alexparrado 2021 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | extern int errno __attribute__((section("data"))); 25 | 26 | //Embedded install files 27 | extern unsigned char OPL_elf[]; 28 | extern unsigned int size_OPL_elf; 29 | 30 | extern unsigned char ULE_elf[]; 31 | extern unsigned int size_ULE_elf; 32 | 33 | extern unsigned char MBR_xin[]; 34 | extern unsigned int size_MBR_xin; 35 | 36 | extern unsigned char FHDB_MBR_xin[]; 37 | extern unsigned int size_FHDB_MBR_xin; 38 | 39 | /////////////From FHDB 1.9 installer source code//////////////////// 40 | int HDDCheckStatus(void) 41 | { 42 | int status; 43 | 44 | status = fileXioDevctl("hdd0:", HDIOC_STATUS, NULL, 0, NULL, 0); 45 | 46 | if (status == 0) 47 | fileXioRemove("hdd0:_tmp"); //Remove _tmp, if it exists. 48 | 49 | return status; 50 | } 51 | 52 | int EnableHDDBooting(void) 53 | { 54 | int OpResult, result; 55 | unsigned char OSDConfigBuffer[15]; 56 | 57 | do 58 | { 59 | sceCdOpenConfig(0, 0, 1, &OpResult); 60 | } while (OpResult & 9); 61 | 62 | do 63 | { 64 | result = sceCdReadConfig(OSDConfigBuffer, &OpResult); 65 | } while (OpResult & 9 || result == 0); 66 | 67 | do 68 | { 69 | result = sceCdCloseConfig(&OpResult); 70 | } while (OpResult & 9 || result == 0); 71 | 72 | if ((OSDConfigBuffer[0] & 3) != 2) 73 | { //If ATAD support and HDD booting are not already activated. 74 | OSDConfigBuffer[0] = (OSDConfigBuffer[0] & ~3) | 2; 75 | 76 | do 77 | { 78 | sceCdOpenConfig(0, 1, 1, &OpResult); 79 | } while (OpResult & 9); 80 | 81 | do 82 | { 83 | result = sceCdWriteConfig(OSDConfigBuffer, &OpResult); 84 | } while (OpResult & 9 || result == 0); 85 | 86 | do 87 | { 88 | result = sceCdCloseConfig(&OpResult); 89 | } while (OpResult & 9 || result == 0); 90 | 91 | result = 0; 92 | } 93 | else 94 | result = 1; 95 | 96 | return result; 97 | } 98 | ///////////////////////////////////////////////////////////////////// 99 | 100 | //To create file from embedded buffer 101 | int createFileFromBuffer(char *fileName, char *buffer, int size) 102 | { 103 | FILE *file; 104 | int result = 0; 105 | 106 | file = fopen(fileName, "w"); 107 | if (file) 108 | { 109 | if (fwrite(buffer, 1, size, file) != size) 110 | result = -1; 111 | 112 | fclose(file); 113 | } 114 | else 115 | result = -1; 116 | 117 | return result; 118 | } 119 | 120 | //To inject MBR from embedded buffer (MBR.XIN) 121 | int injectMBRFromBuffer(char *buffer, int size) 122 | { 123 | 124 | int result; 125 | iox_stat_t statFile; 126 | unsigned int numSectors; 127 | unsigned int sector; 128 | unsigned int remainder; 129 | unsigned int i; 130 | unsigned int numBytes; 131 | hddSetOsdMBR_t MBRInfo; 132 | 133 | //Buffer for I/O devctl operations on HDD 134 | uint8_t IOBuffer[512 + sizeof(hddAtaTransfer_t)] __attribute__((aligned(64))); 135 | 136 | //IF stats can be retrieved 137 | if ((result = fileXioGetStat("hdd0:__mbr", &statFile)) >= 0) 138 | { 139 | //Sector to write 140 | sector = statFile.private_5 + 0x2000; 141 | 142 | //Bytes in last sector 143 | remainder = (size & 0x1FF); 144 | 145 | //Total sectors to inject 146 | numSectors = (size / 512) + ((remainder) ? 1 : 0); 147 | numBytes = 512; 148 | 149 | //Writes sectors 150 | for (i = 0; i < numSectors; i++) 151 | { 152 | //If last sector 153 | if ((i == (numSectors - 1)) && (remainder != 0)) 154 | { 155 | numBytes = remainder; 156 | //Performs read operation for one sector 157 | ((hddAtaTransfer_t *)IOBuffer)->lba = sector + i; 158 | ((hddAtaTransfer_t *)IOBuffer)->size = 1; 159 | if ((result = fileXioDevctl("hdd0:", APA_DEVCTL_ATA_READ, IOBuffer, sizeof(hddAtaTransfer_t), IOBuffer + sizeof(hddAtaTransfer_t), 512)) < 0) 160 | break; 161 | } 162 | //Copies from buffer 163 | memcpy(IOBuffer + sizeof(hddAtaTransfer_t), buffer + 512 * i, numBytes); 164 | //Performs write operation for one sector 165 | ((hddAtaTransfer_t *)IOBuffer)->lba = sector + i; 166 | ((hddAtaTransfer_t *)IOBuffer)->size = 1; 167 | 168 | if ((result = fileXioDevctl("hdd0:", APA_DEVCTL_ATA_WRITE, IOBuffer, 512 + sizeof(hddAtaTransfer_t), NULL, 0)) < 0) 169 | break; 170 | } 171 | //Writes MBR information 172 | if (result >= 0) 173 | { 174 | MBRInfo.start = sector; 175 | MBRInfo.size = numSectors; 176 | fileXioDevctl("hdd0:", APA_DEVCTL_SET_OSDMBR, &MBRInfo, sizeof(MBRInfo), NULL, 0); 177 | } 178 | } 179 | return result; 180 | } 181 | 182 | //Main installation function 183 | int InstallSoftDev2() 184 | { 185 | 186 | char *party = "hdd0:__sysconf"; 187 | int result; 188 | 189 | if ((result = fileXioMount("pfs0:", party, FIO_MT_RDWR)) == 0) 190 | { 191 | result = mkdir("pfs0:/softdev2", 0777); 192 | 193 | if ((result == 0) || ((result == -1) && (errno == EEXIST))) 194 | { 195 | result = 0; 196 | if ((result = createFileFromBuffer("pfs0:/softdev2/OPNPS2LD.ELF", OPL_elf, size_OPL_elf)) == 0) 197 | if ((result = createFileFromBuffer("pfs0:/softdev2/ULE.ELF", ULE_elf, size_ULE_elf)) == 0) 198 | { 199 | if ((result = injectMBRFromBuffer(MBR_xin, size_MBR_xin)) >= 0) 200 | result = EnableHDDBooting(); 201 | } 202 | } 203 | } 204 | 205 | return result; 206 | } 207 | 208 | //Function to restore FHDB MBR 209 | int InstallFHDBMBR() 210 | { 211 | int result; 212 | 213 | if ((result = injectMBRFromBuffer(FHDB_MBR_xin, size_FHDB_MBR_xin)) >= 0) 214 | result = EnableHDDBooting(); 215 | 216 | return result; 217 | } 218 | -------------------------------------------------------------------------------- /installer/iop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | //Embedded IOP drivers 15 | extern unsigned char IOMANX_irx[]; 16 | extern unsigned int size_IOMANX_irx; 17 | 18 | extern unsigned char FILEXIO_irx[]; 19 | extern unsigned int size_FILEXIO_irx; 20 | 21 | extern unsigned char SIO2MAN_irx[]; 22 | extern unsigned int size_SIO2MAN_irx; 23 | 24 | extern unsigned char PADMAN_irx[]; 25 | extern unsigned int size_PADMAN_irx; 26 | 27 | extern unsigned char DEV9_irx[]; 28 | extern unsigned int size_DEV9_irx; 29 | 30 | extern unsigned char ATAD_irx[]; 31 | extern unsigned int size_ATAD_irx; 32 | 33 | extern unsigned char HDD_irx[]; 34 | extern unsigned int size_HDD_irx; 35 | 36 | extern unsigned char PFS_irx[]; 37 | extern unsigned int size_PFS_irx; 38 | 39 | void ResetIOP() 40 | { 41 | 42 | SifInitRpc(0); 43 | while (!SifIopReset("", 0)) 44 | { 45 | }; 46 | while (!SifIopSync()) 47 | { 48 | }; 49 | SifInitRpc(0); 50 | } 51 | 52 | void InitPS2() 53 | { 54 | 55 | static const char PFS_args[] = "-n\0" 56 | "24\0" 57 | "-o\0" 58 | "8"; 59 | ResetIOP(); 60 | 61 | SifInitIopHeap(); 62 | SifLoadFileInit(); 63 | fioInit(); 64 | 65 | sbv_patch_enable_lmb(); 66 | sbv_patch_disable_prefix_check(); 67 | 68 | SifExecModuleBuffer(IOMANX_irx, size_IOMANX_irx, 0, NULL, NULL); 69 | SifExecModuleBuffer(FILEXIO_irx, size_FILEXIO_irx, 0, NULL, NULL); 70 | 71 | fileXioInit(); 72 | sceCdInit(SCECdINoD); 73 | 74 | SifExecModuleBuffer(DEV9_irx, size_DEV9_irx, 0, NULL, NULL); 75 | SifExecModuleBuffer(SIO2MAN_irx, size_SIO2MAN_irx, 0, NULL, NULL); 76 | SifExecModuleBuffer(PADMAN_irx, size_PADMAN_irx, 0, NULL, NULL); 77 | PadInitPads(); 78 | 79 | if (SifExecModuleBuffer(ATAD_irx, size_ATAD_irx, 0, NULL, NULL) >= 0) 80 | { 81 | SifExecModuleBuffer(HDD_irx, size_HDD_irx, 0, NULL, NULL); 82 | SifExecModuleBuffer(PFS_irx, size_PFS_irx, sizeof(PFS_args), PFS_args, NULL); 83 | } 84 | 85 | SifExitIopHeap(); 86 | SifLoadFileExit(); 87 | } 88 | 89 | void DeInitPS2(void) 90 | { 91 | PadDeinitPads(); 92 | sceCdInit(SCECdEXIT); 93 | fileXioExit(); 94 | SifExitRpc(); 95 | } 96 | -------------------------------------------------------------------------------- /installer/linkfile: -------------------------------------------------------------------------------- 1 | /* 2 | # _____ ___ ____ ___ ____ 3 | # ____| | ____| | | |____| 4 | # | ___| |____ ___| ____| | \ PS2DEV Open Source Project. 5 | #----------------------------------------------------------------------- 6 | # Copyright 2001-2004, ps2dev - http://www.ps2dev.org 7 | # Licenced under Academic Free License version 2.0 8 | # Review ps2sdk README & LICENSE files for further details. 9 | # 10 | # $Id$ 11 | # Linkfile script for ee-ld 12 | */ 13 | 14 | ENTRY(_start); 15 | 16 | SECTIONS { 17 | .text 0x00200000: { 18 | _ftext = . ; 19 | *(.text) 20 | *(.text.*) 21 | *(.gnu.linkonce.t*) 22 | KEEP(*(.init)) 23 | KEEP(*(.fini)) 24 | QUAD(0) 25 | } 26 | 27 | PROVIDE(_etext = .); 28 | PROVIDE(etext = .); 29 | 30 | .reginfo : { *(.reginfo) } 31 | 32 | /* Global/static constructors and deconstructors. */ 33 | .ctors ALIGN(16): { 34 | KEEP(*crtbegin*.o(.ctors)) 35 | KEEP(*(EXCLUDE_FILE(*crtend*.o) .ctors)) 36 | KEEP(*(SORT(.ctors.*))) 37 | KEEP(*(.ctors)) 38 | } 39 | .dtors ALIGN(16): { 40 | KEEP(*crtbegin*.o(.dtors)) 41 | KEEP(*(EXCLUDE_FILE(*crtend*.o) .dtors)) 42 | KEEP(*(SORT(.dtors.*))) 43 | KEEP(*(.dtors)) 44 | } 45 | 46 | /* Static data. */ 47 | .rodata ALIGN(128): { 48 | *(.rodata) 49 | *(.rodata.*) 50 | *(.gnu.linkonce.r*) 51 | } 52 | 53 | .data ALIGN(128): { 54 | _fdata = . ; 55 | *(.data) 56 | *(.data.*) 57 | *(.gnu.linkonce.d*) 58 | SORT(CONSTRUCTORS) 59 | } 60 | 61 | .rdata ALIGN(128): { *(.rdata) } 62 | .gcc_except_table ALIGN(128): { *(.gcc_except_table) } 63 | 64 | _gp = ALIGN(128) + 0x7ff0; 65 | .lit4 ALIGN(128): { *(.lit4) } 66 | .lit8 ALIGN(128): { *(.lit8) } 67 | 68 | .sdata ALIGN(128): { 69 | *(.sdata) 70 | *(.sdata.*) 71 | *(.gnu.linkonce.s*) 72 | } 73 | 74 | _edata = .; 75 | PROVIDE(edata = .); 76 | 77 | /* Uninitialized data. */ 78 | .sbss ALIGN(128) : { 79 | _fbss = . ; 80 | *(.sbss) 81 | *(.sbss.*) 82 | *(.gnu.linkonce.sb*) 83 | *(.scommon) 84 | } 85 | 86 | .bss ALIGN(128) : { 87 | *(.bss) 88 | *(.bss.*) 89 | *(.gnu.linkonce.b*) 90 | *(COMMON) 91 | } 92 | _end_bss = .; 93 | 94 | /* Symbols needed by crt0.s. */ 95 | PROVIDE(_heap_size = 0x02000000 - _end); 96 | PROVIDE(_stack_size = 0x2000); 97 | 98 | _stack = ALIGN(128); 99 | PROVIDE(_stack = .); 100 | . = _stack + _stack_size; 101 | 102 | _end = . ; 103 | PROVIDE(end = .); 104 | 105 | /* Unwanted stuff */ 106 | /DISCARD/ : { 107 | * ( .MIPS.abiflags ) 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /installer/main.c: -------------------------------------------------------------------------------- 1 | // SoftDev2 Installer by alexparrado 2021 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "include/pad.h" 23 | #include "include/iop.h" 24 | #include "include/gui.h" 25 | #include "include/textures.h" 26 | 27 | #define FONT_SIZE 0.8F 28 | #define SPACING 20 29 | 30 | // External variables for GS 31 | extern GSGLOBAL *gsGlobal; 32 | extern GSTEXTURE gsTextures[TEXTURES_COUNT]; 33 | 34 | int file_exists(char filepath[]) 35 | { 36 | int fdn; 37 | 38 | fdn = open(filepath, O_RDONLY); 39 | if (fdn < 0) 40 | return 0; 41 | close(fdn); 42 | 43 | return 1; 44 | } 45 | 46 | // States of menu Finite State Machine (FSM) 47 | enum 48 | { 49 | STATE_INIT, 50 | STATE_HDD, 51 | STATE_ENABLE_HDD_BOOT, 52 | STATE_FORMAT, 53 | STATE_CONFIRM, 54 | STATE_INSTALLING_FHDB_MBR, 55 | STATE_INSTALLING_SOFTDEV2, 56 | STATE_EXIT 57 | }; 58 | 59 | // From FMCB source 60 | static int CheckFormat(void) 61 | { 62 | int status; 63 | 64 | status = HDDCheckStatus(); 65 | 66 | return status; 67 | } 68 | 69 | // To draw a selection screen 70 | void drawSelectionScreen(internal_texture_t backgroundTexture, char *title, char *options[], int nOptions) 71 | { 72 | 73 | internal_texture_t i; 74 | int prevH = 0; 75 | u64 WhiteFont = GS_SETREG_RGBAQ(0xFF, 0xFF, 0xFF, 0x80, 0x00); 76 | 77 | drawBackground(backgroundTexture); 78 | 79 | drawTexture(LOGO, gsGlobal->Width / 2 - gsTextures[LOGO].Width / 2, SPACING); 80 | 81 | prevH += gsTextures[LOGO].Height + SPACING; 82 | 83 | if (title) 84 | { 85 | drawFont(SPACING, SPACING + prevH, FONT_SIZE, WhiteFont, title); 86 | prevH += 3 * SPACING; 87 | } 88 | 89 | for (i = CROSS; i < (nOptions + CROSS); i++) 90 | { 91 | drawTexture(i, SPACING, prevH); 92 | drawFont(SPACING + 1.5 * gsTextures[i].Width, (gsTextures[i].Height - (int)(26.0f * FONT_SIZE)) / 2 + prevH, FONT_SIZE, WhiteFont, options[i - CROSS]); 93 | prevH += gsTextures[i].Height; 94 | } 95 | 96 | drawTexture(CIRCLE, SPACING, prevH); 97 | drawFont(SPACING + 1.5 * gsTextures[CIRCLE].Width, (gsTextures[i].Height - (int)(26.0f * FONT_SIZE)) / 2 + prevH, FONT_SIZE, WhiteFont, "Exit"); 98 | 99 | draw(); 100 | } 101 | 102 | // Main text menu implemented as a Finite State Machine (FSM) 103 | int menu() 104 | { 105 | 106 | int key; 107 | 108 | int hddStatus; 109 | int isOSDUpdate = 0; 110 | 111 | int ret = 1; 112 | 113 | static int state = STATE_INIT; 114 | static int formatStatus = 0; 115 | char *hddosd_party = "hdd0:__system"; 116 | 117 | char *options[3]; 118 | int nOptions; 119 | 120 | switch (state) 121 | { 122 | // State where installer starts 123 | case STATE_INIT: 124 | 125 | options[0] = "Continue"; 126 | options[1] = "Enable HDD booting"; 127 | nOptions = 2; 128 | drawSelectionScreen(BACKGROUND, "PLEASE SELECT ONE OPTION", options, nOptions); 129 | 130 | while (1) 131 | { 132 | key = ReadCombinedPadStatus(); 133 | if (key & PAD_CROSS) 134 | { 135 | state = STATE_HDD; 136 | break; 137 | } 138 | if (key & PAD_SQUARE) 139 | { 140 | state = STATE_ENABLE_HDD_BOOT; 141 | break; 142 | } 143 | 144 | if (key & PAD_CIRCLE) 145 | { 146 | state = STATE_EXIT; 147 | break; 148 | } 149 | } 150 | 151 | break; 152 | case STATE_ENABLE_HDD_BOOT: 153 | 154 | EnableHDDBooting(); 155 | 156 | nOptions = 0; 157 | drawSelectionScreen(BACKGROUND, "HDD BOOT ENABLED", options, nOptions); 158 | 159 | while (1) 160 | { 161 | key = ReadCombinedPadStatus(); 162 | 163 | if (key & PAD_CIRCLE) 164 | { 165 | state = STATE_EXIT; 166 | break; 167 | } 168 | } 169 | 170 | break; 171 | 172 | // State where HDD is checked 173 | case STATE_HDD: 174 | 175 | hddStatus = CheckFormat(); 176 | 177 | switch (hddStatus) 178 | { 179 | case 1: // Not formatted 180 | 181 | options[0] = "Format"; 182 | nOptions = 1; 183 | drawSelectionScreen(BACKGROUND, "HDD IS NOT FORMATTED", options, nOptions); 184 | 185 | while (1) 186 | { 187 | key = ReadCombinedPadStatus(); 188 | if (key & PAD_CROSS) 189 | { 190 | 191 | formatStatus = hddFormat(); 192 | state = STATE_FORMAT; 193 | break; 194 | } 195 | 196 | if (key & PAD_CIRCLE) 197 | { 198 | state = STATE_EXIT; 199 | break; 200 | } 201 | } 202 | 203 | break; 204 | case 0: // Formatted 205 | state = STATE_CONFIRM; 206 | break; 207 | 208 | default: // Unknown errors 209 | 210 | nOptions = 0; 211 | drawSelectionScreen(BACKGROUND_ERROR, "HDD IS NOT CONNECTED OR IS UNUSABLE", options, nOptions); 212 | 213 | while (1) 214 | { 215 | key = ReadCombinedPadStatus(); 216 | 217 | if (key & PAD_CIRCLE) 218 | { 219 | state = STATE_EXIT; 220 | break; 221 | } 222 | } 223 | break; 224 | } 225 | 226 | break; 227 | 228 | case STATE_FORMAT: 229 | 230 | if (formatStatus) 231 | { 232 | 233 | nOptions = 0; 234 | drawSelectionScreen(BACKGROUND_ERROR, "FORMAT FAILED", options, nOptions); 235 | while (1) 236 | { 237 | key = ReadCombinedPadStatus(); 238 | 239 | if (key & PAD_CIRCLE) 240 | { 241 | state = STATE_EXIT; 242 | break; 243 | } 244 | } 245 | } 246 | else 247 | { 248 | 249 | nOptions = 1; 250 | options[0] = "Continue"; 251 | drawSelectionScreen(BACKGROUND_SUCCESS, "FORMAT SUCCEDED", options, nOptions); 252 | while (1) 253 | { 254 | key = ReadCombinedPadStatus(); 255 | 256 | if (key & PAD_CROSS) 257 | { 258 | state = STATE_CONFIRM; 259 | break; 260 | } 261 | 262 | if (key & PAD_CIRCLE) 263 | { 264 | state = STATE_EXIT; 265 | break; 266 | } 267 | } 268 | } 269 | 270 | break; 271 | 272 | // State where installation is confirmed 273 | case STATE_CONFIRM: 274 | 275 | if (fileXioMount("pfs0:", hddosd_party, FIO_MT_RDONLY) == 0) 276 | { 277 | 278 | // Tests for FHDB 279 | if (file_exists("pfs0:/osd/osdmain.elf")) 280 | isOSDUpdate = 1; 281 | 282 | // Tests for two locations of HDD-OSD 283 | if (file_exists("pfs0:/osd/hosdsys.elf")) 284 | isOSDUpdate = 1; 285 | 286 | if (file_exists("pfs0:/osd100/hosdsys.elf")) 287 | isOSDUpdate = 1; 288 | 289 | fileXioUmount("pfs0:"); 290 | } 291 | 292 | options[0] = "Install SoftDev2 on HDD"; 293 | nOptions = 1; 294 | 295 | if (isOSDUpdate) 296 | { 297 | options[1] = "Restore FreeHDBoot MBR"; 298 | nOptions = 2; 299 | } 300 | drawSelectionScreen(BACKGROUND, "PLEASE SELECT ONE OPTION", options, nOptions); 301 | 302 | while (1) 303 | { 304 | key = ReadCombinedPadStatus(); 305 | if (key & PAD_CROSS) 306 | { 307 | state = STATE_INSTALLING_SOFTDEV2; 308 | break; 309 | } 310 | 311 | if (isOSDUpdate) 312 | { 313 | if (key & PAD_SQUARE) 314 | { 315 | state = STATE_INSTALLING_FHDB_MBR; 316 | break; 317 | } 318 | } 319 | if (key & PAD_CIRCLE) 320 | { 321 | state = STATE_EXIT; 322 | break; 323 | } 324 | } 325 | 326 | break; 327 | // State where actual installation is carried out 328 | case STATE_INSTALLING_FHDB_MBR: 329 | 330 | nOptions = 0; 331 | drawSelectionScreen(BACKGROUND, "RESTORING FHDB MBR...", options, nOptions); 332 | 333 | if (InstallFHDBMBR() < 0) 334 | drawSelectionScreen(BACKGROUND_ERROR, "RESTORATION FAILED", options, nOptions); 335 | else 336 | drawSelectionScreen(BACKGROUND_SUCCESS, "RESTORATION SUCCEDED", options, nOptions); 337 | 338 | while (1) 339 | { 340 | key = ReadCombinedPadStatus(); 341 | if (key & PAD_CIRCLE) 342 | { 343 | state = STATE_EXIT; 344 | break; 345 | } 346 | } 347 | 348 | state = STATE_EXIT; 349 | 350 | break; 351 | 352 | // State where SoftDev2 installation is carried out 353 | case STATE_INSTALLING_SOFTDEV2: 354 | 355 | nOptions = 0; 356 | drawSelectionScreen(BACKGROUND, "INSTALLING SOFTDEV2 ON HDD...", options, nOptions); 357 | 358 | if (InstallSoftDev2() < 0) 359 | drawSelectionScreen(BACKGROUND_ERROR, "INSTALLATION FAILED", options, nOptions); 360 | else 361 | drawSelectionScreen(BACKGROUND_SUCCESS, "INSTALLATION SUCCEDED", options, nOptions); 362 | 363 | while (1) 364 | { 365 | key = ReadCombinedPadStatus(); 366 | if (key & PAD_CIRCLE) 367 | { 368 | state = STATE_EXIT; 369 | break; 370 | } 371 | } 372 | 373 | state = STATE_EXIT; 374 | 375 | break; 376 | case STATE_EXIT: 377 | ret = 0; 378 | 379 | break; 380 | 381 | default: 382 | break; 383 | } 384 | 385 | return ret; 386 | } 387 | 388 | // Main function 389 | int main(int argc, char *argv[]) 390 | { 391 | 392 | // Inits PS2 393 | InitPS2(); 394 | 395 | // Inits GUI 396 | gui_init(FONT_SIZE); 397 | 398 | // Displays menu 399 | while (menu()) 400 | ; 401 | 402 | // De-inits PS2 403 | DeInitPS2(); 404 | 405 | __asm__ __volatile__( 406 | " li $3, 0x04;" 407 | " syscall;" 408 | " nop;"); 409 | 410 | return 0; 411 | } 412 | -------------------------------------------------------------------------------- /installer/pad.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "include/pad.h" 8 | 9 | static unsigned char padArea[2][256] ALIGNED(64); 10 | static unsigned int old_pad[2] = {0, 0}; 11 | 12 | void PadInitPads(void) 13 | { 14 | padInit(0); 15 | padPortOpen(0, 0, padArea[0]); 16 | padPortOpen(1, 0, padArea[1]); 17 | 18 | old_pad[0] = 0; 19 | old_pad[1] = 0; 20 | } 21 | 22 | void PadDeinitPads(void) 23 | { 24 | padPortClose(0, 0); 25 | padPortClose(1, 0); 26 | padEnd(); 27 | } 28 | 29 | int ReadPadStatus_raw(int port, int slot) 30 | { 31 | struct padButtonStatus buttons; 32 | u32 paddata; 33 | 34 | paddata = 0; 35 | if (padRead(port, slot, &buttons) != 0) 36 | { 37 | paddata = 0xffff ^ buttons.btns; 38 | } 39 | 40 | return paddata; 41 | } 42 | 43 | int ReadCombinedPadStatus_raw(void) 44 | { 45 | return (ReadPadStatus_raw(0, 0) | ReadPadStatus_raw(1, 0)); 46 | } 47 | 48 | int ReadPadStatus(int port, int slot) 49 | { 50 | struct padButtonStatus buttons; 51 | u32 new_pad, paddata; 52 | 53 | new_pad = 0; 54 | if (padRead(port, slot, &buttons) != 0) 55 | { 56 | paddata = 0xffff ^ buttons.btns; 57 | 58 | new_pad = paddata & ~old_pad[port]; 59 | old_pad[port] = paddata; 60 | } 61 | 62 | return new_pad; 63 | } 64 | 65 | int ReadCombinedPadStatus(void) 66 | { 67 | return (ReadPadStatus(0, 0) | ReadPadStatus(1, 0)); 68 | } 69 | -------------------------------------------------------------------------------- /installer/resources/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/bg.png -------------------------------------------------------------------------------- /installer/resources/bg_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/bg_error.png -------------------------------------------------------------------------------- /installer/resources/bg_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/bg_success.png -------------------------------------------------------------------------------- /installer/resources/button_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/button_circle.png -------------------------------------------------------------------------------- /installer/resources/button_cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/button_cross.png -------------------------------------------------------------------------------- /installer/resources/button_square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/button_square.png -------------------------------------------------------------------------------- /installer/resources/button_triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/button_triangle.png -------------------------------------------------------------------------------- /installer/resources/dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/dot.png -------------------------------------------------------------------------------- /installer/resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/installer/resources/logo.png -------------------------------------------------------------------------------- /installer/textures.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "include/textures.h" 5 | 6 | extern void *background_png; 7 | extern void *background_success_png; 8 | extern void *background_error_png; 9 | extern void *logo_png; 10 | extern void *cross_png; 11 | extern void *circle_png; 12 | extern void *square_png; 13 | extern void *triangle_png; 14 | 15 | typedef struct 16 | { 17 | int id; 18 | void **texture; 19 | } texture_t; 20 | 21 | static texture_t internalTexture[TEXTURES_COUNT] = { 22 | {BACKGROUND, &background_png}, 23 | {BACKGROUND_SUCCESS, &background_success_png}, 24 | {BACKGROUND_ERROR, &background_error_png}, 25 | {LOGO, &logo_png}, 26 | {CROSS, &cross_png}, 27 | {SQUARE, &square_png}, 28 | {TRIANGLE, &triangle_png}, 29 | {CIRCLE, &circle_png}}; 30 | 31 | static int texSizeValidate(int width, int height, short psm) 32 | { 33 | if (width > 1024 || height > 1024) 34 | return -1; 35 | 36 | if (gsKit_texture_size(width, height, psm) > 720 * 512 * 4) 37 | return -1; 38 | 39 | return 0; 40 | } 41 | 42 | typedef struct 43 | { 44 | u8 red; 45 | u8 green; 46 | u8 blue; 47 | u8 alpha; 48 | } png_clut_t; 49 | 50 | typedef struct 51 | { 52 | png_colorp palette; 53 | int numPalette; 54 | int numTrans; 55 | png_bytep trans; 56 | png_clut_t *clut; 57 | } png_texture_t; 58 | 59 | static png_texture_t pngTexture; 60 | 61 | static int texPngEnd(png_structp pngPtr, png_infop infoPtr, int status) 62 | { 63 | if (infoPtr != NULL) 64 | png_destroy_read_struct(&pngPtr, &infoPtr, (png_infopp)NULL); 65 | 66 | return status; 67 | } 68 | 69 | static void texPngReadMemFunction(png_structp pngPtr, png_bytep data, png_size_t length) 70 | { 71 | void **PngBufferPtr = png_get_io_ptr(pngPtr); 72 | 73 | memcpy(data, *PngBufferPtr, length); 74 | *PngBufferPtr = (u8 *)(*PngBufferPtr) + length; 75 | } 76 | 77 | static void texPngReadPixels4(GSTEXTURE *texture, png_bytep *rowPointers) 78 | { 79 | unsigned char *pixel = (unsigned char *)texture->Mem; 80 | png_clut_t *clut = (png_clut_t *)texture->Clut; 81 | 82 | int i, j, k = 0; 83 | 84 | for (i = pngTexture.numPalette; i < 16; i++) 85 | { 86 | memset(&clut[i], 0, sizeof(clut[i])); 87 | } 88 | 89 | for (i = 0; i < pngTexture.numPalette; i++) 90 | { 91 | clut[i].red = pngTexture.palette[i].red; 92 | clut[i].green = pngTexture.palette[i].green; 93 | clut[i].blue = pngTexture.palette[i].blue; 94 | clut[i].alpha = 0x80; 95 | } 96 | 97 | for (i = 0; i < pngTexture.numTrans; i++) 98 | clut[i].alpha = pngTexture.trans[i] >> 1; 99 | 100 | for (i = 0; i < texture->Height; i++) 101 | { 102 | for (j = 0; j < texture->Width / 2; j++) 103 | { 104 | memcpy(&pixel[k], &rowPointers[i][1 * j], 1); 105 | pixel[k] = (pixel[k] << 4) | (pixel[k] >> 4); 106 | k++; 107 | } 108 | } 109 | } 110 | 111 | static void texPngReadPixels8(GSTEXTURE *texture, png_bytep *rowPointers) 112 | { 113 | unsigned char *pixel = (unsigned char *)texture->Mem; 114 | png_clut_t *clut = (png_clut_t *)texture->Clut; 115 | 116 | int i, j, k = 0; 117 | 118 | for (i = pngTexture.numPalette; i < 256; i++) 119 | { 120 | memset(&clut[i], 0, sizeof(clut[i])); 121 | } 122 | 123 | for (i = 0; i < pngTexture.numPalette; i++) 124 | { 125 | clut[i].red = pngTexture.palette[i].red; 126 | clut[i].green = pngTexture.palette[i].green; 127 | clut[i].blue = pngTexture.palette[i].blue; 128 | clut[i].alpha = 0x80; 129 | } 130 | 131 | for (i = 0; i < pngTexture.numTrans; i++) 132 | clut[i].alpha = pngTexture.trans[i] >> 1; 133 | 134 | // rotate clut 135 | for (i = 0; i < pngTexture.numPalette; i++) 136 | { 137 | if ((i & 0x18) == 8) 138 | { 139 | png_clut_t tmp = clut[i]; 140 | clut[i] = clut[i + 8]; 141 | clut[i + 8] = tmp; 142 | } 143 | } 144 | 145 | for (i = 0; i < texture->Height; i++) 146 | { 147 | for (j = 0; j < texture->Width; j++) 148 | { 149 | memcpy(&pixel[k++], &rowPointers[i][1 * j], 1); 150 | } 151 | } 152 | } 153 | 154 | static void texPngReadPixels24(GSTEXTURE *texture, png_bytep *rowPointers) 155 | { 156 | struct pixel3 157 | { 158 | unsigned char r, g, b; 159 | }; 160 | struct pixel3 *Pixels = (struct pixel3 *)texture->Mem; 161 | 162 | int i, j, k = 0; 163 | for (i = 0; i < texture->Height; i++) 164 | { 165 | for (j = 0; j < texture->Width; j++) 166 | { 167 | memcpy(&Pixels[k++], &rowPointers[i][4 * j], 3); 168 | } 169 | } 170 | } 171 | 172 | static void texPngReadPixels32(GSTEXTURE *texture, png_bytep *rowPointers) 173 | { 174 | struct pixel 175 | { 176 | unsigned char r, g, b, a; 177 | }; 178 | struct pixel *Pixels = (struct pixel *)texture->Mem; 179 | 180 | int i, j, k = 0; 181 | for (i = 0; i < texture->Height; i++) 182 | { 183 | for (j = 0; j < texture->Width; j++) 184 | { 185 | memcpy(&Pixels[k], &rowPointers[i][4 * j], 3); 186 | Pixels[k++].a = rowPointers[i][4 * j + 3] >> 1; 187 | } 188 | } 189 | } 190 | 191 | static void texPngReadData(GSTEXTURE *texture, png_structp pngPtr, png_infop infoPtr, 192 | void (*texPngReadPixels)(GSTEXTURE *texture, png_bytep *rowPointers)) 193 | { 194 | int row, rowBytes = png_get_rowbytes(pngPtr, infoPtr); 195 | size_t size = gsKit_texture_size_ee(texture->Width, texture->Height, texture->PSM); 196 | texture->Mem = memalign(128, size); 197 | 198 | // failed allocation 199 | if (!texture->Mem) 200 | { 201 | printf("TEXTURES PngReadData: Failed to allocate %d bytes\n", size); 202 | return; 203 | } 204 | 205 | png_bytep *rowPointers = calloc(texture->Height, sizeof(png_bytep)); 206 | for (row = 0; row < texture->Height; row++) 207 | { 208 | rowPointers[row] = malloc(rowBytes); 209 | } 210 | png_read_image(pngPtr, rowPointers); 211 | 212 | texPngReadPixels(texture, rowPointers); 213 | 214 | for (row = 0; row < texture->Height; row++) 215 | free(rowPointers[row]); 216 | 217 | free(rowPointers); 218 | 219 | png_read_end(pngPtr, NULL); 220 | } 221 | 222 | int texPngLoad(GSTEXTURE *texture, int texID) 223 | { 224 | png_structp pngPtr = NULL; 225 | png_infop infoPtr = NULL; 226 | png_voidp readData = NULL; 227 | png_rw_ptr readFunction = NULL; 228 | void **PngFileBufferPtr; 229 | 230 | texture->ClutPSM = 0; 231 | texture->Filter = GS_FILTER_LINEAR; 232 | texture->Mem = NULL; 233 | texture->Vram = 0; 234 | texture->VramClut = 0; 235 | texture->Clut = NULL; 236 | 237 | if (!internalTexture[texID].texture) 238 | return -1; 239 | 240 | PngFileBufferPtr = internalTexture[texID].texture; 241 | readData = &PngFileBufferPtr; 242 | readFunction = &texPngReadMemFunction; 243 | 244 | pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, NULL, NULL); 245 | if (!pngPtr) 246 | return texPngEnd(pngPtr, infoPtr, -2); 247 | 248 | infoPtr = png_create_info_struct(pngPtr); 249 | if (!infoPtr) 250 | return texPngEnd(pngPtr, infoPtr, -3); 251 | 252 | if (setjmp(png_jmpbuf(pngPtr))) 253 | return texPngEnd(pngPtr, infoPtr, -4); 254 | 255 | png_set_read_fn(pngPtr, readData, readFunction); 256 | 257 | unsigned int sigRead = 0; 258 | png_set_sig_bytes(pngPtr, sigRead); 259 | png_read_info(pngPtr, infoPtr); 260 | 261 | png_uint_32 pngWidth, pngHeight; 262 | int bitDepth, colorType, interlaceType; 263 | png_get_IHDR(pngPtr, infoPtr, &pngWidth, &pngHeight, &bitDepth, &colorType, &interlaceType, NULL, NULL); 264 | texture->Width = pngWidth; 265 | texture->Height = pngHeight; 266 | 267 | if (colorType == PNG_COLOR_TYPE_GRAY) 268 | png_set_expand(pngPtr); 269 | 270 | if (bitDepth == 16) 271 | png_set_strip_16(pngPtr); 272 | 273 | png_set_filler(pngPtr, 0x80, PNG_FILLER_AFTER); 274 | png_read_update_info(pngPtr, infoPtr); 275 | 276 | void (*texPngReadPixels)(GSTEXTURE * texture, png_bytep * rowPointers); 277 | switch (png_get_color_type(pngPtr, infoPtr)) 278 | { 279 | case PNG_COLOR_TYPE_RGB_ALPHA: 280 | texture->PSM = GS_PSM_CT32; 281 | texPngReadPixels = &texPngReadPixels32; 282 | break; 283 | case PNG_COLOR_TYPE_RGB: 284 | texture->PSM = GS_PSM_CT24; 285 | texPngReadPixels = &texPngReadPixels24; 286 | break; 287 | case PNG_COLOR_TYPE_PALETTE: 288 | pngTexture.palette = NULL; 289 | pngTexture.numPalette = 0; 290 | pngTexture.trans = NULL; 291 | pngTexture.numTrans = 0; 292 | 293 | png_get_PLTE(pngPtr, infoPtr, &pngTexture.palette, &pngTexture.numPalette); 294 | png_get_tRNS(pngPtr, infoPtr, &pngTexture.trans, &pngTexture.numTrans, NULL); 295 | texture->ClutPSM = GS_PSM_CT32; 296 | 297 | if (bitDepth == 4) 298 | { 299 | texture->PSM = GS_PSM_T4; 300 | texture->Clut = memalign(128, gsKit_texture_size_ee(8, 2, GS_PSM_CT32)); 301 | memset(texture->Clut, 0, gsKit_texture_size_ee(8, 2, GS_PSM_CT32)); 302 | 303 | texPngReadPixels = &texPngReadPixels4; 304 | } 305 | else 306 | { 307 | texture->PSM = GS_PSM_T8; 308 | texture->Clut = memalign(128, gsKit_texture_size_ee(16, 16, GS_PSM_CT32)); 309 | memset(texture->Clut, 0, gsKit_texture_size_ee(16, 16, GS_PSM_CT32)); 310 | 311 | texPngReadPixels = &texPngReadPixels8; 312 | } 313 | break; 314 | default: 315 | return texPngEnd(pngPtr, infoPtr, -6); 316 | } 317 | 318 | if (texSizeValidate(texture->Width, texture->Height, texture->PSM) < 0) 319 | { 320 | if (texture->Clut) 321 | { 322 | free(texture->Clut); 323 | texture->Clut = NULL; 324 | } 325 | 326 | return texPngEnd(pngPtr, infoPtr, -7); 327 | } 328 | 329 | texPngReadData(texture, pngPtr, infoPtr, texPngReadPixels); 330 | 331 | return texPngEnd(pngPtr, infoPtr, 0); 332 | } 333 | -------------------------------------------------------------------------------- /kelftool/kelftool.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parrado/SoftDev2/8a1c32cc257b09fa78ec3196bf2639856e45adf2/kelftool/kelftool.elf -------------------------------------------------------------------------------- /launcher-hdd/elf-loader/Makefile: -------------------------------------------------------------------------------- 1 | # _____ ___ ____ ___ ____ 2 | # ____| | ____| | | |____| 3 | # | ___| |____ ___| ____| | \ PS2DEV Open Source Project. 4 | #----------------------------------------------------------------------- 5 | # (c) 2020 Francisco Javier Trujillo Mata 6 | # Licenced under Academic Free License version 2.0 7 | # Review ps2sdk README & LICENSE files for further details. 8 | 9 | ### Adjust these three, for PS2Link compatibility tests 10 | ### Old LaunchELF used LA=0x90000, SA=0xB0000, SS=0x08000 11 | LOADADDR = 0x90000 12 | STACKADDR = 0xA8000 13 | STACKSIZE = 0x04000 14 | 15 | ifeq ($(DEBUG),1) 16 | LOADADDR = 0x1700000 17 | STACKADDR = 0x1720000 18 | STACKSIZE = 0x08000 19 | endif 20 | 21 | LDPARAMS := -Wl,--defsym -Wl,_stack_size=$(STACKSIZE) -Wl,--defsym -Wl,_stack=$(STACKADDR) 22 | 23 | EE_LDFLAGS += -Wl,-Ttext -Wl,$(LOADADDR) -s $(LDPARAMS) 24 | 25 | EE_BIN = loader.elf 26 | 27 | EE_OBJS = loader.o 28 | 29 | EE_LIBS = 30 | ifeq ($(DEBUG),1) 31 | EE_LIBS += -ldebug 32 | endif 33 | 34 | all: $(EE_BIN) 35 | 36 | clean: 37 | rm -f -r $(EE_OBJS) $(EE_BIN) 38 | 39 | # Include makefiles 40 | include $(PS2SDK)/samples/Makefile.pref 41 | include $(PS2SDK)/samples/Makefile.eeglobal 42 | -------------------------------------------------------------------------------- /launcher-hdd/elf-loader/loader.c: -------------------------------------------------------------------------------- 1 | //-------------------------------------------------------------- 2 | //File name: loader.c 3 | //-------------------------------------------------------------- 4 | //dlanor: This subprogram has been modified to minimize the code 5 | //dlanor: size of the resident loader portion. Some of the parts 6 | //dlanor: that were moved into the main program include loading 7 | //dlanor: of all IRXs and mounting pfs0: for ELFs on hdd. 8 | //dlanor: Another change was to skip threading in favor of ExecPS2 9 | /*================================================================== 10 | == == 11 | == Copyright(c)2004 Adam Metcalf(gamblore_@hotmail.com) == 12 | == Copyright(c)2004 Thomas Hawcroft(t0mb0la@yahoo.com) == 13 | == This file is subject to terms and conditions shown in the == 14 | == file LICENSE which should be kept in the top folder of == 15 | == this distribution. == 16 | == == 17 | == Portions of this code taken from PS2Link: == 18 | == pkoLoadElf == 19 | == wipeUserMemory == 20 | == (C) 2003 Tord Lindstrom (pukko@home.se) == 21 | == (C) 2003 adresd (adresd_ps2dev@yahoo.com) == 22 | == Portions of this code taken from Independence MC exploit == 23 | == tLoadElf == 24 | == LoadAndRunHDDElf == 25 | == (C) 2003 Marcus Brown == 26 | == == 27 | ==================================================================*/ 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #define ELF_MAGIC 0x464c457f 37 | 38 | void _ps2sdk_libc_init() {} 39 | void _ps2sdk_libc_deinit() {} 40 | //Code for OSDSYS patching was taken from FMCB 1.8 sources 41 | 42 | u32 execps2_code[] = { 43 | 0x24030007, // li v1, 7 44 | 0x0000000c, // syscall 45 | 0x03e00008, // jr ra 46 | 0x00000000 // nop 47 | }; 48 | u32 execps2_mask[] = { 49 | 0xffffffff, 50 | 0xffffffff, 51 | 0xffffffff, 52 | 0xffffffff}; 53 | 54 | //========================================================================= 55 | // SkipHdd patch for v3, v4 (those not supporting "SkipHdd" arg) 56 | 57 | u32 pattern10[] = { 58 | // Code near MC Update & HDD load 59 | 0x0c000000, // jal CheckMcUpdate 60 | 0x0220282d, // daddu a1, s1, zero 61 | 0x3c04002a, // lui a0, 0x002a #SkipHdd jump must be here 62 | 0x0000282d, // daddu a1, zero, zero #arg1: 0 63 | 0x24840000, // addiu a0, a0, 0xXXXX #arg0: "rom0:ATAD" 64 | 0x0c000000, // jal LoadModule 65 | 0x0000302d, // daduu a2, zero, zero #arg2: 0 66 | 0x04400000 // bltz v0, Exit_HddLoad 67 | }; 68 | u32 pattern10_mask[] = { 69 | 0xfc000000, 70 | 0xffffffff, 71 | 0xffffffff, 72 | 0xffffffff, 73 | 0xffff0000, 74 | 0xfc000000, 75 | 0xffffffff, 76 | 0xffff0000}; 77 | 78 | //-------------------------------------------------------------- 79 | u8 *find_bytes_with_mask(u8 *buf, u32 bufsize, u8 *bytes, u8 *mask, u32 len) 80 | { 81 | u32 i, j; 82 | 83 | for (i = 0; i < bufsize - len; i++) 84 | { 85 | for (j = 0; j < len; j++) 86 | { 87 | if ((buf[i + j] & mask[j]) != bytes[j]) 88 | break; 89 | } 90 | if (j == len) 91 | return &buf[i]; 92 | } 93 | return NULL; 94 | } 95 | //-------------------------------------------------------------- 96 | u8 *find_string(const u8 *string, u8 *buf, u32 bufsize) 97 | { 98 | u32 i; 99 | const u8 *s, *p; 100 | 101 | for (i = 0; i < bufsize; i++) 102 | { 103 | s = string; 104 | for (p = buf + i; *s && *s == *p; s++, p++) 105 | ; 106 | if (!*s) 107 | return (buf + i); 108 | } 109 | return NULL; 110 | } 111 | void patch_skip_hdd(u8 *osd) 112 | { 113 | u8 *ptr; 114 | u32 addr; 115 | 116 | // Search code near MC Update & HDD load 117 | ptr = find_bytes_with_mask(osd, 0x00100000, (u8 *)pattern10, (u8 *)pattern10_mask, sizeof(pattern10)); 118 | if (!ptr) 119 | return; 120 | addr = (u32)ptr; 121 | 122 | // Place "beq zero, zero, Exit_HddLoad" just after CheckMcUpdate() call 123 | _sw(0x10000000 + ((signed short)(_lw(addr + 28) & 0xffff) + 5), addr + 8); 124 | } 125 | 126 | void patch_and_execute_osdsys(void *epc, void *gp) 127 | { 128 | 129 | int n = 0; 130 | char *args[5], *ptr; 131 | 132 | args[n++] = "rom0:"; 133 | args[n++] = "BootBrowser"; // triggers BootBrowser to reach internal mc browser 134 | args[n++] = "SkipMc"; // Skip mc?:/BREXEC-SYSTEM/osdxxx.elf update on v5 and above 135 | 136 | if (find_string("SkipHdd", (u8 *)epc, 0x100000)) // triggers SkipHdd arg 137 | args[n++] = "SkipHdd"; // Skip Hddload on v5 and above 138 | else 139 | patch_skip_hdd((u8 *)epc); // SkipHdd patch for v3 & v4 140 | 141 | // To avoid loop in OSDSYS (Handle those models not supporting SkipMc arg) : 142 | while ((ptr = find_string("EXEC-SYSTEM", (u8 *)epc, 0x100000))) 143 | strncpy(ptr, "EXEC-OSDSYS", 11); 144 | 145 | SifExitRpc(); 146 | FlushCache(0); 147 | FlushCache(2); 148 | 149 | ExecPS2(epc, gp, n, args); 150 | } 151 | 152 | //-------------------------------------------------------------- 153 | //End of data declarations 154 | //-------------------------------------------------------------- 155 | //Start of function code: 156 | //-------------------------------------------------------------- 157 | // Clear user memory 158 | // PS2Link (C) 2003 Tord Lindstrom (pukko@home.se) 159 | // (C) 2003 adresd (adresd_ps2dev@yahoo.com) 160 | //-------------------------------------------------------------- 161 | void wipeUserMem(void) 162 | { 163 | int i; 164 | for (i = 0x100000; i < GetMemorySize(); i += 64) 165 | { 166 | asm volatile( 167 | "\tsq $0, 0(%0) \n" 168 | "\tsq $0, 16(%0) \n" 169 | "\tsq $0, 32(%0) \n" 170 | "\tsq $0, 48(%0) \n" ::"r"(i)); 171 | } 172 | } 173 | 174 | //-------------------------------------------------------------- 175 | //End of func: void wipeUserMem(void) 176 | //-------------------------------------------------------------- 177 | // *** MAIN *** 178 | //-------------------------------------------------------------- 179 | int main(int argc, char *argv[]) 180 | { 181 | static t_ExecData elfdata; 182 | char *target, *path; 183 | char *args[2]; 184 | int ret; 185 | u8 *ptr; 186 | FILE *fh; 187 | u32 ident; 188 | 189 | // Initialize 190 | SifInitRpc(0); 191 | wipeUserMem(); 192 | 193 | if (argc != 2) 194 | { // arg1=path to ELF, arg2=partition to mount 195 | SifExitRpc(); 196 | return -EINVAL; 197 | } 198 | 199 | target = argv[0]; 200 | path = argv[1]; 201 | 202 | //Writeback data cache before loading ELF. 203 | FlushCache(0); 204 | 205 | //Open file to read magic number 206 | fh = fopen(target, "r"); 207 | if (fh) 208 | { 209 | fread(&ident, sizeof(u32), 1, fh); 210 | fclose(fh); 211 | 212 | //Checks magic number 213 | if (ident == ELF_MAGIC) 214 | //Loads regular ELF 215 | ret = SifLoadElf(target, &elfdata); 216 | else 217 | //Loads KELF 218 | ret = SifLoadElfEncrypted(target, &elfdata); 219 | 220 | if (ret == 0) 221 | { 222 | argc = 1; 223 | args[0] = path; 224 | 225 | //If OSDSYS load requested then patch before launching (taken from FMCB 1.8 source code) 226 | if (strncmp(target, "rom0:OSDSYS", 11) == 0) 227 | { 228 | 229 | // Find the ExecPS2 function in the unpacker starting from 0x100000. 230 | ptr = find_bytes_with_mask((u8 *)0x100000, 0x1000, (u8 *)execps2_code, (u8 *)execps2_mask, sizeof(execps2_code)); 231 | 232 | // If found replace it with a call to our patch_and_execute_osdsys() function. 233 | if (ptr) 234 | { 235 | u32 instr = 0x0c000000; 236 | instr |= ((u32)patch_and_execute_osdsys >> 2); 237 | *(u32 *)ptr = instr; 238 | *(u32 *)&ptr[4] = 0; 239 | } 240 | } 241 | 242 | //IF HDD-OSD requested 243 | if ((strncmp(target, "pfs0:/osd/hosdsys.elf", 21) == 0)||(strncmp(target, "pfs0:/osd100/hosdsys.elf", 24) == 0)) 244 | { 245 | args[1] = "BootBrowser"; 246 | argc = 2; 247 | } 248 | 249 | if (strncmp(path, "hdd", 3) == 0 && (path[3] >= '0' && path[3] <= ':')) 250 | { /* Final IOP reset, to fill the IOP with the default modules. 251 | It appears that it was once a thing for the booting software to leave the IOP with the required IOP modules. 252 | This can be seen in OSDSYS v1.0x (no IOP reboot) and the mechanism to boot DVD player updates (OSDSYS will get LoadExecPS2 to load SIO2 modules). 253 | However, it changed with the introduction of the HDD unit, as the software booted may be built with a different SDK revision. 254 | 255 | Reboot the IOP, to leave it in a clean & consistent state. 256 | But do not do that for boot targets on other devices, for backward-compatibility with older (homebrew) software. */ 257 | while (!SifIopReset("", 0)) 258 | { 259 | }; 260 | while (!SifIopSync()) 261 | { 262 | }; 263 | } 264 | 265 | SifExitRpc(); 266 | 267 | FlushCache(0); 268 | FlushCache(2); 269 | 270 | ExecPS2((void *)elfdata.epc, (void *)elfdata.gp, argc, args); 271 | return 0; 272 | } 273 | else 274 | { 275 | SifExitRpc(); 276 | return -ENOENT; 277 | } 278 | } 279 | else 280 | { 281 | SifExitRpc(); 282 | return -ENOENT; 283 | } 284 | } 285 | //-------------------------------------------------------------- 286 | //End of func: int main(int argc, char *argv[]) 287 | //-------------------------------------------------------------- 288 | //End of file: loader.c 289 | //-------------------------------------------------------------- 290 | -------------------------------------------------------------------------------- /launcher-hdd/payload/Makefile: -------------------------------------------------------------------------------- 1 | LOADADDR = 0x100000 2 | EE_TARGET=payload 3 | EE_BIN = $(EE_TARGET).elf 4 | EE_BIN_RAW = $(EE_TARGET).bin 5 | EE_BIN_STRIPPED = $(EE_TARGET)-stripped.elf 6 | 7 | EE_BIN_RAW = $(EE_TARGET).bin 8 | EE_OBJS = main.o pad.o elf_loader_elf.o $(EE_IOP_OBJS) 9 | EE_IOP_OBJS = IOMANX_irx.o FILEXIO_irx.o SIO2MAN_irx.o PADMAN_irx.o DEV9_irx.o ATAD_irx.o HDD_irx.o PFS_irx.o 10 | 11 | 12 | EE_LDFLAGS = -L $(PS2SDK)/ee/lib -Wl,--gc-sections -Wl,-Ttext -Wl,$(LOADADDR) 13 | EE_LIBS = -lpatches -lfileXio -lpadx 14 | EE_INCS= -I$(GSKIT)/include -I$(PS2SDK)/ports/include 15 | EE_CFLAGS=-G0 -I $(PS2SDK)/ee/include -I $(PS2SDK)/common/include -D_EE -Os -Wall -ffunction-sections -fdata-sections -DNEWLIB_PORT_AWARE 16 | 17 | 18 | all: 19 | $(MAKE) $(EE_BIN_RAW) 20 | 21 | 22 | 23 | clean: 24 | $(MAKE) -C ../elf-loader/ clean 25 | rm -f *.elf *.ELF *.irx *.o *.s *.bin DEV9_irx.c IOMANX_irx.c FILEXIO_irx.c SIO2MAN_irx.c PADMAN_irx.c ATAD_irx.c HDD_irx.c PFS_irx.c 26 | 27 | DEV9_irx.c: $(PS2SDK)/iop/irx/ps2dev9.irx 28 | bin2c $(PS2SDK)/iop/irx/ps2dev9.irx DEV9_irx.c DEV9_irx 29 | 30 | IOMANX_irx.c: $(PS2SDK)/iop/irx/iomanX.irx 31 | bin2c $(PS2SDK)/iop/irx/iomanX.irx IOMANX_irx.c IOMANX_irx 32 | 33 | FILEXIO_irx.c: $(PS2SDK)/iop/irx/fileXio.irx 34 | bin2c $(PS2SDK)/iop/irx/fileXio.irx FILEXIO_irx.c FILEXIO_irx 35 | 36 | SIO2MAN_irx.c: $(PS2SDK)/iop/irx/freesio2.irx 37 | bin2c $(PS2SDK)/iop/irx/freesio2.irx SIO2MAN_irx.c SIO2MAN_irx 38 | 39 | PADMAN_irx.c: $(PS2SDK)/iop/irx/freepad.irx 40 | bin2c $(PS2SDK)/iop/irx/freepad.irx PADMAN_irx.c PADMAN_irx 41 | 42 | 43 | ATAD_irx.c: $(PS2SDK)/iop/irx/ps2atad.irx 44 | bin2c $(PS2SDK)/iop/irx/ps2atad.irx ATAD_irx.c ATAD_irx 45 | 46 | HDD_irx.c: $(PS2SDK)/iop/irx/ps2hdd.irx 47 | bin2c $(PS2SDK)/iop/irx/ps2hdd.irx HDD_irx.c HDD_irx 48 | 49 | PFS_irx.c: $(PS2SDK)/iop/irx/ps2fs.irx 50 | bin2c $(PS2SDK)/iop/irx/ps2fs.irx PFS_irx.c PFS_irx 51 | 52 | elf_loader_elf.s: 53 | $(MAKE) -C ../elf-loader/ 54 | bin2s ../elf-loader/loader.elf elf_loader_elf.s elf_loader_elf 55 | 56 | 57 | 58 | 59 | $(EE_BIN_STRIPPED): $(EE_BIN) 60 | $(EE_STRIP) -s -R .comment -R .gnu.version --strip-unneeded -o $@ $< 61 | 62 | $(EE_BIN_RAW): $(EE_BIN_STRIPPED) 63 | $(EE_OBJCOPY) -O binary -v $< $@ 64 | 65 | 66 | 67 | include $(PS2SDK)/samples/Makefile.pref 68 | include $(PS2SDK)/samples/Makefile.eeglobal 69 | 70 | -------------------------------------------------------------------------------- /launcher-hdd/payload/main.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "pad.h" 24 | 25 | #define NTSC 2 26 | #define PAL 3 27 | 28 | #define DELAY 100L 29 | 30 | // ELF-loading stuff 31 | #define ELF_MAGIC 0x464c457f 32 | #define ELF_PT_LOAD 1 33 | 34 | //Extern references to embedded IRX/loaders. 35 | extern u8 elf_loader_elf[]; 36 | extern int elf_size_loader_elf; 37 | 38 | extern unsigned char IOMANX_irx[]; 39 | extern unsigned int size_IOMANX_irx; 40 | 41 | extern unsigned char FILEXIO_irx[]; 42 | extern unsigned int size_FILEXIO_irx; 43 | 44 | extern unsigned char SIO2MAN_irx[]; 45 | extern unsigned int size_SIO2MAN_irx; 46 | 47 | extern unsigned char PADMAN_irx[]; 48 | extern unsigned int size_PADMAN_irx; 49 | 50 | extern unsigned char DEV9_irx[]; 51 | extern unsigned int size_DEV9_irx; 52 | 53 | extern unsigned char ATAD_irx[]; 54 | extern unsigned int size_ATAD_irx; 55 | 56 | extern unsigned char HDD_irx[]; 57 | extern unsigned int size_HDD_irx; 58 | 59 | extern unsigned char PFS_irx[]; 60 | extern unsigned int size_PFS_irx; 61 | 62 | int VMode = NTSC; 63 | extern void *_gp; 64 | 65 | //------------------------------ 66 | typedef struct 67 | { 68 | u8 ident[16]; // struct definition for ELF object header 69 | u16 type; 70 | u16 machine; 71 | u32 version; 72 | u32 entry; 73 | u32 phoff; 74 | u32 shoff; 75 | u32 flags; 76 | u16 ehsize; 77 | u16 phentsize; 78 | u16 phnum; 79 | u16 shentsize; 80 | u16 shnum; 81 | u16 shstrndx; 82 | } elf_header_t; 83 | //------------------------------ 84 | typedef struct 85 | { 86 | u32 type; // struct definition for ELF program section header 87 | u32 offset; 88 | void *vaddr; 89 | u32 paddr; 90 | u32 filesz; 91 | u32 memsz; 92 | u32 flags; 93 | u32 align; 94 | } elf_pheader_t; 95 | 96 | u8 romver[16]; 97 | char romver_region_char[1]; 98 | char ROMVersionNumStr[5]; 99 | 100 | u32 bios_version = 0; 101 | 102 | void ResetIOP() 103 | { 104 | 105 | SifInitRpc(0); 106 | while (!SifIopReset("", 0)) 107 | { 108 | }; 109 | while (!SifIopSync()) 110 | { 111 | }; 112 | SifInitRpc(0); 113 | } 114 | 115 | void InitPS2() 116 | { 117 | 118 | static const char PFS_args[] = "-n\0" 119 | "24\0" 120 | "-o\0" 121 | "8"; 122 | ResetIOP(); 123 | 124 | SifInitIopHeap(); 125 | SifLoadFileInit(); 126 | fioInit(); 127 | 128 | sbv_patch_enable_lmb(); 129 | sbv_patch_disable_prefix_check(); 130 | 131 | SifExecModuleBuffer(IOMANX_irx, size_IOMANX_irx, 0, NULL, NULL); 132 | SifExecModuleBuffer(FILEXIO_irx, size_FILEXIO_irx, 0, NULL, NULL); 133 | 134 | fileXioInit(); 135 | 136 | SifExecModuleBuffer(DEV9_irx, size_DEV9_irx, 0, NULL, NULL); 137 | SifExecModuleBuffer(SIO2MAN_irx, size_SIO2MAN_irx, 0, NULL, NULL); 138 | SifExecModuleBuffer(PADMAN_irx, size_PADMAN_irx, 0, NULL, NULL); 139 | PadInitPads(); 140 | 141 | if (SifExecModuleBuffer(ATAD_irx, size_ATAD_irx, 0, NULL, NULL) >= 0) 142 | { 143 | SifExecModuleBuffer(HDD_irx, size_HDD_irx, 0, NULL, NULL); 144 | SifExecModuleBuffer(PFS_irx, size_PFS_irx, sizeof(PFS_args), PFS_args, NULL); 145 | } 146 | 147 | SifExitIopHeap(); 148 | SifLoadFileExit(); 149 | } 150 | 151 | void LoadElf(char *filename, char *party) 152 | { 153 | 154 | u8 *boot_elf; 155 | elf_header_t *eh; 156 | elf_pheader_t *eph; 157 | void *pdata; 158 | int i; 159 | char *argv[2], bootpath[256]; 160 | 161 | if ((!strncmp(party, "hdd0:", 5)) && (!strncmp(filename, "pfs0:", 5))) 162 | { 163 | //If a path to a file on PFS is specified, change it to the standard format. 164 | //hdd0:partition:pfs:path/to/file 165 | if (strncmp(filename, "pfs0:", 5) == 0) 166 | { 167 | sprintf(bootpath, "%s:pfs:%s", party, &filename[5]); 168 | } 169 | else 170 | { 171 | sprintf(bootpath, "%s:%s", party, filename); 172 | } 173 | 174 | argv[0] = filename; 175 | argv[1] = bootpath; 176 | } 177 | else 178 | { 179 | argv[0] = filename; 180 | argv[1] = filename; 181 | } 182 | 183 | /* NB: LOADER.ELF is embedded */ 184 | boot_elf = (u8 *)elf_loader_elf; 185 | eh = (elf_header_t *)boot_elf; 186 | if (_lw((u32)&eh->ident) != ELF_MAGIC) 187 | asm volatile("break\n"); 188 | 189 | eph = (elf_pheader_t *)(boot_elf + eh->phoff); 190 | 191 | /* Scan through the ELF's program headers and copy them into RAM, then 192 | zero out any non-loaded regions. */ 193 | for (i = 0; i < eh->phnum; i++) 194 | { 195 | if (eph[i].type != ELF_PT_LOAD) 196 | continue; 197 | 198 | pdata = (void *)(boot_elf + eph[i].offset); 199 | memcpy(eph[i].vaddr, pdata, eph[i].filesz); 200 | 201 | if (eph[i].memsz > eph[i].filesz) 202 | memset(eph[i].vaddr + eph[i].filesz, 0, 203 | eph[i].memsz - eph[i].filesz); 204 | } 205 | 206 | /* Let's go. */ 207 | SifExitRpc(); 208 | FlushCache(0); 209 | FlushCache(2); 210 | 211 | ExecPS2((void *)eh->entry, NULL, 2, argv); 212 | } 213 | 214 | int file_exists(char filepath[]) 215 | { 216 | int fdn; 217 | 218 | fdn = open(filepath, O_RDONLY); 219 | if (fdn < 0) 220 | return 0; 221 | close(fdn); 222 | 223 | return 1; 224 | } 225 | 226 | int main(int argc, char *argv[]) 227 | { 228 | 229 | int lastKey = 0; 230 | int keyStatus; 231 | int isEarlyJap = 0; 232 | struct tms tstart, tstop; 233 | 234 | char *party = "hdd0:__sysconf"; 235 | char *hddosd_party = "hdd0:__system"; 236 | 237 | InitPS2(); 238 | 239 | int fdnr; 240 | if ((fdnr = open("rom0:ROMVER", O_RDONLY)) > 0) 241 | { // Reading ROMVER 242 | read(fdnr, romver, sizeof romver); 243 | close(fdnr); 244 | } 245 | 246 | // Getting region char 247 | romver_region_char[0] = (romver[4] == 'E' ? 'E' : (romver[4] == 'J' ? 'I' : (romver[4] == 'H' ? 'A' : (romver[4] == 'U' ? 'A' : romver[4])))); 248 | 249 | strncpy(ROMVersionNumStr, romver, 4); 250 | ROMVersionNumStr[4] = '\0'; 251 | bios_version = strtoul(ROMVersionNumStr, NULL, 16); 252 | 253 | if ((romver_region_char[0] == 'J') && (bios_version <= 0x120)) 254 | isEarlyJap = 1; 255 | 256 | if (fileXioMount("pfs0:", party, FIO_MT_RDONLY) == 0) 257 | { 258 | 259 | times(&tstart); 260 | //Stores last key during DELAY msec 261 | do 262 | { 263 | 264 | keyStatus = ReadCombinedPadStatus(); 265 | if (keyStatus) 266 | lastKey = keyStatus; 267 | times(&tstop); 268 | } while (tstop.tms_utime <= (tstart.tms_utime + DELAY)); 269 | 270 | //Deinits pad 271 | if (!isEarlyJap) 272 | { 273 | padPortClose(0, 0); 274 | padPortClose(1, 0); 275 | padEnd(); 276 | } 277 | 278 | if (lastKey & PAD_TRIANGLE) 279 | { 280 | //Check if HDD-OSD is installed 281 | fileXioUmount("pfs0:"); 282 | if (fileXioMount("pfs0:", hddosd_party, FIO_MT_RDONLY) == 0) 283 | { 284 | 285 | //Tests for FHDB 286 | if (file_exists("pfs0:/osd/osdmain.elf")) 287 | LoadElf("pfs0:/osd/osdmain.elf", hddosd_party); 288 | 289 | //Tests for two locations of HDD-OSD 290 | if (file_exists("pfs0:/osd/hosdsys.elf")) 291 | LoadElf("pfs0:/osd/hosdsys.elf", hddosd_party); 292 | 293 | if (file_exists("pfs0:/osd100/hosdsys.elf")) 294 | LoadElf("pfs0:/osd100/hosdsys.elf", hddosd_party); 295 | 296 | fileXioUmount("pfs0:"); 297 | } 298 | 299 | //If no HDD-OSD was found, then launch ROM OSD 300 | LoadElf("rom0:OSDSYS", "hdd0:"); 301 | } 302 | 303 | if (lastKey & PAD_CIRCLE) 304 | { 305 | 306 | if (file_exists("pfs0:/softdev2/ULE.ELF")) 307 | LoadElf("pfs0:/softdev2/ULE.ELF", party); 308 | 309 | if (file_exists("pfs0:/softdev2/OPNPS2LD.ELF")) 310 | LoadElf("pfs0:/softdev2/OPNPS2LD.ELF", party); 311 | } 312 | 313 | if (file_exists("pfs0:/softdev2/OPNPS2LD.ELF")) 314 | LoadElf("pfs0:/softdev2/OPNPS2LD.ELF", party); 315 | 316 | if (file_exists("pfs0:/softdev2/ULE.ELF")) 317 | LoadElf("pfs0:/softdev2/ULE.ELF", party); 318 | 319 | fileXioUmount("pfs0:"); 320 | } 321 | 322 | //Check if HDD-OSD is installed 323 | if (fileXioMount("pfs0:", hddosd_party, FIO_MT_RDONLY) == 0) 324 | { 325 | 326 | //Tests for FHDB 327 | if (file_exists("pfs0:/osd/osdmain.elf")) 328 | LoadElf("pfs0:/osd/osdmain.elf", hddosd_party); 329 | //Tests for two locations of HDD-OSD 330 | if (file_exists("pfs0:/osd/hosdsys.elf")) 331 | LoadElf("pfs0:/osd/hosdsys.elf", hddosd_party); 332 | 333 | if (file_exists("pfs0:/osd100/hosdsys.elf")) 334 | LoadElf("pfs0:/osd100/hosdsys.elf", hddosd_party); 335 | 336 | fileXioUmount("pfs0:"); 337 | } 338 | 339 | //If no HDD-OSD was found, then launch ROM OSD 340 | LoadElf("rom0:OSDSYS", "hdd0:"); 341 | 342 | return 0; 343 | } 344 | -------------------------------------------------------------------------------- /launcher-hdd/payload/pad.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pad.h" 8 | 9 | static unsigned char padArea[2][256] ALIGNED(64); 10 | static unsigned int old_pad[2]={0, 0}; 11 | 12 | void PadInitPads(void) 13 | { 14 | padInit(0); 15 | padPortOpen(0, 0, padArea[0]); 16 | padPortOpen(1, 0, padArea[1]); 17 | 18 | old_pad[0] = 0; 19 | old_pad[1] = 0; 20 | } 21 | 22 | void PadDeinitPads(void) 23 | { 24 | padPortClose(0, 0); 25 | padPortClose(1, 0); 26 | padEnd(); 27 | } 28 | 29 | int ReadPadStatus_raw(int port, int slot){ 30 | struct padButtonStatus buttons; 31 | u32 paddata; 32 | 33 | paddata=0; 34 | if(padRead(port, slot, &buttons) != 0){ 35 | paddata = 0xffff ^ buttons.btns; 36 | } 37 | 38 | return paddata; 39 | } 40 | 41 | int ReadCombinedPadStatus_raw(void){ 42 | return(ReadPadStatus_raw(0, 0)|ReadPadStatus_raw(1, 0)); 43 | } 44 | 45 | int ReadPadStatus(int port, int slot){ 46 | struct padButtonStatus buttons; 47 | u32 new_pad, paddata; 48 | 49 | new_pad=0; 50 | if (padRead(port, slot, &buttons) != 0) { 51 | paddata = 0xffff ^ buttons.btns; 52 | 53 | new_pad = paddata & ~old_pad[port]; 54 | old_pad[port] = paddata; 55 | } 56 | 57 | return new_pad; 58 | } 59 | 60 | int ReadCombinedPadStatus(void){ 61 | return(ReadPadStatus(0, 0)|ReadPadStatus(1, 0)); 62 | } 63 | -------------------------------------------------------------------------------- /launcher-hdd/payload/pad.h: -------------------------------------------------------------------------------- 1 | void PadInitPads(void); 2 | void PadDeinitPads(void); 3 | 4 | int ReadPadStatus_raw(int port, int slot); 5 | int ReadCombinedPadStatus_raw(void); 6 | int ReadPadStatus(int port, int slot); 7 | int ReadCombinedPadStatus(void); 8 | --------------------------------------------------------------------------------