Naked PSP
Naked PSP
TyRaNiD
ps2dev.org
August 4, 2006
2 PSP Hardware
The System Controller
3 PSP Software
The Toolchain
Modular Kernel
Threading Model
Programming Interfaces
PSP Security
4 Debugging
Debugging Tools
Outline
1 History of PSP Home brew
Revisions of the PSP
2 PSP Hardware
The System Controller
3 PSP Software
The Toolchain
Modular Kernel
Threading Model
Programming Interfaces
PSP Security
4 Debugging
Debugging Tools
Firmware Revisions
How you run code depends on the firmware revision of the PSP
For versions 1.0 and 1.5 build a special EBOOT.PBP file and run
directly on the PSP
For version 2.0 use eLoader in libTIFF mode
For version 2.01+ use Grand Theft Auto UMD plus eLoader
For version 2.7+ no known way of developing
Outline
1 History of PSP Home brew
Revisions of the PSP
2 PSP Hardware
The System Controller
3 PSP Software
The Toolchain
Modular Kernel
Threading Model
Programming Interfaces
PSP Security
4 Debugging
Debugging Tools
Specifications
Miscellaneous Hardware
The ALLEGREX
The ALLEGREX is the name of the PSP’s main CPU
Customised MIPS32 core
Instruction set additions (bit twiddling, user mode interrupt control,
CPU halt)
Limited Memory Management Unit (MMU) (no TLB present)
Variable clocking (approx 33MHz to 333MHz)
On board single precision (32bit) FPU
On board vector/matrix co-processor (VFPU)
Built in hardware debug unit
16KiB scratch pad RAM (pretty useless)
On board profiler (monitor cache hits, instructions executed etc.)
Separate instruction and data cache
Vector Processing
To supplement the 3D graphics capability of the PSP the main CPU has a
vector co-processor (VFPU)
128 32bit registers
Registers reconfigurable to operate as single values, 2x2/3x3/4x4
rows, columns, matrices, transposed matrices
Can multiply whole matrices in one operation
Usual selection of trigonometric/square root instructions
On-board pseudo-random number generator
VFPU Registers
The Graphics Engine (GE) is the core of the PSP’s graphics capability
Modelled on a simplistic GL like API
Drawing performed with in memory display lists
2MiB VRAM for frame buffer/textures/display lists
Can operate in a bus master mode to pull in textures/lists from main
RAM
Only data which needs to be in VRAM are framebuffers
Display Lists
Display Lists
The display lists are transferred to the GE using a DMA mechanism, this
has important ramifications when developing the lists.
A list can be transferred while building it using a ’Stall’ address
The list must be written using an uncached memory area or the data
cache written back before use
Lists should be terminated with a FINISH command
u i n t 3 2 t l i s t [ 2 5 6 ∗ 1 0 2 4 ] ; // Define a display list
i n t q i d = s c e G e L i s t E n Q u e u e ( l i s t , l i s t , c b i d , NULL ) ;
/∗ F i l l i n t h e d i s p l a y l i s t ∗/
s c e K e r n e l D c a c h e W r i t e b a c k I n v a l i d a t e A l l ( ) ; // Writeback cache
s c e G e L i s t U p d a t e S t a l l A d d r ( q i d , & l i s t [ endp ] ) ;
While the PSP’s main CPU does not have a general purpose MMU there
is the ability to do limited memory segmentation.
Kernel/User mode specification, prevents a user application modifying
kernel memory
32MiB main RAM split into 4MiB kernel only, 4MiB volatile memory,
24MiB user space
4MiB volatile memory only available through a system call (except on
v1.0 where it is available always)
Devices mapped into memory space
There is no virtual memory, all memory space is accessible as long as
you have the permissions.
Outline
1 History of PSP Home brew
Revisions of the PSP
2 PSP Hardware
The System Controller
3 PSP Software
The Toolchain
Modular Kernel
Threading Model
Programming Interfaces
PSP Security
4 Debugging
Debugging Tools
Compilers
The PSP compiler was developed using the experience of maintaining the
similar PS2 build tools.
Compiler based on the 4.0.2 revision of the GNU Compiler Collection
C and C++ development
Support for ALLGREX specific instructions including VFPU
Port of Newlib to support normal libc and stdc++ functions
(stdio/iostream etc.)
Designed for *nix like systems, to use on Windows requires either
Cygwin or MingW (DevkitPRO)
The PSPSDK
Whilst C and C++ are the main languages used for developing PSP
software you are not limited to using them.
Other options are:
LUA (LUAPlayer) - Ported version of LUA with a PSP specific
interface and libraries
Python - Port of python with PSP specific extensions
Flash - 2.7+ PSP firmware comes with a limited flash player
Modular Kernel
Executable Formats
The PSP uses the Executable and Linking Format (ELF) as the base for
its modules
The kernel can load 3 types of files natively
ELF - Basic ELF format, linked to a hard coded address (typically
0x8900000)
PRX - Customised ELF format, can be relocated anywhere in memory
space
˜PSP - An encrypted wrapper format for ELF or PRX
The PSPSDK is capable of producing ELF or PRX files but not the
encrypted ˜PSP format
Module Information
In order to do something useful the kernel modules can export library sets
to user mode applications.
The import of functions is done through special stub files, this is handled
for you by the SDK
User to kernel transitions are handled through a syscall gateway
User to user calls are just resolved to direct jumps
Functions are identified using a NID, for the kernel libraries this is the
first 32bits of the function name’s SHA1 hash
You cannot link user libraries to kernel modules. This has caused alot
of problems in the past.
While it is possible to export functions from your code using an export file,
it is not normally necessary.
Loading Modules
Loading and starting new modules is theoretically quite simple, there are
however a few important caveats.
The locations where modules can be loaded from is quite limited in
user mode
While there are few restrictions in kernel mode you then hit a linking
issue with some libraries
The kernel cannot load up plain text kernel PRX modules, although
ELF works fine
The SDK contains patches to ease some of these restrictions
SceUID modid ;
/∗ Load module ∗/
modid = s c e K e r n e l L o a d M o d u l e ( path , 0 , NULL ) ;
/∗ S t a r t module ∗/
s c e K e r n e l S t a r t M o d u l e ( modid , a r g s , argp , NULL , NULL ) ;
Kernel Reset
As the PSP’s kernel does not properly track resources for a module the
best way to get the PSP into a clean state is to the reset the kernel.
There are two normal ways of doing this:
Perhaps the most important part of the kernel, it is loaded first after
reboot.
Its tasks are as follows :
Manages the PSP’s memory allocation
Segments main RAM into 3 allocation partitions (kernel/ME/user)
Controls resource tracking (Unique Identifier Table)
Handle system event notification
Implements basic debug functionality
Resource Tracking
Thread Overview
The threading model on the PSP is quite simple. It is similar to the model
used in the PS2’s IOP kernel.
Threads are cooperative
Scheduling based on thread priority, the lower the number the higher
the priority
Small amount of thread local storage (TLS), referenced with the CPU
register K0.
To use the VFPU in your code the thread must be created with the
PSP THREAD ATTR VFPU attribute
Thread Creation
Threads must first be created then started. Once a thread is created it is
given a UID with which further actions can be performed.
i n t my thread ( SceSize args , void ∗ argp )
{ /∗ Do s o m e t h i n g ∗/ }
SceUID t h i d ;
/∗ C r e a t e a u s e r t h r e a d ∗/
t h i d = s c e K e r n e l C r e a t e T h r e a d ( ” MyThread ” , // Name
my thread , // Entry Point
20 , // Priority
16384 , // Stack size
0, // Attribute
NULL ) ;
/∗ S t a r t t h r e a d w i t h a r g u m e n t s ∗/
sceKernelStartThread ( thid , args , argp ) ;
Thread States
Synchronization Primitives
The PSP kernel provides a number of ways of performing thread
synchronization and control. All waits can have an optional timeout.
Mutual Exclusion
I Semaphores
I Interrupt Control
Message Posting
I Event Flags
I Message Boxes and Pipe
I Callbacks
Synchronized Memory Pools
I Variable Pools
I Fixed Pools
Timers
I Alarms
I Virtual Timers
Mutual Exclusion
Event Flags
Event flags allow you to post ’events’ between 2 or more thread.
An event flag consists of a 32x1bit events
One or more bits can be waited on at one time
Bits can be set to auto or manual reset modes
SceUID e v i d ;
e v i d = s c e K e r n e l C r e a t e E v e n t F l a g ( ” E v e n t ” , // Name
0, // Initial pattern
0, // Attributes
NULL ) ;
v o i d t h o n e ( ) { s c e K e r n e l S e t E v e n t F l a g ( e v i d , BITMASK ) ; }
void th two ( ) {
s c e K e r n e l W a i t E v e n t F l a g ( e v i d , BITMASK ,
PSP EVENT WAITCLEAR | PSP EVENT WAITOR , NULL , NULL ) ;
/∗ E v e n t p o s t e d , do s o m e t h i n g ∗/
}
Callbacks
Callbacks are used by the kernel to send special events in a thread context.
A thread must either poll for callbacks occurring or call a special wait
function, normally suffixed with CB.
i n t e x i t c b ( i n t a , i n t b , v o i d ∗p )
{ sceKernelExitGame ( ) ; return 0; }
/∗ C r e a t e c a l l b a c k ∗/
SceUID c b i d ;
c b i d = s c e K e r n e l C r e a t e C a l l b a c k ( ” E x i t ” , e x i t c b , NULL ) ;
sceKernelRegisterExitCallback ( cbid ) ;
/∗ S l e e p and w a i t f o r c a l l b a c k ∗/
sceKernelSleepThreadCB ( ) ;
Interrupts
File IO
File IO
Graphics Libraries
For basic graphics work such as directly writing pixels to VRAM only the
display library is needed.
Can setup frambuffer in 16bit (565, 5551, 4444) or 32bit colour.
Setup frame buffer with sceDisplaySetFrameBuf
sceDisplayWaitVblankStart puts the current thread into a wait state
until the next vblank interrupt, useful for synchronization and to allow
other threads to run
/∗ Se t u p d i s p l a y mode ∗/
sceDisplaySetMode (0 , 480 , 2 7 2 ) ;
/∗ S e t f r a m e b u f f e r t o 32 b i t c o l o u r ∗/
s c e D i s p l a y S e t F r a m e B u f ( 0 x4000000 , 5 1 2 , 3 , 1 ) ;
Graphics Libraries
libGU is the mainstay of developing hardware accelerated graphics for the
PSP.
It is based on a reverse engineered version of the official Sony libraries.
It acts as a wrapper around the GE and display hardware
Automatically manages display lists, can create online or offline lists
Handles setting up of the framebuffer and flipping
Graphics Libraries
LibGU and libGUM are not the only ways to display graphics on the PSP.
Some important libraries available are:
PSPGL, a hardware accelerated library with a GL style interface
SDL, useful for 2D graphics
Other libraries ported to the PSP for use with graphics display.
libPNG, PNG decoding
libJPEG, JPEG decoding
FreeType, TTF font library
Audio Libraries
Joypad
Using the joypad is simple affair, although not directly useful for demos it
can be useful for debugging.
All digital buttons are mapped in a button bitmask
The analogue stick is mapped to two unsigned 8bit words
S c e C t r l D a t a pad ;
/∗ I n i t i a l i s e t h e pad , a n a l o g u e mode ∗/
sceKernelSetSamplingCycle (0);
s c e K e r n e l S e t S a m p l i n g M o d e (PSP CTRL MODE ANALOG ) ;
for ( ; ; ) {
s c e C t r l R e a d B u f f e r P o s i t i v e (&pad , 1 ) ;
/∗ Do s o m e t h i n g w i t h pad . B u t t o n s o r pad . Lx / Ly ∗/
}
Thread Security
Threads have a privilege level which indicates if they can run in kernel or
user mode, this allows protection of kernel memory from user applications.
When creating a new thread you cannot escalate its privilege level
Thread primitives inherit permissions of the thread which created
them
Cannot enumerate or use thread primitives without the same privilege
During syscall transition a separate allocated stack is used to prevent
attacks or data leakage
All kernel functions which take pointer arguments check them based
on the threads privilege.
Different privilege levels handle module loading differently, kernel mode for
example does few checks.
An example of how a module is loaded is as follows:
1 Step 1. Check type of executable (user/kernel/encrypted/not
encrypted) etc.
2 Step 2. Check we are allowed to load from the specified device for
this type (user mode can only load from UMD)
3 Step 3. Load (and possibly decrypt) executable into memory
4 Step 4. Start module with a thread of the correct type (e.g. kernel for
kernel mode)
Is it really secure?
Outline
1 History of PSP Home brew
Revisions of the PSP
2 PSP Hardware
The System Controller
3 PSP Software
The Toolchain
Modular Kernel
Threading Model
Programming Interfaces
PSP Security
4 Debugging
Debugging Tools
Debugging
Of course all is not lost, there are ways of debugging without requiring an
expensive devkit from Sony
Blind Debugging
Originally the only option was blind debugging, build your application,
copy to the PSP and run it.
There are some features in the SDK to aid in this process (some only for
1.0 and 1.5 firmware)
On screen and via SIO textual output
Basic SIO based GDB stub
Functions to add a user specified exception handler
Miscellaneous functions to do call stack traces, enumerate threads etc.
Not exactly an efficient development process, all applications must be on
memory stick. Might be only option on 2.00+.
PSP Inside
A development and hacking tool created by Hitmen.
PSPLink
Exceptions
When the inevitable crash occurs PSPLink or PSP Inside will normally
split out a CPU exception. From this information the location of the crash
can be tracked and fixed.
Always build you application with the -g compiler switch to enable
debugging information
The exception will give an indication of what caused it
The exception will also print the EPC register, this is the memory
address at which the exception occurred
Pass the value of EPC to psp-addr2line to get a line number in your
executable
If it comes to it try and use GDB
psp−a d d r 2 l i n e −e program . e l f 0 x08900340
main . c : 6 8