Kernel Loader

From Vita Development Wiki
Jump to: navigation, search

The kernel loader is (likely) the third stage bootloader for the system. It is kernel_boot_loader.self in the Boot Partition. It initializes the ARM TrustZone Secure Kernel and non-secure kernel.

ARM Secure Bootloader (SBL)

It is speculated that the first stage of the secure boot process is the Boot ROM in the MeP core and second loader in the MeP core to decrypt kernel_boot_loader.self into DRAM and reset ARM. The stage at this point would have set up DRAM and the eMMC driver. There is no VMA at this point. A couple of things are loaded into memory. kprx_auth_sm.self from the SLB2 boot partition is located at 0x40000500 (as-is/encrypted). Similarly prog_rvk.srvk is located at 0x40008B00. The compressed non-secure bootloader is loaded to 0x50000000. The VBAR is likely set to 0x40000000, where most handlers point to unhandled exception error code. The bootloader code is loaded to 0x40020000 (where the reset vector points to) and are in three main parts. The first part is the bootloader code which includes stripped down versions of SceSysmem, SceKernelModulemgr, and initialization code (reset vector points to code in this range). The second part is the Secure Kernel stored as a series of either plaintext ELFs or ARZL compressed ELF. On 1.69, only SceSysmem is ARZL compressed, the other ones are plaintext. Additionally, some initialization data is passed in 0x4005A000, 0x0, and 0x100.


The reset function cleans the cache and resets many CP15 registers. Next it does some more device initialization and prints out the debug string Starting PSP2 Kernel Boot Loader. Core 0 then creates some initialization data from parameters passed in from the previous stage as well as with params hard coded. This includes the VMA for the VBAR, MVBAR, TTBR0, TTBR1, and other configurations. It then turns on virtual memory and maps the defined regions for everything defined above. Other cores wait for this to complete and then just use the initialization data created by core 0. The L2 cache is also setup at this point. After this point, the low-level system is finished initializing.

Secure Kernel

Next the secure kernel is loaded with the stripped down module manager inside the bootloader. First SceSysmem, which is ARZL compressed is decompressed to scratch space at 0x1C000000. Then the ELF loader loads it and the memory manager's initialization function is called which setups the memory system in secure world. This also setups sysroot in secure world. Data from physical address 0x100 is copied to the buffer allocated at offset 0x6C0 of the sysroot buffer (in 1.69 this is 0x46C0 in secure world). The other ELFs are not compressed and just loaded as-is to the ELF loader. SceExcpmgr is loaded next and its initialization function replaces the vectors pointed to by VBAR and MVBAR. The MVBAR determines how SMC calls are handled and is the entry point to secure world. Other modules' initialization functions invoke SceExcpmgr functions to register SMC handlers. When SceSblSmsched is initialized, it initialized the security processor with kprx_auth_sm.self and prog_rvk.srvk found in memory. After this point is likely when signature revocation would take affect. The other modules are loaded and after that, the secure world is completely done loading.

Non-secure Bootloader

The Non-secure Bootloader is stored as an ARZL compressed binary at physical address 0x50000000. It is uncompressed to 0x51000000. The reset vector for non-secure bootloader is also found at 0x51000000. The initialization data initially found at 0x100 is copied to 0x40300100 so non-secure world can access it. It then switches to non-secure world by writing to SCR and does a return-from-exception to the non-secure reset vector. The non-secure bootloader then has to setup everything (including VMA) again in the non-secure world. The initialization of the non-secure bootloader is almost exactly the same as the secure version.

Non-secure Kernel

TODO: Talk about os0:psp2bootconfig.skprx loading and stuff.