PS-X EXE: Difference between revisions
| Revision as of 02:44, 23 October 2026 RemmyLee (CPU and system bus at register depth: instruction set, COP0, I/O map, memory control, interrupts, DMA, timers) | Revision as of 02:45, 23 October 2026 RemmyLee (BIOS and kernel: A, B, C functions, syscalls, events, threads, file I/O, boot, PS-X EXE) | ||
| Line 1: | Line 1: | ||
| + | --- | ||
| + | title: PS-X EXE | ||
| + | type: format | ||
| + | summary: Execution file format loaded and started by the PlayStation kernel. | ||
| + | category: File formats | ||
| + | category: System software | ||
| + | info: ID = "PS-X EXE" | ||
| + | info: Header size = 2048 bytes | ||
| + | info: Header structure = XF_HDR (kernel.h) | ||
| + | --- | ||
| + | |||
| + | ## Overview | ||
| + | |||
| + | An execution file conforms to the PlayStation EXE format. It holds code and data linked to fixed addresses, a starting address, an initial value for the gp register, and the starting address and size of the initialized data area.[^lo216] The kernel functions Load(), Exec() and LoadExec() read and start files in this format.[^lr146][^lr125][^lr147] The boot executable named by [SYSTEM.CNF](/system/system-cnf/) is a PS-X EXE file, as is any program that a game loads later.[^spxexe] | ||
| + | |||
| + | The file is divided into three sections. A 2048-byte header that starts with the XF_HDR structure comes first. The text section and the data section with initial values follow it. The sections after the header occupy a multiple of 2048 bytes.[^lo216] Because the CD-ROM block size is also 2048 bytes, the header and the body each start on a sector boundary.[^lo215] | ||
| + | |||
| + | Unlike an MS-DOS executable, the file has no relocation information. The kernel copies the body to the destination address given in the header and nothing more.[^spxexe] The kernel also does not check whether that memory is in use by the heap, the boot executable or the kernel itself. A program that loads further executables should therefore keep a region free for them and not pass all memory to InitHeap().[^spxload] | ||
| + | |||
| + | ## Header | ||
| + | |||
| + | The header is described by the following C structures, which are defined in kernel.h.[^lo217][^lr105] | ||
| + | |||
| + | ``` | ||
| + | struct XF_HDR { /* execution file header */ | ||
| + | char key[8]; /* key code */ | ||
| + | unsigned long text; /* position of text section within file */ | ||
| + | unsigned long data; /* position of data section within file */ | ||
| + | struct EXEC exec; /* execution file information */ | ||
| + | char title[60]; /* license code */ | ||
| + | }; | ||
| + | |||
| + | struct EXEC { /* execution file information */ | ||
| + | unsigned long pc0; /* execution start address */ | ||
| + | unsigned long gp0; /* gp register initial value */ | ||
| + | unsigned long t_addr; /* text and initialized data start address */ | ||
| + | unsigned long t_size; /* text and initialized data size */ | ||
| + | unsigned long d_addr; /* system reserved */ | ||
| + | unsigned long d_size; /* system reserved */ | ||
| + | unsigned long b_addr; /* uninitialized data start address */ | ||
| + | unsigned long b_size; /* uninitialized data size */ | ||
| + | unsigned long s_addr; /* stack area start address (user) */ | ||
| + | unsigned long s_size; /* stack area size (user) */ | ||
| + | unsigned long sp, fp, gp, ret, base; /* register shunt area for Exec() */ | ||
| + | }; | ||
| + | ``` | ||
| + | |||
| + | The byte offsets of the fields within the file are shown below. psx-spx gives the offsets and the values seen in released files.[^spxexe] | ||
| + | |||
| + | Table: PS-X EXE header layout | ||
| + | |||
| + | | Offset | Size | Field | Contents | | ||
| + | | --- | --- | --- | --- | | ||
| + | | 0x000 | 8 | key | ASCII "PS-X EXE" | | ||
| + | | 0x008 | 8 | text, data | Zero-filled | | ||
| + | | 0x010 | 4 | pc0 | Initial PC (usually 0x80010000 or higher) | | ||
| + | | 0x014 | 4 | gp0 | Initial GP (usually 0) | | ||
| + | | 0x018 | 4 | t_addr | Destination address in RAM (usually 0x80010000 or higher) | | ||
| + | | 0x01C | 4 | t_size | Size of the body after the header, a multiple of 0x800 | | ||
| + | | 0x020 | 4 | d_addr | Data section start address (usually 0) | | ||
| + | | 0x024 | 4 | d_size | Data section size (usually 0) | | ||
| + | | 0x028 | 4 | b_addr | BSS start address (usually 0) | | ||
| + | | 0x02C | 4 | b_size | BSS size (0 means no BSS) | | ||
| + | | 0x030 | 4 | s_addr | Initial SP and FP base (usually 0x801FFFF0, or 0 for none) | | ||
| + | | 0x034 | 4 | s_size | Initial SP and FP offset, added to the base (usually 0) | | ||
| + | | 0x038 | 20 | sp, fp, gp, ret, base | Register shunt area used by Exec() (zero in the file) | | ||
| + | | 0x04C | 60 | title | ASCII region marker (license code) | | ||
| + | | 0x088 | to 0x7FF | | Zero-filled | | ||
| + | | 0x800 | t_size | | Code and data, loaded to t_addr | | ||
| + | |||
| + | ## Region Marker | ||
| + | |||
| + | The title field holds one of three strings in licensed executables: "Sony Computer Entertainment Inc. for Japan area", "Sony Computer Entertainment Inc. for Europe area", or "Sony Computer Entertainment Inc. for North America area". The BIOS does not verify the string, however, and a file with a zero-filled field boots in the same way.[^spxexe] The region check at boot is made on the disc instead. The [boot](/system/bios/boot/) page describes it. | ||
| + | |||
| + | ## Loading and Execution | ||
| + | |||
| + | LoadTest() reads only the header of a file and writes its execution file information to an EXEC structure. Load() reads the whole file to the address given in its header and calls FlushCache(). Exec() then starts the loaded module.[^lr148][^lr146][^lr125] Load() and Exec() need the ISO 9660 file system, which is installed by _96_init().[^lr146] | ||
| + | |||
| + | Exec() clears the data section without initial values to zero. It saves sp, fp and gp, sets them from the EXEC structure, and calls the execution start address with the arguments of main() in a0 and a1. When the module returns, sp, fp and gp are restored.[^lr125] If s_addr is 0, the stack and frame pointers are not set and the current execution context is used as it is.[^lr125][^lo216] Exec() must be executed in a critical section.[^lr125] | ||
| + | |||
| + | The shunt area at 0x038 to 0x04B receives the caller's RA, SP, FP, GP and R16 during Exec(). The BIOS therefore saves these registers in the header in memory and not on the stack.[^spxexe] The BSS clear runs word by word, so b_addr and b_size must be multiples of 4.[^spxexe] | ||
| + | |||
| + | The executable is entered with R4 = 1 and R5 = 0 in normal use.[^spxexe] A non-boot executable may return to its caller through RA, and Exec() then returns 1.[^spxload] If the boot executable returns, the BIOS stops in SystemError.[^spxexe] | ||
| + | |||
| + | In boot files the header usually gives SP as 0x801FFFF0. However, the BIOS uses the stack value from SYSTEM.CNF in place of the header values when it starts the boot file.[^spxexe] | ||
| + | |||
| + | ## Related Formats | ||
| + | |||
| + | A relocatable variant with the ID "PS-X EXR" is used by one game and is not supported by the kernel.[^spxexe] The Psy-Q development tools also produce CPE files for debugging, which are not PS-X EXE files.[^spxcpe] | ||
| + | |||
| + | ## References | ||
| + | |||
| + | [^lo215]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-15, Table 2-18. | ||
| + | [^lo216]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-16, Figure 2-1. | ||
| + | [^lo217]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-17. | ||
| + | [^lr105]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-5, EXEC. | ||
| + | [^lr125]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-25, Exec. | ||
| + | [^lr146]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-46, Load. | ||
| + | [^lr147]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-47, LoadExec. | ||
| + | [^lr148]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-48, LoadTest. | ||
| + | [^spxexe]: psx-spx. CDROM File Formats, CDROM File Playstation EXE and SYSTEM.CNF. https://psx-spx.consoledev.net/cdromfileformats/ | ||
| + | [^spxcpe]: psx-spx. CDROM File Formats, CDROM File PsyQ .CPE Files. https://psx-spx.consoledev.net/cdromfileformats/ | ||
| + | [^spxload]: psx-spx. Kernel (BIOS), BIOS File Execute and Flush Cache. https://psx-spx.consoledev.net/kernelbios/ | ||