PS2 Julian's various PS2 projects (Worklog)

Sample photos and music for XOSD 2.xx is at
hdd:/__sysconf/etc/PresetContents/gmm_000
Note: the files appear to be encrypted partially, resulting in corrupt photo decoding or pops in music playback.

Cover for sample photo is at
hdd:/__system/xosd/packages/xMB_Plugin_PrePhoto_0/art/PhotoAlbum.png
Filepaths for sample photo can be inferred at
hdd:/__system/xosd/packages/xMB_Plugin_PrePhoto_0/dic/jp.dic
Cover for sample music is at
hdd:/__system/xosd/packages/xMB_Plugin_PreMusic_0/art/PresetMusic.png
Filepaths for sample music can be inferred at
hdd:/__system/xosd/packages/xMB_Plugin_PreMusic_0/dic/jp.dic
Default GMM database (containing file names, file paths, metadata) is at
hdd:/__system/xosd/packages/DefaultContents_0/__xdata/gmm.db
 
The RPi CM5 looks interesting. It not only has PCIe but it also has USB3.0 and Gigabit Ethernet, which unlocks more possibilities for various projects.

The major con compared to CM4, however, is that it removes the high-speed SMI bus interface. But apparently RPi is working on software to control PIOs on RP1 so that may be a suitable replacement.

Thanks to PCIe and USB3.0 and Gigabit Ethernet being exposed on CM5, it is possible to connect stuff but still leave the PCIe open for maybe connecting a PI7C9X111SL chip for e.g. possible compatibility with PICMG 1.2 half width interface.
 
A note on iomanX feature update differences

close: return value (not FD) .
remove: return value (not zero) .
mkdir: return value (not zero)
rmdir: return value (not zero)
getstat: return value (not zero)
chstat: return value (not zero)
format: return value (not zero) .
rename: return value (not zero) .
chdir: return value (not zero)
sync: return value (not zero) .
mount: return value (not zero)
umount: return value (not zero)
symlink: return value (not zero)
 
Some notes about alignment:

The documentation is inconsistent in regards to WORD=16-bit (win32) or WORD=32-bit (MIPS). If there is a definitions section in the documentation, look at it first.

2-byte/16-bit/word/halfword(MIPS) alignment: lh/sh, lhu, lwl, lwr
4-byte/32-bit/dword/word(MIPS) alignment: jr, lw/sw, lwu, jalr, lwc1/swc1, SIF RPC buffer on IOP, USB buffer when pkt size is 63/64bytes
8-byte/64bit/qword alignment: ld/sd, VIFcode MPG, VU memory, VU microprogram
16-byte/128-bit/2qword/qword(MIPS) alignment: load/store 128 bit value lq/sq MMI (silent truncation/no error of low four bits!!!); SIF RPC buffer on EE (no cache writeback); DMAC MADR and TADR; GIF tag and data; DMA alignment requirement, D_RBOR, Dn_TADR, Dn_SADR, Dn_MADR, Dn_ASR0, Dn_ASR1, D_STADR, Source/destination chain tag ADDR, VIF DMA packet, DMA tag, SPU2 addr start
64-byte/8qword alignment: SIF RPC buffer on EE (yes cache writeback); SPR DMA; DMA tag/data; PATH3; DMA xfer unit/block/slice, SPU2 addr size
128-byte alignment:
256-byte/64word alignment: Texture buffer, CLUT buffer, IOP/EE sysmem block units
8192-byte/2048word(MIPS) alignment: Frame buffer, Z buffer
128k alignment: SPU2 digital effect work area highest address
 
sio2man was not exposed to developers, and the API is not backwards compatible.
Notably:
* Between SDK 1.3 and 1.6 a function to explicitly reset the transfer event flag was added, no longer being merged into the transfer function
* Between SDK 1.6 and 2.0 the major export version was changed from 1 to 2, making previous library clients incompatible
* Between SDK 2.8 and 3.0 the locking was changed from event flags to semaphores. This will result in differing behavior

---

It appears to be possible to register multiple exports with loadcore where the name is the same but the major version is different.
 
Last edited:
For sio2man:
To resolve the explicit reset incompatibility, for export version 1.2 and newer sio2_mtap_change_slot is called after the transfer init function, so it can be differentiated with that. For export version 2.x explicit reset is always used.
To resolve the major export version incompatibility, both versions export tables can be registered at the same time.
The locking change from event flags to semaphores should be backwards compatible.
 
A note about RPC version checking:

