Syscon powers up and sets up DRAM, sets up boot context buffer, turns on the cmep processor that starts the Boot ROM.
The PS Vita main application processor is an ARM Cortex A9 MPcore. It implements ARM TrustZone for execution in both a non-secure world and a sandboxed Secure World. However it is not the first processor to run on boot.
The cmep processor is the actual secure boot device rather than the ARM processor. The cmep processor bootrom ("first loader") is the first code running on PS Vita 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 bootrom. There are 2 layers of encryption. First it decrypts the per-console layer that was added during the firmware installation. After that it decrypts the factory-encrypted layer then begins execution. See Enc.
The Second Loader is primarily responsible for preparing the ARM processor. It initializes DRAM and decrypts kernel_boot_loader.self from eMMC SLB2 partition 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 TrustZone, as well as the non-secure kernel bootloader. At this point the kprx_auth_sm.self and prog_rvk.srvk read from the eMMC SLB2 partition are both loaded into DRAM. Finally, the Second Loader resets itself with a pointer to the secure_kernel.enp or enp_ binary.
Cmep processor then restarts and loads the secure_kernel.enp in and again decrypts the per-console layer that was added during the firmware install, and the factory layer. At this point the cmep processor is prepared and Secure Kernel tells Syscon to reset the ARM CPU at 0x00000000 (cmep scratch buffer). This triggers the ARM secure boot process.
Secure Kernel Bootloader
The secure kernel bootloader decompresses the ARZL compressed TrustZone 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 with svc mode. See Kernel Boot 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.
FW 0.931 special case
On FW 0.931, NSKBL embeds the kernel modules list in data segment instead of using the ScePsp2BootConfig kernel module. 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 the cmep 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
See also: SceSysStateMgr.
os0:psp2config.skprx once decrypted is a UTF-8 text file that is parsed by SceSysStateMgr. It is a 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 and encrypted SELF), then it will be launched. If "Development Mode" (DEVELOPMENT_MODE) is enabled (note that this does not necessarily mean PDEL nor DevKit), then
psp2config.skprx can be a plaintext file instead.
Comments start out with
As an example, here is the header of FW 1.69 psp2config.skprx:
# # PSP2 System Configuration for Release # # [NOTICE] # # This configuration is only for kernel_boot_loader_release.self. #
System Configuration scripts can contain conditional blocks executed based on the result of predicates (see SceSysStateMgr#if for more details). The table below describes the effect of some of them based on the standard bootscript (
|MANUFACTURING_MODE||Unit is in Manufacturing Mode (enabled by Jig). Try loading |
|EXTERNAL_BOOT_MODE||Skip mounting |
|UPDATE_MODE||Set by Syscon when an update is about to be performed. This info comes from Ernie NVS. In this case, psp2swu.self is loaded.|
|USB_ENUM_WAKEUP||This flag is set when the PS Vita boots due to USB CMA connection while device is turned off or USB automatic boot in IDU mode. Launches SceEnumWakeUp instead of Shell.|
|KERMIT_REV_ES1_X||Related to Kermit revision. ES1 units do not support the Home Menu and use |
|KERMIT_REV_ES2_X||Related to Kermit revision. Used to launch the appropriate GPU driver.|
|KERMIT_REV_ES3_X||Related to Kermit revision. Used to launch the appropriate GPU driver.|
|KERMIT_REV_ES4_X||Related to Kermit revision. Used to launch the appropriate GPU driver.|
|KERMIT10_REV_ES4_X||Related to Kermit revision. Used along with |
|KERMIT15_REV_ES1_X||Related to Kermit revision. Used along with |
|UD0_EXIST||Launch updater from |
|DEMO_MODE||Set if unit doesn't have |
|BSOD_REBOOT||Must the PS Vita boot in BSOD mode? This info comes from Ernie NVS. In this case, os0:kd/crashdump.skprx is loaded. Once the home menu appears a warning message about bad shutdown risks is displayed.|
|SAFE_MODE||Is the PS Vita booting in safe mode? This info comes from Ernie NVS. In this case, |
|DEVELOPMENT_MODE||SceSblACMgr is called to check if device is a development device and is in DevMode. This info comes from CP DIP Switches.|
|AU_CODEC_IC_CONEXANT||An audio IC chip from CONEXANT that could be seen only on late Slim PS Vita (CEX/DEX) units. This info comes from KBL Param#Hardware_flags. Load |
if SAFE_MODE spawn os0:ue/safemode.self end endif
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: |
All codes (from FW 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.
Second Loader checkpoint codes start at 0x40 (e.g. GPO value
0x52 corresponds to SBL code
The GPIO registers are registered at
0xE20A000C (turn off bits) and
0xE20A0008 (turn on bits). On PDEL units, this maps to the LED lights.
The Event column indicates what happens/is about to happen when a code is shown on the GPO LED. If boot of the unit doesn't succeed, the Halting event column indicates what caused the boot process to fail based on the last value of the GPO LED.
|64 / 0x40||second_loader (0.931)||SBL finished successfully|
|65 / 0x41||second_loader||Some Hardware Info check complete - GPO intiailization OK?|
|66 / 0x42||second_loader (0.931)||Something with Syscon||ERROR: communication with Syscon failed|
|67 / 0x43||second_loader||Register bigmac key 0x508 and 0x51B complete||ERROR: communication with Syscon failed|
|68 / 0x44||second_loader||ERROR: ?some check with keyring 0x501 and Cmep data? failed|
|69 / 0x45||second_loader||?Initializing LPDDR2?||ERROR: ?LPDDR2 initialization failed?|
|70 / 0x46||second_loader||Setting QA flags to bigmac keyring complete|
|71 / 0x47||second_loader (0.931)||Calling
|72 / 0x48||second_loader (0.931)||?Initializing SD/eMMC?||ERROR: ?SD/eMMC initialization failed?|
|73 / 0x49||second_loader (0.931)||?Loading
||ERROR: ?reading/loading/... |
|74 / 0x4A||second_loader (0.931)||ERROR: ?SD/eMMC I/O error?|
|75 / 0x4B||second_loader (0.931)||WARNING: Reading ConsoleID from eMMC failed|
|76 / 0x4C||second_loader (0.931)||ERROR: ?starting ARM clock failed? (cannot happen on FW 0.931)|
|77 / 0x4D||second_loader (0.931)||?Initializing SNVS?||ERROR: Writing 0x502-0x504/0x50B/... keyring failed (?SNVS init failed?) (cannot happen on FW 0.931)|
|78 / 0x4E||second_loader (0.931)||ERROR: SBL version mismatch with SVNS-stored firmware version|
|79 / 0x4F||second_loader (0.931)||ERROR: |
|80 / 0x50||second_loader (0.931)||Copying keyrings 0x602/0x601 to physical address 0xE0020100/0xE0020200|
|82 / 0x52||second_loader||ERROR: eMMC is not available|
|83 / 0x53||second_loader||WARNING: Reading OpenPSID from eMMC failed|
|84 / 0x54||second_loader||ERROR: Minimal firmware read failed / SBL version is lower than minimal firmware|
|85 / 0x55||second_loader||Setting factory firmware version to Bigmac keyring complete||WARNING: Something related to Syscon communication failed?|
|86 / 0x56||second_loader|
|87 / 0x57||second_loader (0.931)||WARNING: ???|
|88 / 0x58||second_loader (0.940)||WARNING: invalid/mismatched per-console information?|
|89 / 0x59||second_loader (0.931)||WARNING: ???|
|90 / 0x5A||second_loader||About to write SceKblParam to SPAD32K|
|94 / 0x5E||second_loader (0.931)||ERROR: SVNS-stored firmware version is lower than minimal firmware|
|96 / 0x60||second_loader||Setting SceKblParam complete and Start setting some device clock.|
|129 / 0x81||Secure Kernel BootLoader||Core 0 (secure world) pre-init complete|
|130 / 0x82||Secure Kernel BootLoader||Secure world interrupts registered (?)|
|131 / 0x83||Secure Kernel BootLoader||Serial console ready, boot message printed|
|132 / 0x84||Secure Kernel BootLoader||Some device init|
|133 / 0x85||Secure Kernel BootLoader||Some co-processor init. Starting point for other cores.|
|134 / 0x86||Secure Kernel BootLoader||MMU enabled, VBAR/MVBAR set up|
|135 / 0x87||Secure Kernel BootLoader||Nothing since 134|
|136 / 0x88||Secure Kernel BootLoader||Boot setup complete, secure kernel loading begin|
|137 / 0x89||Secure Kernel BootLoader||Secure kernel loaded. About to load NS KBL at
|138 / 0x8A||Secure Kernel BootLoader||Secure kernel loaded. About to resume context at
||ERROR: Undefined Instruction exception|
|139 / 0x8B||Secure Kernel BootLoader||ERROR: SVC exception (should not happen)|
|140 / 0x8C||Secure Kernel BootLoader||ERROR: Prefetch abort exception|
|141 / 0x8D||Secure Kernel BootLoader||ERROR: Data abort exception|
|142 / 0x8E||Secure Kernel BootLoader||ERROR: IRQ exception (should not happen)|
|143 / 0x8F||Secure Kernel BootLoader||ERROR: FIQ exception (should not happen)|
|161 / 0xA1||Non-Secure Kernel BootLoader||Core 0 (non-secure world) pre-init complete|
|162 / 0xA2||Non-Secure Kernel BootLoader||Some interrupts registered (?)|
|163 / 0xA3||Non-Secure Kernel BootLoader||Serial console ready, boot message printed (if enabled)|
|164 / 0xA4||Non-Secure Kernel BootLoader||Some buffer is initialized to device addresses|
|165 / 0xA5||Non-Secure Kernel BootLoader||Some co-processor init. Starting point for other cores.|
|166 / 0xA6||Non-Secure Kernel BootLoader||MMU enabled, VBAR set up|
|167 / 0xA7||Non-Secure Kernel BootLoader||Nothing since 166|
|168 / 0xA8||Non-Secure Kernel BootLoader||Boot setup complete, NS kernel loading begin|
|169 / 0xA9||Non-Secure Kernel BootLoader||Kernel pre-init (setup stacks, interrupts, etc) done. Right before first external loading.|
|170 / 0xAA||Non-Secure Kernel BootLoader||ERROR: Undefined Instruction exception|
|171 / 0xAB||Non-Secure Kernel BootLoader||ERROR: SVC exception (should not happen)|
|172 / 0xAC||Non-Secure Kernel BootLoader||ERROR: Prefetch abort exception|
|173 / 0xAD||Non-Secure Kernel BootLoader||ERROR: Data abort exception|
|174 / 0xAE||Non-Secure Kernel BootLoader||ERROR: IRQ exception (should not happen)|
|175 / 0xAF||Non-Secure Kernel BootLoader||ERROR: FIQ exception (should not happen)|
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.
See also Suspend.