- 1 Boot Process
- 2 Boot Partition
- 3 System Configuration Script
- 4 Boot Debug Checkpoint Codes
- 5 Suspend and Resume
The F00D processor is the actual secure boot device rather than the ARM processor. The F00D processor bootrom ("first loader") is the first code running on PSVita start. Once it starts it likely maps the eMMC and directly reads in the second_loader.enp or second_loader.enp_ from the eMMC slb2 partition. This is in the native load format of the F00D bootrom. There are likely 2 layers of encryption. First it decrypts the per-console layer that was added during the install. After that it will decrypt the factory-encrypted layer then begin execution.
The second_loader is primarily responsible for preparing the ARM processor. It initializes DRAM and decrypts slb2 kernel_boot_loader.self into DRAM. It also writes the ARM exception vector and some boot context information to the 32KB scratch buffer (mirror mapped to 0x00000000 on ARM). kernel_boot_loader.self contains both the secure kernel bootloader and secure kernel, as well as the non-secure kernel bootloader. At this point the slb2 kprx_auth_sm.self and prog_rvk.srvk are both loaded into DRAM.
Finally, the second_loader resets itself with a pointer to the secure_kernel.enp or enp_. F00D processor then restarts and loads the secure_kernel.enp in and again decrypts the per-console layer that was added by the install, and the factory layer. At this point the F00D processor secure kernel is prepared and it resets the ARM CPU at 0x00000000 (F00D scratch buffer). This triggers the ARM secure boot process to begin.
Secure Kernel Bootloader
The secure kernel bootloader decompresses the ARZL compressed secure kernel, loads it and sets up the VBAR and MVBAR. It then decompresses the ARZL non-secure kernel bootloader, sets NS in SCR and jumps into non-secure kernel bootloader. See Kernel Loader for more information.
Non-secure Kernel Bootloader
The non-secure kernel bootloader contains an embedded and likely stripped version of SceSysmem, SceKernelModulemgr, SceSblSmschedProxy, and some other core drivers. The NSKBL sets up the eMMC device (again) and starts
This kernel module does not export any library. It only has a module init function that has a hard coded list of core kernel modules (ex: sysmem.skprx) which are loaded with calls back into NSKBL through SceKblForKernel imports. Once the core initialization is done, the next module to run is SceSysStateMgr.
0.931 special case
On 0.931, NSKBL embeds the kernel modules list instead of using ScePsp2BootConfig. Here is the list:
sysmem.skprx excpmgr.skprx intrmgr.skprx systimer.skprx acmgr.skprx threadmgr.skprx dmacmgr.skprx ssproxy.skprx smsc_proxy.skprx authmgr.skprx iofilemgr.skprx modulemgr.skprx processmgr.skprx backtrace.skprx sdbgsdio.skprx deci4p_sdfmgr.skprx deci4p_sttyp.skprx deci4p_sdbgp.skprx deci4p_sdrfp.skprx stdio.skprx lowio.skprx clockgen.skprx sdif.skprx sdstor.skprx fatsd.skprx exfatfs.skprx pamgr.skprx sysstatemgr.skprx
This kernel module also does not export any library. Its init function first maps all the SceKernelBootimage embedded modules and redirects them to os0:kd/. Then it decrypts
os0:psp2config_dolce.skprx and parses the System Configuration Script to load the remaining modules and finally either SceSafemode or SceShell or ScePsp2Swu or ScePsp2Diag.
The boot partition is SLB2 formatted. It contains entries these files:
|Name||Earliest Known Version||Comments|
|kernel_boot_loader.self||0.931||Secure KBL and ARZL compressed NS KBL|
|kprx_auth_sm.self||0.931||Used with F00D Processor to decrypt SELFs|
|prog_rvk.srvk||0.931||SCE encrypted SELF revocation list|
|second_loader.enp_||0.931||Related to second_loader.enp in some way, likely for encryption|
|secure_kernel.enp||0.931||Secure kernel loader|
|secure_kernel.enp_||0.931||Related to secure_kernel.enp in some way, likely for encryption|
|secure_kernel.xxx||0.931||Prototype secure kernel loader encrypted differently than secure_kernel.enc|
System Configuration Script
os0:psp2config.skprx once decrypted is a UTF-8 text file that is parsed by SceSysStateMgr. It is a very simple script format.
If "Producting Mode" (MANUFACTURING_MODE) is enabled, then it is possible to load
sd0: (SD adapter in GameCard slot) or
ux0:. However, the files must still be signed and encrypted SELFs. In "Producting Mode" if
ux0:psp2diag.self exists (and is a valid signed & encrypted SELF), then it will be launched. If "Development Mode" (DEVELOPMENT_MODE) is enabled (note that this does not necessarily mean PDEL or devkit), then
psp2config.skprx can be a plaintext file instead.
Comments start out with
#, as an example, here's the header of 1.69 psp2config.skprx
# # PSP2 System Configuration for Release # # [NOTICE] # # This configuration is only for kernel_boot_loader_release.self. #
Conditionals start with
if and end with
endif. There are certain conditional constants defined in SceSysStateMgr. A table of known conditionals is below.
|MANUFACTURING_MODE||Unknown. Depends on some condition set on boot by some bootloader|
|EXTERNAL_BOOT_MODE||Unknown. Depends on some condition set on boot by some bootloader|
|UPDATE_MODE||Set by Syscon when an update is about to be performed.|
|USB_ENUM_WAKEUP||Unknown. Could be CMA connection while device is turned off or IDU mode USB boot.|
|KERMIT_REV_ES1_X||Unknown. GPU hardware revision related.|
|KERMIT_REV_ES2_X||Unknown. GPU hardware revision related.|
|KERMIT_REV_ES3_X||Unknown. GPU hardware revision related.|
|KERMIT_REV_ES4_X||Unknown. GPU hardware revision related.|
|UD0_EXIST||Does the ud0: Partition exist?|
|DEMO_MODE||Is the Vita a IDU/ShowMode flagged?|
|SAFE_MODE||A flag in sysroot buffer indicates device should enter safe mode.|
|DEVELOPMENT_MODE||SceSblACMgr is called to check if device is a development device and is in DevMode.|
if SAFE_MODE spawn os0:ue/safemode.self end endif
load path will load the kernel module at
tload path possibly stands for "test load." Possibly used in development units to load to module to dedicated devkit RAM.
spawn path will spawn an app and continue processing the script in the background.
spawnwait path will spawn an app and wait for it to exit before continuing processing the script.
appspawn path param is used to spawn the app self located at
path with the parameter
Known param constants:
|SHELL_BUDGET_ID||Unknown. Example modules: |
|GAME_BUDGET_ID||Unknown. Example module: |
if UPDATE_MODE if UD0_EXIST spawn ud0:PSP2UPDATE/psp2swu.self else spawn ur0:PSP2UPDATE/psp2swu.self endif end endif
include path will include and process a config script located at
end will end script processing
Any line that starts with
- will not fail the boot sequence if the line fails. For example, you can specify an optional module to load such that boot continues if the module does not exist or errors on load.
All codes (from 0.990)
load, unload, loadonly, start, stop, unloadonly, spawn, spawnwait, wait, kill, loadconfig, ifmodel, ifnmodel, setenv, setmodfile, repeat, endrepeat, appspawn, tload
+ include, if, endif, end
Boot Debug Checkpoint Codes
During the boot sequence, the various bootloaders will update a GPIO register specifying the progress into boot. This can be used to debug where in the boot process something fails.
The GPIO registers are registered at
0xE20A000C (turn off bits) and
0xE20A0008 (turn on bits). On PDEL units, this maps to the LED lights.
|129||Secure Kernel Loader||Core 0 (secure world) pre-init complete|
|130||Secure Kernel Loader||Secure world interrupts registered (?)|
|131||Secure Kernel Loader||Serial console ready, boot message printed|
|132||Secure Kernel Loader||Some device init|
|133||Secure Kernel Loader||Some co-processor init. Starting point for other cores.|
|134||Secure Kernel Loader||MMU enabled, VBAR/MVBAR set up|
|135||Secure Kernel Loader||Nothing since 134|
|136||Secure Kernel Loader||Boot setup complete, secure kernel loading begin|
|137||Secure Kernel Loader||Secure kernel loaded. About to load NS KBL at |
|138||Secure Kernel Loader||Secure kernel loaded. About to resume context at |
|139||Secure Kernel Loader||SVC exception (should not happen, error)|
|140||Secure Kernel Loader||Prefetch abort exception|
|141||Secure Kernel Loader||Data abort exception|
|142||Secure Kernel Loader||IRQ exception (should not happen, error)|
|143||Secure Kernel Loader||FIQ exception (should not happen, error)|
|161||NS Kernel Loader||Core 0 (non-secure world) pre-init complete|
|162||NS Kernel Loader||Some interrupts registered (?)|
|163||NS Kernel Loader||Serial console ready, boot message printed (if enabled)|
|164||NS Kernel Loader||Some buffer is initialized to device addresses|
|165||NS Kernel Loader||Some co-processor init. Starting point for other cores.|
|166||NS Kernel Loader||MMU enabled, VBAR set up|
|167||NS Kernel Loader||Nothing since 166|
|168||NS Kernel Loader||Boot setup complete, NS kernel loading begin|
|169||NS Kernel Loader||Kernel pre-init (setup stacks, interrupts, etc) done. Right before first external loading.|
|170||NS Kernel Loader||Undefined instruction exception|
|171||NS Kernel Loader||SVC exception (should not happen, error)|
|172||NS Kernel Loader||Prefetch abort exception|
|173||NS Kernel Loader||Data abort exception|
|174||NS Kernel Loader||IRQ exception (should not happen, error)|
|175||NS Kernel Loader||FIQ exception (should not happen, error)|
Suspend and Resume
Upon suspension, context is written to memory and a syscon command is issued to save the context pointer as well as other information (for example, if it should restart into update mode). When resuming, the boot process is the same as cold boot up until the secure kernel bootloader. After secure kernel loads, instead of decompressing and jumping to the non-secure kernel bootloader, it restores the saved context and returns to the kernel resume code.