From c342d9539e166a3793b25f5a4337085fd1a666c5 Mon Sep 17 00:00:00 2001 From: Julian Uy Date: Tue, 30 Jun 2026 15:09:38 -0500 Subject: [PATCH 1/3] feat: [sbv] add support for patching romdrv rom1 info --- ee/sbv/Makefile | 13 ++++- ee/sbv/include/sbv_patches.h | 15 ++++++ ee/sbv/src/patch_romdrv_set_rom1_info.c | 66 +++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 ee/sbv/src/patch_romdrv_set_rom1_info.c diff --git a/ee/sbv/Makefile b/ee/sbv/Makefile index 318172c6fe23..1d932a5bea6d 100644 --- a/ee/sbv/Makefile +++ b/ee/sbv/Makefile @@ -8,8 +8,17 @@ EE_LIB = libpatches.a -EE_OBJS = smem.o smod.o slib.o patch_enable_lmb.o patch_disable_prefix_check.o \ - patch_user_mem_clear.o patch_fileio.o common.o erl-support.o +EE_OBJS = \ + smem.o \ + smod.o \ + slib.o \ + patch_enable_lmb.o \ + patch_disable_prefix_check.o \ + patch_user_mem_clear.o \ + patch_romdrv_set_rom1_info.o \ + patch_fileio.o \ + common.o \ + erl-support.o include $(PS2SDKSRC)/Defs.make include $(PS2SDKSRC)/ee/Rules.lib.make diff --git a/ee/sbv/include/sbv_patches.h b/ee/sbv/include/sbv_patches.h index adaaf3b36dda..ac0e7fd95997 100644 --- a/ee/sbv/include/sbv_patches.h +++ b/ee/sbv/include/sbv_patches.h @@ -57,6 +57,21 @@ extern int sbv_patch_user_mem_clear(void *start); * 2. The RPC dispatcher code for remove() has a missing break, resulting in mkdir() being called after remove() returns. */ extern int sbv_patch_fileio(void); +/** + * @param iop_reset_addr address of RESET-headered ROMDIR block in IOP memory + * @param romdir_size size of ROMDIR block in IOP memory + * @return 0: success, none-zero: error + * + * Patches data inside ROMDRV to point to an arbritary RESET image in memory. + * This avoids requiring code patches, such as those done for the following: + * * LoadModuleBuffer enable patch + * * Disable prefix check patch + * As a result, it is compatible with ROMDRV found in the following: + * * SDK 1.3 (protokernel) + * * SDK 1.6 (most systems) + * * SDK 3.1.0 (last SDK, flashable in ROM on DTL-T) + */ +extern int sbv_patch_romdrv_set_rom1_info(void *iop_reset_addr, int romdir_size); #ifdef __cplusplus } diff --git a/ee/sbv/src/patch_romdrv_set_rom1_info.c b/ee/sbv/src/patch_romdrv_set_rom1_info.c new file mode 100644 index 000000000000..d13f162e729a --- /dev/null +++ b/ee/sbv/src/patch_romdrv_set_rom1_info.c @@ -0,0 +1,66 @@ +/* +# _____ ___ ____ ___ ____ +# ____| | ____| | | |____| +# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. +#----------------------------------------------------------------------- +# Copyright (c) 2003 Marcus R. Brown +# Licenced under Academic Free License version 2.0 +# Review ps2sdk README & LICENSE files for further details. +*/ + +/** + * @file + * Patches data inside ROMDRV to point to an arbritary RESET image in memory. + */ + +#include +#include +#include +#include + +#include "smod.h" +#include "slib.h" + +#include "common.h" + +/* from common.c */ +extern struct smem_buf smem_buf; + +int sbv_patch_romdrv_set_rom1_info(void *iop_reset_addr, int romdir_size) +{ + SifRpcReceiveData_t rdata; + smod_mod_info_t romdrv_info; + u32 *data; + SifDmaTransfer_t dmat[1]; + int trid; + + /* Find the romdrv module. */ + if (!smod_get_mod_by_name("ROM_file_driver", &romdrv_info)) + return -1; + + dmat[0].src = &smem_buf; + dmat[0].size = 64; + dmat[0].dest = (void *)(romdrv_info.text_start + romdrv_info.text_size + romdrv_info.data_size + 0x40); + dmat[0].attr = 0; + + /* Get offset into rom mount information in bss section */ + SyncDCache(dmat[0].src, ((u8 *)dmat[0].src) + dmat[0].size); + if (sceSifGetOtherData(&rdata, dmat[0].dest, dmat[0].src, dmat[0].size, 0) < 0) + return 1; + data = UNCACHED_SEG(dmat[0].src); + /* Ensure data contains rom0: information */ + if (data[0] != 0xBFC00000 || data[1] <= data[0] || data[2] <= data[1]) + return 1; + + /* ImageStart for rom1: */ + data[3] = (u32)iop_reset_addr; + /* RomdirStart for rom1: */ + data[4] = data[3]; + /* RomdirEnd for rom1: */ + data[5] = data[3] + romdir_size; + + sceSifWriteBackDCache(dmat[0].src, dmat[0].size); + while (!(trid = sceSifSetDma(dmat, sizeof(dmat) / sizeof(dmat[0])))); + while (sceSifDmaStat(trid) >= 0); + return 0; +} From 2fd782312b2ba852b90ef565c77793c8a1f3d41a Mon Sep 17 00:00:00 2001 From: Julian Uy Date: Tue, 30 Jun 2026 15:09:38 -0500 Subject: [PATCH 2/3] compat: [romdrv] make internal data layout same as official --- iop/fs/romdrv/src/romdrv.c | 51 ++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/iop/fs/romdrv/src/romdrv.c b/iop/fs/romdrv/src/romdrv.c index b172227ce38f..61c46902c306 100644 --- a/iop/fs/romdrv/src/romdrv.c +++ b/iop/fs/romdrv/src/romdrv.c @@ -36,9 +36,16 @@ struct RomFileSlot int offset; }; -static struct RomImg images[ROMDRV_MAX_IMAGES]; -static struct RomdirFileStat fileStats[ROMDRV_MAX_FILES]; -static struct RomFileSlot fileSlots[ROMDRV_MAX_FILES]; +// For compatibility with sbv_patch_romdrv_set_rom1_info, the bss section needs +// to be laid out in exactly this manner. +struct RomdrvInternalData +{ + struct RomFileSlot fileSlots[ROMDRV_MAX_FILES]; + struct RomImg images[ROMDRV_MAX_IMAGES]; + struct RomdirFileStat fileStats[ROMDRV_MAX_FILES]; +}; + +static struct RomdrvInternalData romdrvData; /* Function prototypes */ static int init(void); @@ -103,11 +110,11 @@ int _start(int argc, char **argv) static int init(void) { - memset(images, 0, sizeof(images)); - memset(fileStats, 0, sizeof(fileStats)); - memset(fileSlots, 0, sizeof(fileSlots)); + memset(romdrvData.images, 0, sizeof(romdrvData.images)); + memset(romdrvData.fileStats, 0, sizeof(romdrvData.fileStats)); + memset(romdrvData.fileSlots, 0, sizeof(romdrvData.fileSlots)); // Add DEV2 (Boot ROM) as rom0. Unlike ROMDRV v1.1, the code for DEV1 is in the ADDDRV module. - romGetImageStat((const void *)0xbfc00000, (const void *)0xbfc40000, &images[0]); + romGetImageStat((const void *)0xbfc00000, (const void *)0xbfc40000, &romdrvData.images[0]); return 0; } @@ -119,8 +126,8 @@ int romAddDevice(int unit, const void *image) if (unit < ROMDRV_MAX_IMAGES) { CpuSuspendIntr(&OldState); - if (images[unit].ImageStart == NULL) { - stat = romGetImageStat(image, (const void *)((const u8 *)image + 0x8000), &images[unit]); + if (romdrvData.images[unit].ImageStart == NULL) { + stat = romGetImageStat(image, (const void *)((const u8 *)image + 0x8000), &romdrvData.images[unit]); CpuResumeIntr(OldState); result = stat != NULL ? 0 : ROMDRV_ADD_BAD_IMAGE; @@ -142,8 +149,8 @@ int romDelDevice(int unit) if (unit < ROMDRV_MAX_IMAGES) { CpuSuspendIntr(&OldState); - if (images[unit].ImageStart != NULL) { - images[unit].ImageStart = 0; + if (romdrvData.images[unit].ImageStart != NULL) { + romdrvData.images[unit].ImageStart = 0; CpuResumeIntr(OldState); result = 0; } else { @@ -164,7 +171,7 @@ static int romOpen(iop_file_t *fd, const char *path, int mode) if (fd->unit < ROMDRV_MAX_IMAGES) { struct RomImg *image; - image = &images[fd->unit]; + image = &romdrvData.images[fd->unit]; if (image->ImageStart != NULL) { int slotNum, result; @@ -178,7 +185,7 @@ static int romOpen(iop_file_t *fd, const char *path, int mode) // Locate a free file slot. for (slotNum = 0; slotNum < ROMDRV_MAX_FILES; slotNum++) { - if (fileStats[slotNum].data == NULL) { + if (romdrvData.fileStats[slotNum].data == NULL) { break; } } @@ -187,14 +194,14 @@ static int romOpen(iop_file_t *fd, const char *path, int mode) return -ENOMEM; } - stat = GetFileStatFromImage(image, path, &fileStats[slotNum]); + stat = GetFileStatFromImage(image, path, &romdrvData.fileStats[slotNum]); CpuResumeIntr(OldState); if (stat != NULL) { result = 0; - fileSlots[slotNum].slotNum = slotNum; - fileSlots[slotNum].offset = 0; - fd->privdata = &fileSlots[slotNum]; + romdrvData.fileSlots[slotNum].slotNum = slotNum; + romdrvData.fileSlots[slotNum].offset = 0; + fd->privdata = &romdrvData.fileSlots[slotNum]; } else { result = -ENOENT; } @@ -216,7 +223,7 @@ static int romClose(iop_file_t *fd) if (slot->slotNum < ROMDRV_MAX_FILES) { struct RomdirFileStat *stat; - stat = &fileStats[slot->slotNum]; + stat = &romdrvData.fileStats[slot->slotNum]; if (stat->data != NULL) { stat->data = NULL; @@ -236,7 +243,7 @@ static int romRead(iop_file_t *fd, void *buffer, int size) struct RomFileSlot *slot = (struct RomFileSlot *)fd->privdata; struct RomdirFileStat *stat; - stat = &fileStats[slot->slotNum]; + stat = &romdrvData.fileStats[slot->slotNum]; // Bounds check. if (stat->romdirent->size < (u32)(slot->offset + size)) { @@ -261,7 +268,7 @@ static int romLseek(iop_file_t *fd, int offset, int whence) u32 size; int newOffset; - stat = &fileStats[slot->slotNum]; + stat = &romdrvData.fileStats[slot->slotNum]; size = stat->romdirent->size; switch (whence) { @@ -368,8 +375,8 @@ const struct RomImg *romGetDevice(int unit) if (unit < ROMDRV_MAX_IMAGES) { CpuSuspendIntr(&OldState); - if (images[unit].ImageStart != NULL) { - result = &images[unit]; + if (romdrvData.images[unit].ImageStart != NULL) { + result = &romdrvData.images[unit]; CpuResumeIntr(OldState); } else { CpuResumeIntr(OldState); From 008fd16dbfb2244a217af5fc1f7b1885f572f503 Mon Sep 17 00:00:00 2001 From: Julian Uy Date: Tue, 30 Jun 2026 15:09:38 -0500 Subject: [PATCH 3/3] change: [iopreboot] Changes to avoid using imgdrv Use sbv_patch_romdrv_set_rom1_info Remove const specifier from ioprp image, since it gets modified Allow generateIOPBTCONF_img to work on already-patched images Allow using unencapsulated IRX for SifIopRebootBufferEncrypted Avoid needing to load SYSCLIB --- ee/iopreboot/Makefile | 24 +-- ee/iopreboot/include/iopcontrol_special.h | 2 +- ee/iopreboot/src/SifIopRebootBuffer.c | 231 +++++++++------------- ee/iopreboot/src/imgdrv/Makefile | 19 -- ee/iopreboot/src/imgdrv/src/imgdrv.c | 90 --------- ee/iopreboot/src/imgdrv/src/imports.lst | 3 - ee/iopreboot/src/imgdrv/src/irx_imports.h | 18 -- 7 files changed, 94 insertions(+), 293 deletions(-) delete mode 100644 ee/iopreboot/src/imgdrv/Makefile delete mode 100644 ee/iopreboot/src/imgdrv/src/imgdrv.c delete mode 100644 ee/iopreboot/src/imgdrv/src/imports.lst delete mode 100644 ee/iopreboot/src/imgdrv/src/irx_imports.h diff --git a/ee/iopreboot/Makefile b/ee/iopreboot/Makefile index 34f8f70daeda..fde8c8f96170 100644 --- a/ee/iopreboot/Makefile +++ b/ee/iopreboot/Makefile @@ -6,10 +6,9 @@ # Review ps2sdk README & LICENSE files for further details. IOPCONTROL_SPECIAL_EE_OBJS = _iopcontrol_special_internals.o SifIopRebootBufferEncrypted.o SifIopRebootBuffer.o -IOPCONTROL_SPECIAL_IOP_OBJS = imgdrv_irx.o IOPCONTROL_SPECIAL_OBJS = -EE_OBJS = $(IOPCONTROL_SPECIAL_EE_OBJS) $(IOPCONTROL_SPECIAL_IOP_OBJS) erl-support.o +EE_OBJS = $(IOPCONTROL_SPECIAL_EE_OBJS) erl-support.o include $(PS2SDKSRC)/Defs.make include $(PS2SDKSRC)/ee/Rules.lib.make @@ -19,24 +18,3 @@ include $(PS2SDKSRC)/ee/Rules.release $(IOPCONTROL_SPECIAL_EE_OBJS:%=$(EE_OBJS_DIR)%): $(EE_SRC_DIR)SifIopRebootBuffer.c $(DIR_GUARD) $(EE_C_COMPILE) -I$(PS2SDKSRC)/ee/sbv/include -DF_$(*:$(EE_OBJS_DIR)%=%) $< -c -o $@ - -$(EE_OBJS_DIR)imgdrv_irx.o: $(EE_OBJS_DIR)imgdrv_irx.c - $(DIR_GUARD) - $(EE_C_COMPILE) $< -c -o $@ - -$(PS2SDKSRC)/tools/bin2c/bin/bin2c: $(PS2SDKSRC)/tools/bin2c - $(MAKEREC) $< - -$(EE_SRC_DIR)imgdrv/irx/imgdrv.irx: $(EE_SRC_DIR)imgdrv - $(MAKEREC) $< - -$(EE_OBJS_DIR)imgdrv_irx.c: $(EE_SRC_DIR)imgdrv/irx/imgdrv.irx $(PS2SDKSRC)/tools/bin2c/bin/bin2c - $(DIR_GUARD) - $(PS2SDKSRC)/tools/bin2c/bin/bin2c $< $@ _imgdrv_irx - -clean:: - $(MAKEREC) $(EE_SRC_DIR)imgdrv clean - -.NOTPARALLEL:: \ - $(PS2SDKSRC)/tools/bin2c/bin/bin2c \ - $(EE_SRC_DIR)imgdrv/irx/imgdrv.irx diff --git a/ee/iopreboot/include/iopcontrol_special.h b/ee/iopreboot/include/iopcontrol_special.h index f5a08317abb7..22aeb1373062 100644 --- a/ee/iopreboot/include/iopcontrol_special.h +++ b/ee/iopreboot/include/iopcontrol_special.h @@ -33,7 +33,7 @@ extern int SifIopRebootBufferEncrypted(const void *udnl, int size); * @param size Size of the IOPRP image in bytes. * @return 1 for success or 0 for failure. */ -extern int SifIopRebootBuffer(const void *ioprp, int size); +extern int SifIopRebootBuffer(void *ioprp, int size); #ifdef __cplusplus } diff --git a/ee/iopreboot/src/SifIopRebootBuffer.c b/ee/iopreboot/src/SifIopRebootBuffer.c index b51eed19def7..6f5469f8a8c5 100644 --- a/ee/iopreboot/src/SifIopRebootBuffer.c +++ b/ee/iopreboot/src/SifIopRebootBuffer.c @@ -22,103 +22,114 @@ #include "string.h" #include "sbv_patches.h" -#define IMGDRV_IRX_SIZE ((size__imgdrv_irx + 15) & ~15) // Was a hardcoded value of 0x400 bytes #define IOPBTCONF_IOP_MAX_SIZE 0x400 extern int _iop_reboot_count; extern u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE]; -extern unsigned char _imgdrv_irx[]; -extern unsigned int size__imgdrv_irx; -extern int imgdrv_offset_ioprpimg; -extern int imgdrv_offset_ioprpsiz; +extern int send_romdrv_rom1_payloads(void *payload1, int payload1_size, void *payload2, int payload2_size); -extern void init_imgdrv_offsets(void); +typedef struct romdir +{ + char name[10]; + u16 ExtInfoEntrySize; + u32 size; +} romdir_t; + +typedef struct extinfo +{ + u16 value; /* Only applicable for the version field type. */ + u8 ExtLength; /* The length of data appended to the end of this entry. */ + u8 type; +} extinfo_t; + +enum EXTINFO_TYPE { + EXTINFO_TYPE_DATE = 1, + EXTINFO_TYPE_VERSION, + EXTINFO_TYPE_COMMENT, + EXTINFO_TYPE_FIXED = 0x7F // Must exist at a fixed location. +}; #ifdef F__iopcontrol_special_internals u8 iopbtconf_img[IOPBTCONF_IOP_MAX_SIZE] __attribute__((aligned(64))); -int imgdrv_offset_ioprpimg = 0; -int imgdrv_offset_ioprpsiz = 0; -void init_imgdrv_offsets(void) +struct payload_img { - if (imgdrv_offset_ioprpimg == 0 || imgdrv_offset_ioprpsiz == 0) { - int i; - - for (i = 0; (unsigned int)i < size__imgdrv_irx; i += 4) { - if (*(u32 *)((&((unsigned char *)_imgdrv_irx)[i])) == 0xDEC1DEC1) { - imgdrv_offset_ioprpimg = i; - } - if (*(u32 *)((&((unsigned char *)_imgdrv_irx)[i])) == 0xDEC2DEC2) { - imgdrv_offset_ioprpsiz = i; - } - } - } + romdir_t romdir[5]; +}; + +static const struct payload_img g_payload_img_base = { + {{"RESET", 0, 0}, + {"ROMDIR", 0, 0x50}, + {"0", 0, 0}, + {"1", 0, 0}, + {"", 0, 0}}, + }; + +int send_romdrv_rom1_payloads(void *payload1, int payload1_size, void *payload2, int payload2_size) +{ + unsigned int i; + unsigned int size_total; + struct payload_img cur_payload_img __attribute__((__aligned__(64))); + SifDmaTransfer_t dmat[3]; + int trid; + + cur_payload_img = g_payload_img_base; + dmat[0].src = &cur_payload_img; + dmat[0].size = sizeof(cur_payload_img); + dmat[1].src = payload1; + dmat[1].size = (payload1_size + 15) & -16; + dmat[2].src = payload2; + dmat[2].size = (payload2_size + 15) & -16; + for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1) + dmat[i].attr = 0; + cur_payload_img.romdir[1].size = dmat[0].size; + cur_payload_img.romdir[2].size = dmat[1].size; + cur_payload_img.romdir[3].size = dmat[2].size; + size_total = 0; + for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1) + size_total += dmat[i].size; + dmat[0].dest = SifAllocIopHeap(size_total); + if (!dmat[0].dest) + return -1; + for (i = 1; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1) + dmat[i].dest = ((u8 *)dmat[i - 1].dest) + dmat[i - 1].size; + for (i = 0; i < (sizeof(dmat)/sizeof(dmat[0])); i += 1) + sceSifWriteBackDCache(dmat[i].src, dmat[i].size); + while (!(trid = sceSifSetDma(dmat, sizeof(dmat) / sizeof(dmat[0])))); + while (sceSifDmaStat(trid) >= 0); + return sbv_patch_romdrv_set_rom1_info(dmat[0].dest, dmat[0].size) ? 1 : 0; } #endif // Our LOADFILE functions are slightly different. #define SifLoadModuleSpecial(path, arg_len, args, dontwait) \ - _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, dontwait); + _SifLoadModule(path, arg_len, args, NULL, LF_F_MOD_LOAD, dontwait) #define SifLoadModuleEncryptedSpecial(path, arg_len, args, dontwait) \ - _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, dontwait); + _SifLoadModule(path, arg_len, args, NULL, LF_F_MG_MOD_LOAD, dontwait) #ifdef F_SifIopRebootBufferEncrypted int SifIopRebootBufferEncrypted(const void *udnl, int size) { int iopbtconf_img_size; - void *imgdrv_iop, *udnl_iop, *iopbtconf_img_iop; - int *imgdrv_img_size; - void **imgdrv_img; - SifDmaTransfer_t dmat[3]; sceSifInitRpc(0); sceSifExitRpc(); SifIopReset("", 0); - while (!SifIopSync()) {}; - - SifLoadFileInit(); - SifInitIopHeap(); + while (!SifIopSync()); - imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE); - udnl_iop = SifAllocIopHeap(size); - iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE); + iopbtconf_img_size = 0; // No support for IOPBTCONF manipulation - if (imgdrv_iop == NULL || udnl_iop == NULL || iopbtconf_img_iop == NULL) + /* Unofficial: Use following instead of patching LoadModuleBuffer and using embedded imgdrv */ + if (send_romdrv_rom1_payloads((void *)udnl, size, iopbtconf_img, iopbtconf_img_size)) return -1; - iopbtconf_img_size = 0; // No support for IOPBTCONF manipulation - - init_imgdrv_offsets(); - imgdrv_img = (void **)&_imgdrv_irx[imgdrv_offset_ioprpimg]; - imgdrv_img_size = (int *)&_imgdrv_irx[imgdrv_offset_ioprpsiz]; - dmat[0].src = _imgdrv_irx; - dmat[0].dest = imgdrv_iop; - dmat[0].size = IMGDRV_IRX_SIZE; - dmat[0].attr = 0; - dmat[1].src = (void *)udnl; - dmat[1].dest = udnl_iop; - dmat[1].size = size; - dmat[1].attr = 0; - dmat[2].src = iopbtconf_img; - dmat[2].dest = iopbtconf_img_iop; - dmat[2].size = iopbtconf_img_size; - dmat[2].attr = 0; - imgdrv_img[0] = udnl_iop; - imgdrv_img[1] = iopbtconf_img_iop; - imgdrv_img_size[0] = size; - imgdrv_img_size[1] = iopbtconf_img_size; - FlushCache(0); - sceSifSetDma(dmat, 3); - - sbv_patch_enable_lmb(); - - SifLoadModule("rom0:SYSCLIB", 0, NULL); - SifLoadModuleBuffer(imgdrv_iop, 0, NULL); - SifLoadModuleEncryptedSpecial("img0:", 0, NULL, 1); + /* Unofficial: do not load rom:SYSCLIB (DMA end checking is done above) */ + /* If ELF header detected, load UDNL as unencrypted module */ + (void)((((u32 *)udnl)[0] == 0x464c457f) ? SifLoadModuleSpecial("rom1:0", 0, NULL, 1) : SifLoadModuleEncryptedSpecial("rom1:0", 0, NULL, 1)); sceSifExitRpc(); SifLoadFileExit(); @@ -136,61 +147,26 @@ int SifIopRebootBufferEncrypted(const void *udnl, int size) #endif #ifdef F_SifIopRebootBuffer -static int generateIOPBTCONF_img(void *output, const void *ioprp); +static int generateIOPBTCONF_img(void *output, void *ioprp); -int SifIopRebootBuffer(const void *ioprp, int size) +int SifIopRebootBuffer(void *ioprp, int size) { int iopbtconf_img_size; - void *imgdrv_iop, *ioprp_iop, *iopbtconf_img_iop; - int *imgdrv_img_size; - void **imgdrv_img; - SifDmaTransfer_t dmat[3]; sceSifInitRpc(0); sceSifExitRpc(); SifIopReset("", 0); - while (!SifIopSync()) {}; + while (!SifIopSync()); - SifLoadFileInit(); - SifInitIopHeap(); - - imgdrv_iop = SifAllocIopHeap(IMGDRV_IRX_SIZE); - ioprp_iop = SifAllocIopHeap(size); - iopbtconf_img_iop = SifAllocIopHeap(IOPBTCONF_IOP_MAX_SIZE); + iopbtconf_img_size = generateIOPBTCONF_img(iopbtconf_img, ioprp); - if (imgdrv_iop == NULL || ioprp_iop == NULL || iopbtconf_img_iop == NULL) + /* Unofficial: Use following instead of patching LoadModuleBuffer and using embedded imgdrv */ + if (send_romdrv_rom1_payloads((void *)ioprp, size, iopbtconf_img, iopbtconf_img_size)) return -1; - iopbtconf_img_size = generateIOPBTCONF_img(iopbtconf_img, ioprp); - - init_imgdrv_offsets(); - imgdrv_img = (void **)&_imgdrv_irx[imgdrv_offset_ioprpimg]; - imgdrv_img_size = (int *)&_imgdrv_irx[imgdrv_offset_ioprpsiz]; - dmat[0].src = _imgdrv_irx; - dmat[0].dest = imgdrv_iop; - dmat[0].size = IMGDRV_IRX_SIZE; - dmat[0].attr = 0; - dmat[1].src = (void *)ioprp; - dmat[1].dest = ioprp_iop; - dmat[1].size = size; - dmat[1].attr = 0; - dmat[2].src = iopbtconf_img; - dmat[2].dest = iopbtconf_img_iop; - dmat[2].size = iopbtconf_img_size; - dmat[2].attr = 0; - imgdrv_img[0] = ioprp_iop; - imgdrv_img[1] = iopbtconf_img_iop; - imgdrv_img_size[0] = size; - imgdrv_img_size[1] = iopbtconf_img_size; - FlushCache(0); - sceSifSetDma(dmat, 3); - - sbv_patch_enable_lmb(); - - SifLoadModule("rom0:SYSCLIB", 0, NULL); - SifLoadModuleBuffer(imgdrv_iop, 0, NULL); - SifLoadModuleSpecial("rom0:UDNL", 11, "img0:\0img1:", 1); + /* Unofficial: do not load rom:SYSCLIB (DMA end checking is done above) */ + SifLoadModuleSpecial("rom:UDNL", 13, "rom1:0\x00rom1:1", 1); sceSifExitRpc(); SifLoadFileExit(); @@ -206,27 +182,6 @@ int SifIopRebootBuffer(const void *ioprp, int size) return 1; } -typedef struct romdir -{ - char name[10]; - u16 ExtInfoEntrySize; - u32 size; -} romdir_t; - -typedef struct extinfo -{ - u16 value; /* Only applicable for the version field type. */ - u8 ExtLength; /* The length of data appended to the end of this entry. */ - u8 type; -} extinfo_t; - -enum EXTINFO_TYPE { - EXTINFO_TYPE_DATE = 1, - EXTINFO_TYPE_VERSION, - EXTINFO_TYPE_COMMENT, - EXTINFO_TYPE_FIXED = 0x7F // Must exist at a fixed location. -}; - struct iopbtconf_img { romdir_t romdir[5]; @@ -248,11 +203,11 @@ static const struct iopbtconf_img iopbtconf_img_base = { /* Generate an IOPRP image that contains IOPBTCONF, if the original contains IOPBTCONF. This is required because UDNL will only seach succeeding IOPRP images for modules specified within IOPBTCONF. */ -static int generateIOPBTCONF_img(void *output, const void *ioprp) +static int generateIOPBTCONF_img(void *output, void *ioprp) { - int size, offset, fsize_rounded; + int offset, fsize_rounded; romdir_t *romdir; - const u8 *ptr_in; + u8 *ptr_in; u8 *ptr_out; romdir = (romdir_t *)ioprp; @@ -260,23 +215,21 @@ static int generateIOPBTCONF_img(void *output, const void *ioprp) return -1; // Now locate IOPBTCONF - size = 0; - offset = 0; - for (; romdir->name[0] != '\0'; romdir++, offset += fsize_rounded) { + for (offset = 0; romdir->name[0] != '\0'; romdir++, offset += fsize_rounded) { fsize_rounded = (romdir->size + 15) & ~15; - if (strcmp(romdir->name, "IOPBTCONF") == 0) { + /* Unofficial: Check for already-patched image */ + if (!strcmp(romdir->name, "IOPBTCONF") || !strcmp(romdir->name, "XOPBTCONF")) { romdir->name[0] = 'X'; // Change 'IOPBTCONF' to 'XOPBTCONF', so that UDNL will not find the original. // Copy IOPBTCONF into the new image. - size = romdir->size + sizeof(iopbtconf_img_base); ptr_out = (u8 *)output; - ptr_in = (const u8 *)ioprp; + ptr_in = (u8 *)ioprp; memcpy(ptr_out, &iopbtconf_img_base, sizeof(iopbtconf_img_base)); memcpy(ptr_out + sizeof(iopbtconf_img_base), &ptr_in[offset], romdir->size); ((romdir_t *)ptr_out)[3].size = romdir->size; // Update the size of IOPBTCONF within the generated IOPRP image. - break; + return romdir->size + sizeof(iopbtconf_img_base); } } - return size; + return 0; } #endif diff --git a/ee/iopreboot/src/imgdrv/Makefile b/ee/iopreboot/src/imgdrv/Makefile deleted file mode 100644 index 07faf220aa28..000000000000 --- a/ee/iopreboot/src/imgdrv/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. - -IOP_BIN ?= imgdrv.irx - -IOP_INCS += \ - -I$(PS2SDKSRC)/iop/system/ioman/include \ - -I$(PS2SDKSRC)/iop/system/loadcore/include - -IOP_OBJS = imgdrv.o imports.o - -include $(PS2SDKSRC)/Defs.make -include $(PS2SDKSRC)/iop/Rules.bin.make -include $(PS2SDKSRC)/iop/Rules.make -include $(PS2SDKSRC)/iop/Rules.release diff --git a/ee/iopreboot/src/imgdrv/src/imgdrv.c b/ee/iopreboot/src/imgdrv/src/imgdrv.c deleted file mode 100644 index 3e30dd23465c..000000000000 --- a/ee/iopreboot/src/imgdrv/src/imgdrv.c +++ /dev/null @@ -1,90 +0,0 @@ -/* -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. -*/ - -/** - * @file - * Image device driver (IMGDRV) - * Used by the special IOP reboot sequence, to reboot the IOP with a buffered IOPRP image. - */ - -#include -#include -#include - -#define MODNAME "imgdrv" - -IRX_ID(MODNAME, 1, 1); - -// Function prototypes -static int imgdrv_read(iop_file_t *f, void *buf, int size); -static int imgdrv_lseek(iop_file_t *f, int offset, int whence); - -/* The IOMAN operations structure is usually longer than this, - but the structure in the original was this short (probably to save space). */ -typedef struct _iop_device_ops_short -{ - int (*init)(iop_device_t *device); - int (*deinit)(iop_device_t *device); - int (*format)(iop_file_t *f); - int (*open)(iop_file_t *f, const char *name, int flags); - int (*close)(iop_file_t *f); - int (*read)(iop_file_t *f, void *ptr, int size); - int (*write)(iop_file_t *f, void *ptr, int size); - int (*lseek)(iop_file_t *f, int offset, int mode); -} iop_device_ops_short_t; - -IOMAN_RETURN_VALUE_IMPL(0); - -static iop_device_ops_short_t imgdrv_ops = { - IOMAN_RETURN_VALUE(0), // init - IOMAN_RETURN_VALUE(0), // deinit - IOMAN_RETURN_VALUE(0), // format - IOMAN_RETURN_VALUE(0), // open - IOMAN_RETURN_VALUE(0), // close - &imgdrv_read, // read - IOMAN_RETURN_VALUE(0), // write - &imgdrv_lseek, // lseek -}; - -#define MAX_IMAGES 2 -// These arrays will be manipulated by the EE-side code before the module is loaded. -void *img[MAX_IMAGES] = {(void *)0xDEC1DEC1, 0}; -int img_size[MAX_IMAGES] = {0xDEC2DEC2, 0}; - -static iop_device_t img_device = { - "img", - IOP_DT_FS, - 1, - "img", - (iop_device_ops_t *)&imgdrv_ops, -}; - -int _start(int argc, char *argv[]) -{ - return (AddDrv(&img_device) < 0) ? MODULE_NO_RESIDENT_END : MODULE_RESIDENT_END; -} - -static int imgdrv_read(iop_file_t *f, void *buf, int size) -{ - int i; - const u32 *img_ptr; - u32 *img_out; - - img_out = (u32 *)buf; - img_ptr = (const u32 *)img[f->unit]; - for (i = size; i > 0; i -= 4, img_ptr++, img_out++) - *img_out = *img_ptr; - - return size; -} - -static int imgdrv_lseek(iop_file_t *f, int offset, int whence) -{ - return (whence == SEEK_SET ? 0 : img_size[f->unit]); -} diff --git a/ee/iopreboot/src/imgdrv/src/imports.lst b/ee/iopreboot/src/imgdrv/src/imports.lst deleted file mode 100644 index 85f42b73a1d6..000000000000 --- a/ee/iopreboot/src/imgdrv/src/imports.lst +++ /dev/null @@ -1,3 +0,0 @@ -ioman_IMPORTS_start -I_AddDrv -ioman_IMPORTS_end diff --git a/ee/iopreboot/src/imgdrv/src/irx_imports.h b/ee/iopreboot/src/imgdrv/src/irx_imports.h deleted file mode 100644 index 6eb7a762eafe..000000000000 --- a/ee/iopreboot/src/imgdrv/src/irx_imports.h +++ /dev/null @@ -1,18 +0,0 @@ -/* -# _____ ___ ____ ___ ____ -# ____| | ____| | | |____| -# | ___| |____ ___| ____| | \ PS2DEV Open Source Project. -#----------------------------------------------------------------------- -# Licenced under Academic Free License version 2.0 -# Review ps2sdk README & LICENSE files for further details. -*/ - -#ifndef IOP_IRX_IMPORTS_H -#define IOP_IRX_IMPORTS_H - -#include "irx.h" - -/* Please keep these in alphabetical order! */ -#include "ioman.h" - -#endif /* IOP_IRX_IMPORTS_H */