Initial Program Loader: Difference between revisions

From PSP Developer wiki
Jump to navigation Jump to search
(Credits to SilverSpring for the info)
 
 
(12 intermediate revisions by 4 users not shown)
Line 1: Line 1:
Initial Program Loader, abbreviated as IPL, is a PSP program that runs on boot and loads Kernel. IPL is loaded by [[PRE-IPL]]. IPL can be stored either on the NAND or on a [[Magic Memory Stick]], depending on the PRE-IPL code and if a [[JigKick Battery]] is inserted or not.
On Devkits, the file is embedded after a pre-IPL known as [[Kbooti.bin]].
= Tools =
== Dumper ==
[https://github.com/KanadeEngel/PSP/tree/master/NAND-IPL-DUMPER NAND-IPL-DUMPER by KanadeEngel]
== Decrypter / Encrypter ==
[https://github.com/zecoxao/ipltool ipltool by zecoxao and others]
== IPL SDK ==
* [https://github.com/mathieulh/PSP_IPL_SDK PSP_IPL_SDK by mathieulh]
* [https://github.com/DaveeFTW/iplsdk iplsdk by davee]
* [https://www.brewology.com/downloads/download.php?id=10768&mcid=1 PSP-IPL-SDK Rev.0.5 (2007.10.9)]
== Bruteforce forger ==
[https://github.com/mathieulh/Kirk-Bruteforce Kirk-Bruteforce by Team C+D]
= Location =
Offset 0x40000 in the NAND (or NAND dump without ECC).
= Structure =
== Encrypted form ==
IPL is divided into chunks of 0x1000 bytes, the size of the buffer used at address 0xBFD00000 where they are decrypted. The IPL blocks are standard KIRK cmd 1 blocks and passed directly to [[KIRK Crypto Engine]] for decryption.
== Decrypted form ==
=== Retail ===
The decrypted IPL is composed of 3 parts: Part1 - the 'loader', Part2 - 'main.bin', and Part3 - the 'payload', aka 'kbooti_for_ipl'.
Part1 is plaintext MIPS code, Part2 is gzip compressed, and Part3 is again encrypted (from 2.60 onwards, parts 2 & 3 are further encrypted again). Part3 is what actually loads the kernel modules from flash and begins the kernel boot process.
=== Prototype 0.4.0-0.6.0 (23-07-2004 or older) ===
The decrypted IPL only contains the 'payload'
= IPL Boot Sequence =
= IPL Boot Sequence =
<pre>
The decrypted IPL is composed of 3 parts:
Part1 - the 'loader', Part2 - 'main.bin', and Part3 - the 'payload'.
Part1 is plaintext MIPS code, Part2 is gzip compressed, and Part3 is
again encrypted (from 2.60 onwards, parts 2 & 3 are further encrypted
again).
</pre>


== Part1 IPL (the loader) ==
== Part1 IPL (the loader) ==


<pre>
One of the first things Part1 IPL does is reset the main CPU.
One of the first things Part1 IPL does is reset the main CPU.
After reset the preipl mask ROM device is no longer mapped to memory at
 
all (the 0x1FC00000 address range is then remapped to the 4KB RAM
After reset the PRE-IPL mask ROM device is no longer mapped to memory at all (the 0x1FC00000 address range is then remapped to the 4KB RAM mentioned above to be used for the ME reset vector). This is why the PRE-IPL is no longer accessible once the IPL has booted.
mentioned above to be used for the ME reset vector). This is why the  
 
preipl is no longer accessable once the IPL has booted. The Part1 IPL  
Part1 IPL does some very basic hardware inits and decompresses the gzipped Part2 IPL (main.bin) to address 0x04000000 (still in EDRAM).
does some very basic hardware inits and decompresses the gzipped Part2  
 
IPL (main.bin) to address 0x04000000 (still in EDRAM). Part1 IPL then  
Part1 IPL then jumps to the entry address of main.bin (0x04000000) to initialize the hardware.
jumps to the entry address of main.bin (0x04000000) to initialise the  
hardware.
</pre>


== Part2 IPL (main.bin) ==
== Part2 IPL (main.bin) ==


<pre>
Part2 IPL (main.bin) is responsible for initializing the PSP hardware.
Part2 IPL (main.bin) is responsible for initialising the PSP hardware.
 
It has copies of it's own driver libraries similar to the drivers found  
It has copies of its own driver modules similar to the drivers found in the firmware (including: sceNAND_Driver, sceDDR_Driver, sceIdStorage_Service, sceSYSREG_Driver, sceSYSCON_Driver, sceGPIO_Driver, sceClockgen_Driver, & sceI2C_Driver). Some of the initialisation of the hardware depends on data stored in IDStorage leaves (for example leaves 4, 5, 6). Note this is where TA-082 / TA-086 motherboards 'brick' on 1.50 firmware. The clockgen hardware was changed on TA-082 / TA-086 motherboards so the functions used to initialize it does not recognise the new hardware. And because part of the initialization depends on data stored in leaf 5, simply by invalidating leaf 5 (by corrupting the header), the initialization is skipped allowing the firmware to continue to boot. See [https://psp.brewology.com/downloads/download.php?id=6454 IdRepair by codes02].
in the firmware (including: sceNAND_Driver, sceDDR_Driver,  
 
sceIdStorage_Service, sceSYSREG_Driver, sceSYSCON_Driver,  
After initializing the hardware (including the DDR RAM), Part2 IPL decrypts Part3 IPL (the payload) and loads it to address 0x08400000 (which is located in normal DDR RAM now that it has been initialised).
sceGPIO_Driver, sceClockgen_Driver, & sceI2C_Driver). Some of the  
 
initialisation of the hardware depends on data stored in idstorage keys
It then jumps to the entry address of the Part3 IPL (0x08400000) to boot the firmware.
(for example keys 4,5,6). Note this is where TA082/086 motherboards  
'brick' on 1.50 firmware. The clockgen hardware was changed on TA082/086
motherboards so the functions used to initialise it does not recognise  
the new hardware. And because part of the initialisation depends on data
stored in key5, simply by invalidating key5 (by corrupting the header),  
the initialisation is skipped allowing the firmware to continue to boot.
After initialising the hardware (including the DDR RAM), Part2 IPL  
decrypts the Part3 IPL (the payload) and loads it to address 0x08400000  
(which is located in normal DDR RAM now that it has been initialised).
It then jumps to the entry address of the Part3 IPL (0x08400000) to boot
the firmware.
</pre>


== Part3 IPL (the payload) ==
== Part3 IPL (the payload) ==


TODO
Part 3 is really the IPL equivalent of reboot.bin. Since part2 kindly initialized main DDR memory, part3 is the first to actually run inside DDR. On most modern firmwares this will load to 0x88600000.
 
After some initial clean up of the co-processsors, this begins by loading /kd/sysmem.prx and /kd/loadcore.prx from flash0. Part3 contains a kernel version of the main prx decrypt routines as well as the keys for decrypting the prx tags for this version of the kernel. This is very similar to what you would find in mesg_led.prx.
 
At the conclusion of the load, part3 sets a series of useful function pointers for loadcore.prx and transfers control to loadcore for the rest of the kernel load process.
 
= Custom IPL =
 
It is possible to load a custom IPL by either:
* exploiting PRE-IPL to run unsigned IPL (never done)
* crafting a fake IPL using bruteforce (since 2007 thanks to [[Prometheus Project]])
* crafting a valid encrypted and signed IPL using recovered keys (since 2018 thanks to PS3 hacks and mathieulh)
 
See [[PRE-IPL]] and [[Pandora]].
 
= See also =
 
* [https://web.archive.org/web/20090206152144/http://dark-alex.org/forum/viewtopic.php?f=44&t=1194&start=0 IPL security explanation by Dark_Alex]
* [https://lolhax.org/2011/07/03/a-look-at-the-ta-88v3-ipl-hash/ Explanation by Davee]

Latest revision as of 03:34, 25 March 2024

Initial Program Loader, abbreviated as IPL, is a PSP program that runs on boot and loads Kernel. IPL is loaded by PRE-IPL. IPL can be stored either on the NAND or on a Magic Memory Stick, depending on the PRE-IPL code and if a JigKick Battery is inserted or not.

On Devkits, the file is embedded after a pre-IPL known as Kbooti.bin.

Tools[edit | edit source]

Dumper[edit | edit source]

NAND-IPL-DUMPER by KanadeEngel

Decrypter / Encrypter[edit | edit source]

ipltool by zecoxao and others

IPL SDK[edit | edit source]

Bruteforce forger[edit | edit source]

Kirk-Bruteforce by Team C+D

Location[edit | edit source]

Offset 0x40000 in the NAND (or NAND dump without ECC).

Structure[edit | edit source]

Encrypted form[edit | edit source]

IPL is divided into chunks of 0x1000 bytes, the size of the buffer used at address 0xBFD00000 where they are decrypted. The IPL blocks are standard KIRK cmd 1 blocks and passed directly to KIRK Crypto Engine for decryption.

Decrypted form[edit | edit source]

Retail[edit | edit source]

The decrypted IPL is composed of 3 parts: Part1 - the 'loader', Part2 - 'main.bin', and Part3 - the 'payload', aka 'kbooti_for_ipl'.

Part1 is plaintext MIPS code, Part2 is gzip compressed, and Part3 is again encrypted (from 2.60 onwards, parts 2 & 3 are further encrypted again). Part3 is what actually loads the kernel modules from flash and begins the kernel boot process.

Prototype 0.4.0-0.6.0 (23-07-2004 or older)[edit | edit source]

The decrypted IPL only contains the 'payload'

IPL Boot Sequence[edit | edit source]

Part1 IPL (the loader)[edit | edit source]

One of the first things Part1 IPL does is reset the main CPU.

After reset the PRE-IPL mask ROM device is no longer mapped to memory at all (the 0x1FC00000 address range is then remapped to the 4KB RAM mentioned above to be used for the ME reset vector). This is why the PRE-IPL is no longer accessible once the IPL has booted.

Part1 IPL does some very basic hardware inits and decompresses the gzipped Part2 IPL (main.bin) to address 0x04000000 (still in EDRAM).

Part1 IPL then jumps to the entry address of main.bin (0x04000000) to initialize the hardware.

Part2 IPL (main.bin)[edit | edit source]

Part2 IPL (main.bin) is responsible for initializing the PSP hardware.

It has copies of its own driver modules similar to the drivers found in the firmware (including: sceNAND_Driver, sceDDR_Driver, sceIdStorage_Service, sceSYSREG_Driver, sceSYSCON_Driver, sceGPIO_Driver, sceClockgen_Driver, & sceI2C_Driver). Some of the initialisation of the hardware depends on data stored in IDStorage leaves (for example leaves 4, 5, 6). Note this is where TA-082 / TA-086 motherboards 'brick' on 1.50 firmware. The clockgen hardware was changed on TA-082 / TA-086 motherboards so the functions used to initialize it does not recognise the new hardware. And because part of the initialization depends on data stored in leaf 5, simply by invalidating leaf 5 (by corrupting the header), the initialization is skipped allowing the firmware to continue to boot. See IdRepair by codes02.

After initializing the hardware (including the DDR RAM), Part2 IPL decrypts Part3 IPL (the payload) and loads it to address 0x08400000 (which is located in normal DDR RAM now that it has been initialised).

It then jumps to the entry address of the Part3 IPL (0x08400000) to boot the firmware.

Part3 IPL (the payload)[edit | edit source]

Part 3 is really the IPL equivalent of reboot.bin. Since part2 kindly initialized main DDR memory, part3 is the first to actually run inside DDR. On most modern firmwares this will load to 0x88600000.

After some initial clean up of the co-processsors, this begins by loading /kd/sysmem.prx and /kd/loadcore.prx from flash0. Part3 contains a kernel version of the main prx decrypt routines as well as the keys for decrypting the prx tags for this version of the kernel. This is very similar to what you would find in mesg_led.prx.

At the conclusion of the load, part3 sets a series of useful function pointers for loadcore.prx and transfers control to loadcore for the rest of the kernel load process.

Custom IPL[edit | edit source]

It is possible to load a custom IPL by either:

  • exploiting PRE-IPL to run unsigned IPL (never done)
  • crafting a fake IPL using bruteforce (since 2007 thanks to Prometheus Project)
  • crafting a valid encrypted and signed IPL using recovered keys (since 2018 thanks to PS3 hacks and mathieulh)

See PRE-IPL and Pandora.

See also[edit | edit source]