LOADFILE RPC version retrieval in _lf_bind: RPC 0x80000006, CMD 0xFF
LOADFILE RPC version check in _lf_version
FILEIO RPC version retrieval in sceFsInit: RPC 0x80000001, CMD 0xFF
FILEIO RPC version check in _fs_version
Normally, the version string to be checked in the EE side is after the string "PsIIlibkernl" in the executable.
However, when the version string is "....", it is allowed as a valid version. However, this additional check is only implemented at a SDK version between 2.0 (exclusive) and 2.4 (inclusive).

CDVDFSV RPC version check in sceCdInit: RPC 0x80000592, CMD 0x00
If value in m_debug_mode is either 254 or 255, it succeeds (0). Otherwise it will check if both m_cdvdfsv_ver and m_cdvdman_ver major version is 2 or later. If so, it succeeds (0), otherwise also succeeds but indicates old version (2).

MCSERV RPC version check in sceMcInit: RPC 0x80000400, CMD 0xFE
Version will be checked if greater or equal.

DBCMAN RPC version check in sceDbcInit: RPC 0x80001300, CMD 0x80001363
Major version will be checked exactly.

MCXSERV RPC version check in sceMcxInit: RPC 0x80000420, CMD 0xFE
Version will be checked if greater or equal.

MTAPMAN RPC version check in sceMtapInit: RPC 0x80000900, CMD 0x05
Major version will be checked exactly.

PADMAN RPC version check in sceMtapInit: RPC 0x80000100, CMD 0x01
Major version will be checked exactly.
 
Some notes regarding IOPBTCONF/IOPBTCON2, dvdplayer.irx, osdmain.irx

When OSDSYS and DVD player supporting booting from memory card detect that the argv[0] is from memory card, the behavior regarding IOP reboot with image changes.

Instead of rebooting normally
Code:
for OSDSYS: argument="rom0:UDNL rom0:OSDCNF", flag=0
for DVD player (in EELOAD moduleload2): argument="rom1:UDNL rom1:DVDCNF", flag=0

when booting from memory card
Code:
for OSDSYS (relative to arg0 path, example used): argument="mc0:/BIEXEC-SYSTEM/osdmain.irx", flag=0x100
for DVD player: argument="mc0:/BIEXEC-DVDPLAYER/dvdplayer.irx", flag=0x100

The flag indicates that the module to be loaded is an encrypted (KELF) executable.

The DVD player update's dvdplayer.irx file is a self contained UDNL module that has embedded compressed/scrambled data.

The process basically goes like this:
* Reboot with argument from EE sends a SIF command
* REBOOT module on IRX receives the command, then calls ReBootStart in MODLOAD
* Modules are terminated
* Flags get set to 1 (soft reboot, search IOPBTCON1)
* If command is not empty string, it gets copied to 0x480, and flags gets set to ((eeflags & 0xFF00) | 2) (update reboot, search IOPBTCON2)
* Find and call IOPBOOT from ROM, argument 1 is RAM size in MB, argument 2 is flags, argument 3 is pointer to command, argument 4 is unused (set to zero)
* If passed RAM size is lower than 2MB, then it is set to 2MB
* Reboot data structure is created at 0x20000 and command copied to 0x20020
* ROMDIR structure is searched at 0xBFC00000. Fail -> infinite write 0x80000000 = 0
* IOPBTCONX is searched for, where X is the character representation of (argument2 & 0xFF). e.g. (argument2 & 0xFF) == 2 then IOPBTCON2 is searched for
* If above not found, IOPBTCONF is searched for. Fail -> infinite write 0x80000000 = 1
* Rest of the proceeds basically the same way that UDNL does it, then calls into LOADCORE.
* LOADCORE sets bootmodes 4 and 5 regarding reboot string info, then initializes modules
* MODLOAD post reboot callback then executes the module in the reboot string (e.g. UDNL)
* UDNL reboots (with self contained code, not calling into IOPBOOT), now with the specified modules


IOPBTCON2 contains a reduced set of modules, but includes some modules to allow more update sources.
It excludes:
* EECONF
* SIFCMD
* REBOOT
* LOADFILE
* CDVDFSV
* SIFINIT
* FILEIO
* EESYNC
It includes:
* ADDDRV
* SIO2MAN
* MCMAN
 
Last edited:
Some notes on DECKARD and load/reset vector addresses:

Normally, PPC reset vector is at 0xFFFFFFFC

Normally, for IOP:
addr of DECKARD: 0xbfc00000 + 0x3e0000 = 0xbffe0000
addr of DECKARD/DECKARD: 0xbffe0000 + 0x120 = 0xbffe0120
addr of DECKARD/DPATCH: 0xbffe0000 + 0x1d000 = 0xbfffd000
addr end of DECKARD/DPATCH: 0xbfffd000 + 0x824 = 0xbfffd824
addr of DECKARD/LOADER: 0xbffe0000 + 0x1e000 = 0xbfffe000
addr end of DECKARD/LOADER: 0xbfffe000 + 0x2000 = 0xc0000000

