Add payload

This commit is contained in:
CTurt 2020-06-14 16:40:36 +01:00
parent 94390a3bdf
commit badb624e2c
8 changed files with 224 additions and 0 deletions

14
PAYLOAD/build.sh Normal file
View file

@ -0,0 +1,14 @@
echo "Building payload"
ee-gcc -Ttext=0x01FFF800 payload.c -o payload.elf -nostartfiles -nostdlib -ffreestanding -Os -Wl,-z,max-page-size=0x1 # 2048
ee-objcopy -O binary payload.elf payload.bin -Wl,-z,max-page-size=0x1
ENTRY=`ee-objdump -t payload.elf | grep " _start"`
ENTRY=0x`grep -o "^\S*" <<< $ENTRY`
echo "Building crt0"
ee-gcc -Ttext=0x01500014 -DENTRY=$ENTRY crt0.S -o fullpayload.elf -nostartfiles -nostdlib -ffreestanding -Wl,-z,max-page-size=0x1
ee-objcopy -O binary fullpayload.elf fullpayload.bin -Wl,-z,max-page-size=0x1
echo "Done. Insert fullpayload.bin into VIDEO_TS.IFO at offset 0x2bb4"

63
PAYLOAD/crt0.S Normal file
View file

@ -0,0 +1,63 @@
.set noreorder # If we're writing assembly, why would we want this?
.section .text.startup
.equ memcpy, 0x225668
.equ getBufferInternal, 0x2986a0
.equ payload, (0x2000000 - 0x800) # End of RAM
.global _start
_start:
#la $a0, 0x7f
#la $v1, 0x01
#syscall 0x01 # ResetEE
#la $a0, relo
la $a0, load
la $a1, 0
la $a2, 0
la $a3, 0
.global ExecPS2
ExecPS2:
la $v1, 7
syscall 7 # ExecPS2
load:
la $a0, 0
la $a1, 0 # 0 = VIDEO_TS.IFO, 1 = VTS_01_0.IFO
la $a2, 0x3000 / 0x800 # lba offset in file
la $a3, payload # Destination
la $t0, 0x800 / 0x800 # Count
la $t1, 0
la $v0, getBufferInternal
jalr $v0
nop
#relo:
# Relocate payload to end of RAM
# la $a0, (0x2000000 - 1024)
# la $a1, payload
# la $a2, 2048
# la $v0, memcpy
# jalr $v0
boot:
la $v1, 0x64; la $a0, 0; syscall 0x64 # FlushCache data writeback
la $v1, 0x64; la $a0, 2; syscall 0x64 # FlushCache instruction invalidate
# Point stack to end of scratchpad RAM
la $sp, 0x70004000
# Execute from relocated place
la $v0, ENTRY
j $v0
nop
.space (_start + 0x2faa - 0x2bb4) - .
fpIndex:
.byte 0x7e
.byte 0xe0
.space (_start + 0x3000 - 0x2bb4) - .
.incbin "payload.bin"

BIN
PAYLOAD/fullpayload.bin Normal file

Binary file not shown.

BIN
PAYLOAD/fullpayload.elf Normal file

Binary file not shown.

BIN
PAYLOAD/payload.bin Normal file

Binary file not shown.

142
PAYLOAD/payload.c Normal file
View file

