KBL Param

The KBL Param buffer (temporary name was sysroot buffer) is a  bytes sized buffer passed to the Secure Kernel BootLoader in the scratch space and contains all sorts of flags and system parameters. This buffer is created in Second Loader copied to Secure Kernel, passed to the Secure and Non-Secure Kernel BootLoaders, and finally to the non-secure kernel. It is used by many functions to check for features that are enabled for the system. The strategy in this buffer is to compute once for all the information that is often used, to share it between all security layers not to have to implement generator code many times, and to implement the generation code in the most secure layer: second_loader (excluding first_loader but that's because first_loader is not updatable and has minimum code).

QA flags
In the following table bytes are counted from left to right and bits from left to right too (little-endian). However the OS uses bit masking for QA flags (unlike bit shifting for DIP Switches).

To check: Byte 0xF bit 7, byte 0xE bit 7, byte 0xE bit 6, byte 0xB bit 3: Revocation related.

The data below contains QA Flags captured (at 0x20 in sysroot buffer) from a System Debugger unit (SD DEM):

Boot flags
These Boot flags come from Ernie NVS and Ernie SNVS.

On FW 3.60, second_loader generates the boot flags as following:
 * byte 0 = NVS 0x4A0 byte 0
 * byte 1 = SNVS 0x480 byte 1
 * byte 2 = 0
 * byte 3 = SNVS 0x480 byte 3
 * byte 4 = SNVS 0x480 byte 7
 * byte 5 = SNVS 0x480 byte 6
 * byte 6-0xF = 0

Example: FF FF 00 FF FF FF 00 00 00 00 00 00 00 00 00 00


 * byte 0: 0xFF - not update mode
 * byte 1: 0xFF - extra UART not enabled
 * byte 3: 0xFF - not safe mode
 * byte 4: 0xFF - unknown, maybe not used on FWs <= 0.995
 * byte 5: 0xFF on FAT - no internal storage or on PSTV or SLIM - internal storage enabled, 0xFE on PSTV or SLIM - internal storage disabled, maybe not used on FWs <= 0.995

DIP Switches
DIP switches area embeds two parts: Communication Processor information as 32-bit integers, followed by DIP switches stored as bit flags.

DIP Switches bit flags resolving
Warning: DIP Switches bit flags actually start at offset 0x10 (before that is CP information), which implies the first bit flag number is 128 (bit_num = offset / 8).

DIP Switches bit flags follow little-endian logic, which makes it hard to visualize in commonly used big-endian hexadecimal:
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x00000001 (big-endian in hex) = 01 00 00 00 (little-endian in hex) = 10000000 00000000 00000000 00000000 (little-endian in base 2) <- the 1 corresponds to bit flag number 128
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x00000002 (big-endian in hex) = 02 00 00 00 (little-endian in hex) = 01000000 00000000 00000000 00000000 (little-endian in base 2) <- the 1 corresponds to bit flag number 129
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x00000100 (big-endian in hex) = 00 01 00 00 (little-endian in hex) = 00000000 10000000 00000000 00000000 (little-endian in base 2) <- the 1 corresponds to bit flag number 136
 * ((uint32_t *)kbl_param->dipsw[0x10])[0] = 0x80000000 (big-endian in hex) = 00 00 00 80 (little-endian in hex) = 00000000 00000000 00000000 00000001 (little-endian in base 2) <- the 1 corresponds to bit flag number 159

As you can see this way is not convenient to know in memory on which byte corresponds which bit flag, so instead we can use a formula to convert bit number to offset and bit:,. This is used for example in the following code:

CP Information
Bits  is a 32-bit integer of the current time on the CP clock. This is duplicated in bits.

Bits  is a 16-bit integer of the CP version and bits   is a 16-bit integer of the CP board ID. All integers are little-endian. On units that do not have a CP, these fields are zeroes.

Bits  is 32-bit integer ASLR seed that is randomized on each boot in second loader. It can be disabled by setting a specific DIP switch or QA flag byte 0xE mask 1.

Bits  are also manipulable as general purpose DIP Switches exposed with ,  , and   but these functions do not change anything in hardware (only cached values are overwritten in SceSysmem).

According to SDK only DIP Switches 0-63 are accessible from usermode, however:
 * On FW 0.990 (but not on FW 0.931 nor 3.60), DIP Switch number 237 is the only one out of range 0-63 that can be set from usermode.
 * Usermode SELFs can use DIP Switches number > 63 if they have a special attribute or capability in SELF Auth Info.

SDK (SCE) flags
Bits  are used for DevKit Boot Parameters.

Shell flags
Bits  are used for SceShell flags.

Debug control flags
Bits  are for various debug options.

System control flags
Bits  are used for various system options.

if ((System control flags & 1) != 0) { // not allow load QA flag } else { // allow load QA flag }

if ((System control flags & 2) != 0) { // clear qa flags // (SceQafMgrForDriver_382C71E8, SceQafMgrForDriver_52B4E164, sceSblQafMgrIsAllowHost0Access and sceSblQafMgrIsAllowDecryptedBootConfigLoad functions will return false) }

Boot type indicator 1
We ignore the official name so we name it Boot type indicator 1.


 * 0x1: external boot mode. It is used in internal FWs to boot in external mode. It cannot be set in external (release) second_loader.
 * 0x2: seems to be never set in external (release) second_loader
 * 0x4: product mode. manufacturing mode (Mgmt bit 0)
 * 0x8: seems to be never set in external (release) second_loader
 * 0x40: use special media type. Never set in external (release) second_loader. Used in NSKBL when loading modules from sd0:.
 * 0x10000: seems to be never set in external (release) second_loader, allows to bypass current fw check for module loading
 * 0x20000: on resume, no boot logo
 * 0x40000: manufacturing mode (Mgmt bit 0) and GCSD initialized (for mounting sd0:) by second_loader using Ernie command 0x888
 * 0x80000: ?sd mode? - (Mgmt bit 1)

Wakeup Factor

 * 14 FF 00 00
 * 04 FF 00 00 after normal reboot
 * 04 00 00 00
 * 00 FF 00 00
 * 0F 00 00 00 ?some debug mode?, -> sceSysrootIsUsbEnumWakeupForKernel : 1
 * 80 xx xx xx after suspend

Hardware Info
Data returned by Ernie.

The following list is ordered by Ernie version, that should approximately match the hardware revision order.


 * 03 10 10 00: supports FW 0.931
 * 03 20 10 00: supports FW 0.931
 * 00 40 31 00: supports FW 0.931
 * 03 24 10 00: supports FW 0.931-1.691, seems to be DEM-3000L (IRT-002) (to confirm)
 * 00 50 31 00: supports FW 0.931-1.691
 * 03 26 10 00: supports FW 0.940-3.68
 * 00 52 31 00: certainly DEM-3000H (IRT-001), supports FW 0.940-1.691
 * 00 10 41 00: supports FW 0.990-1.691
 * 00 40 41 00: supports FW 0.990-1.691
 * 00 50 41 00: supports FW 0.996-1.691
 * 00 52 41 00: supports FW 0.996-3.68
 * 00 60 41 00: PDEL-10XX (IRT-002), supports FW 1.000-3.68
 * 00 40 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 41 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 44 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 46 40 00: unknown DEX model, CEM-3000, supports FW 0.990-1.692
 * 00 48 40 00: unknown DEX model, supports FW 1.66-1.692
 * 00 50 40 00: unknown DEX model, supports FW 1.66-3.68
 * 00 52 40 00: unknown DEX model, supports FW 1.66-3.68
 * 00 60 40 00: PCH-10XX / PTEL-10XX (IRS-002 without 3G PCIe), supports FW 1.04-3.73
 * 02 60 40 00: PCH-11XX (IRS-002 with 3G PCIe), supports FW 1.04-3.73
 * XX XX 51 00: Prototype PSTV.
 * 00 10 60 00: hybrid TOOL/DEX/CEX model (IRS-1001), supports FW 1.80-3.73
 * 00 20 60 00: unknown DEX/CEX model (IRS-1001), supports FW 1.80-3.73
 * 00 30 60 00: unknown DEX/CEX model (IRS-1001), supports FW 1.80-3.73
 * 00 32 60 00: PCH-10XX / PCH-11XX (IRS-1001), supports FW 1.80-3.73
 * 30 30 70 00: VTE-10XX (DOL-1001), supports FW 2.50-3.73
 * 38 50 80 00: PCH-20XX / PTEL-20XX (USS-1001), supports FW 2.50-3.73
 * 30 30 72 00: VTE-10XX (DOL-1002), supports FW 3.30-3.73
 * 38 22 82 00: PCH-20XX (USS-1002), supports FW 3.50-3.73
 * XX XX 90 00: Unknown prototype.

Bytes meaning
Little-endian as usual.

First byte
This byte indicates the presence of some components:
 * 00 -> FAT WIFI
 * 02 -> 3G. This is what SceBbmc checks to know if 3G is supported.
 * 03 -> probably SD card reader
 * 30 -> PSTV (USB, ethernet)
 * 38 -> SLIM (micro USB)

Second byte
This byte indicates the motherboard minor version. It is relative to the motherboard main version which is indicated by third byte.

Third byte
This byte indicates the motherboard main version:
 * 10 -> unknown prototype motherboard, has Syscon, maybe IRS-001, seems to be IRT-002 (to confirm)
 * 31 -> IRT-001
 * 40 -> IRS-002
 * 41 -> IRT-002
 * 51 -> unknown prototype, maybe IRT-003
 * 60 -> IRS-1001
 * 70 -> DOL-1001
 * 72 -> DOL-1002
 * 80 -> USS-1001
 * 82 -> USS-1002
 * 90 -> unknown prototype, maybe PSP3

Fourth byte
This byte is reserved in case 3 bytes becomes not enough to handle all Hardware Info:
 * 00 -> default, unused

Experimental point of view
- No AC connected + No POWER Button pressed: 0x0 ex: rebooting by software PSVita when AC is not connected

- No AC connected + POWER Button pressed: 0x4 ex: booting PSVita by pressing POWER button when AC is not connected

- AC connected + No POWER Button pressed: 0x8 ex: rebooting by software PSVita when AC is connected ex: autobooting PSTV/IDU PSVita by pluging AC

- AC connected + POWER Button pressed: 0xC ex: powering off by software PSTV then booting it by pressing POWER button ex: booting PSVita by pressing POWER button when AC is connected

Hardware flags

 * all zeroes on most cases
 * seen values: 47 02, 07 00 on a Slim PSVita