However, it appears to be for PPC-IOP
addr of DECKARD: 0xffc00000 + 0x3e0000 = 0xfffe0000
addr of DECKARD/DECKARD: 0xfffe0000 + 0x120 = 0xfffe0120
addr of DECKARD/DPATCH: 0xfffe0000 + 0x1d000 = 0xffffd000
addr end of DECKARD/DPATCH: 0xffffd000 + 0x824 = 0xffffd824
addr of DECKARD/LOADER: 0xfffe0000 + 0x1e000 = 0xffffe000
addr end of DECKARD/LOADER: 0xffffe000 + 0x2000 = 0x100000000

The last 32-bit PPC instruction of DECKARD/LOADER is to jump -0x1000 to 0xfffff000 (relative)

So DECKARD/LOADER appears to be mapped at 0xffffe000. I checked and data references to RESETB and DECKARD are resolved correctly. You might get a overflow error when attempting to load it, so subtract 4 bytes from the size to work around it.
 
When booting ROM DVD player, EELOAD is called (from LoadExecPS2 syscall) with following arguments
"moduleload2 rom1:UDNL rom1:DVDCNF" "-k rom1:EROMDRV?" "-m erom0:UDFIO" "-x erom0:DVDELF"
This may be region varianted:
"moduleload2 rom1:UDNL rom1:DVDCNF" "-k rom1:EROMDRVA" "-m erom0:UDFIO" "-x erom0:DVDPLA"

This does the following:
* Load rom1:UDNL with argument "rom1:DVDCNF"
* Load encrypted IOP executable rom1:EROMDRVA
* Load IOP executable erom0:UDFIO
* Load encrypted EE executable erom0:DVDPLA

Here is an idea for semi-persistent code execution:
This involves a payload resident in Dragon MechaCon.
Basically, it will hook reset and MagicGate related S-CMDs.

There is 16KiB of RAM on MechaCon, and at least 3360 bytes are unused.
Since NVRAM is not big enough, payload will need to be installed using another method like the payload backdoor used by mechadump.
After payload is installed, to uninstall the payload, just unplug the console.

The function LoadStartKelfModule loads the IOP module whole into a buffer, then uses SecrDiskBootFile to decrypt the buffer in place (no bounds check).

In SecrDiskBootHeader:
S-CMD 0x90 sets the initial header information.
S-CMD 0x8D writes the rest of the data 0x10 bytes at a time.
S-CMD 0x8F is used to execute operation and check if MagicGate related command finished.
S-CMD 0x91 gets bit table (SecrBitTable_t) length (unsigned 16 bits)
S-CMD 0x8E then reads the above out 0x10 bytes at a time.

Afterwards, the bit table is parsed. Header size is unsigned 32 bit and block count is unsigned 8 bit (max 255 entries)
For each entry, if flag indicates segment is encrypted and/or signed, SecrDiskBootBlock will be called on that segment.

In SecrDiskBootBlock:
S-CMD 0x92 sets the segment size (size member in SecrBitBlockData_t, truncated to unsigned 16 bits, max 0x800 on MechaCon side)
S-CMD 0x8D writes the rest of the data 0x10 bytes at a time.
S-CMD 0x8F is used to execute operation and check if MagicGate related command finished.
S-CMD 0x93 checks segment read size (unsigned 16 bits) by passing it
S-CMD 0x8E then reads the above out 0x10 bytes at a time.

The buffer then gets incremented by the size member in SecrBitBlockData_t, which is unsigned 32 bits (no bounds check).

EROMDRV is around 4KB. Size can be reduced further by using fixed-address ELF or COFF, which omits the relocation section.
There is not enough room in MechaCon RAM for USB drivers, so instead we can load from memory card using the ROM drivers.

The chain then goes like this:

On wake from standby/reset:
* Set disc type flag to DVD Video
* Hook the S-CMD dispatch on MechaCon to intercept the above S-CMDs and also memory card MagicGate related stuff (to prevent update loading)
* When rom1:EROMDRV? data is passed through MechaCon, return a custom payload instead, which will then be loaded
* Custom payload will call some S-CMD to unhook the S-CMD dispatch
* Custom payload will cause the disc insert processing to execute (to reset disc flags)
* Custom payload will enable mc0 access by loading rom0:XMCMAN
* Custom payload will stub IOP executable loading in LOADFILE (to skip erom0:UDFIO loading)
* Custom payload will redirect encrypted EE executable loading in LOADFILE (to instead read from memory card)
* When erom0:UDFIO is loaded by EELOAD, the above behavior will apply
* When erom0:DVDPLA is loaded by EELOAD, the above behavior will apply
 

Similar threads

Back
Top