@ -0,0 +1,142 @@
#include <stddef.h>
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define pointToIFO ((void (*)(unsigned int index, unsigned int lba, unsigned int offset))0x25c880)
#define getDiscData ((void (*)(unsigned int s, void *d))0x25c9f0)
#define getDiscBuffer ((void (*)(void))0x25c678)
#define sceCdSync ((void (*)(int mode))0x2a69c8)
typedef struct {
unsigned int lsn;
unsigned int size;
char name[16];
unsigned char date[8];
} sceCdlFILE;
#define sceCdSearchFile ((int (*)(sceCdlFILE *, char *, int))0x2a6488)
#define SifIopReset ((int (*)(char *, int))0x84fe0)
#define SifIopSync ((int (*)(void))0x85110)
#define SifInitRpc ((void (*)(int))0x84180)
#define SifExitRpc ((void (*)(void))0x84310)
#define getBufferInternal ((int (*)(void *filename, int type, int currentSector, void *dest, unsigned int sectorsRemaining, int curReadPos))0x002986a0)
#define ELF_PT_LOAD 1
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef struct {
u8 ident[16];
u16 type;
u16 machine;
u32 version;
u32 entry;
u32 phoff;
u32 shoff;
u32 flags;
u16 ehsize;
u16 phentsize;
u16 phnum;
u16 shentsize;
u16 shnum;
u16 shstrndx;
} elf_header_t;
typedef struct {
u32 type;
u32 offset;
void *vaddr;
u32 paddr;
u32 filesz;
u32 memsz;
u32 flags;
u32 align;
} elf_pheader_t;
__attribute__((noreturn)) void ExecPS2(void *entry, void *gp, int argc, char **argv) {
asm volatile("la $v1, 7; syscall 7");
//__builtin_unreachable();
}
void *memcpy_(void *dest, void *src, size_t n) {
int i;
for(i = 0; i < n; i++) ((unsigned char *)dest)[i] = ((unsigned char *)src)[i];
return dest;
}
void *memset(void *dest, int c, size_t n) {
int i;
for(i = 0; i < n; i++) ((unsigned char *)dest)[i] = c;
return dest;
}
static void readData(void *dest, unsigned int offset, size_t n) {
unsigned char buffer[0x800];
unsigned int copied = 0;
#define remaining (n - copied)
if(offset % 0x800) {
getBufferInternal("", 1, offset / 0x800, buffer, 1, 0);
memcpy_(dest, buffer + offset % 0x800, min(0x800 - offset, n));
copied += min(0x800 - offset, n);
}
if(remaining >= 0x800) {
getBufferInternal("", 1, (offset + copied) / 0x800, dest + copied, remaining / 0x800, 0);
copied += (remaining / 0x800) * 0x800;
}
if(remaining > 0) {
getBufferInternal("", 1, (offset + copied) / 0x800, buffer, 1, 0);
memcpy_(dest + copied, buffer, remaining);
}
}
__attribute__((noreturn)) void _start(void) {
//Exit(0);
//asm volatile("la $v1, 0x04; la $a0, 0; syscall 0x04");
int i;
// point to VTS_02_0.IFO
pointToIFO(2, 0, 0);
// Force a read from VTS_02_0.IFO
char head[64];
getDiscData(64, &head);
// Based on https://github.com/AKuHAK/uLaunchELF/blob/master/loader/loader.c
elf_header_t eh;
readData(&eh, 0, sizeof(elf_header_t));
elf_pheader_t eph[eh.phnum];
readData(&eph, eh.phoff, sizeof(elf_pheader_t) * eh.phnum);
for (i = 0; i < eh.phnum; i++) {
if (eph[i].type != ELF_PT_LOAD)
continue;
readData(eph[i].vaddr, eph[i].offset, eph[i].filesz);
if(eph[i].memsz > eph[i].filesz) memset(eph[i].vaddr + eph[i].filesz, 0, eph[i].memsz - eph[i].filesz);
}
asm volatile("la $v1, 0x64; la $a0, 0; syscall 0x64"); // FlushCache data writeback
asm volatile("la $v1, 0x64; la $a0, 2; syscall 0x64"); // FlushCache instruction invalidate
//while(!SifIopReset("", 0));
//while(!SifIopSync());
//while(!SifIopReset("rom0:UDNL rom0:EELOADCNF", 0));
SifIopReset("rom0:UDNL rom0:EELOADCNF", 0);
while(!SifIopSync());
SifInitRpc(0);
SifExitRpc();
ExecPS2((void *)eh.entry, 0, 0, 0);
}

BIN
PAYLOAD/payload.elf Normal file

Binary file not shown.

View file

@ -36,3 +36,8 @@ Once you've placed all the homebrew files you'd like into the directory, generat
## Test and burn
I would recommend you test in PCSX2 first, but since [PCSX2 doesn't support loading the DVD Player](https://github.com/PCSX2/pcsx2/issues/1981), you have to decrypt and repack it yourself, which can be a pain.
## Replacing loader payload
If you wish to work on the loader payload, see run `build.sh` inside `PAYLOAD` directory, and copy the output `fullpayload.bin` to `VIDEO_TS/VIDEO_TS.IFO` at offset `0x2bb4`.
The default loader will boot `VIDEO_TS/VTS_02_0.IFO` as an ELF file, but tweaks might be desired to improve compatibility.