ROM-SPL Handoff¶
The transition from the boot ROM through the SPL and into NK.exe is mediated by a set of mailbox addresses in low SDRAM and a callback table populated by the ROM's MIPS16 boot dispatcher.
Mailbox Contract¶
Two physical addresses in SDRAM serve as the communication channel between boot stages:
| Address | Purpose | Expected Value |
|---|---|---|
PA 0x2400 |
Version marker | 0x03020100 (checked by NK.exe at VA 0x76CBC) |
PA 0x24FC |
Next-stage entry address | NK.exe entry point (written by SPL) |
Write Sequence¶
- The SPL decompresses NK.exe into RAM starting at PA
0x60000 - The SPL writes the NK.exe entry address to PA
0x24FC(with0x20000000mask, converting to a kseg1 address) - The SPL writes version marker
0x03020101to PA0x2400 - Control returns to the boot ROM
Read Sequence¶
- The ROM checks PA
0x2400for cold/warm state - After completing section copying and callback registration, the ROM loads PA
0x24FC - The ROM executes
JRto the address found at PA0x24FC, entering NK.exe
Note
The version marker at PA 0x2400 has a subtle difference: the SPL writes 0x03020101, but NK.exe checks for 0x03020100. The low byte difference does not affect the check at 0x76CBC, which masks or ignores it. If the version check fails, NK.exe clears PA 0x254C, which prevents the hibernate path from activating.
SPL Callback Table¶
The SPL registers a callback table at VA 0x80F01590 with hooks for:
- Open/init -- initialize the NAND reading subsystem
- Read/copy -- read data from NAND into RAM
- Seek -- position within the NAND image
- Metadata hooks -- image metadata queries
These callbacks allow the ROM's boot dispatcher to invoke SPL NAND-reading functions during the late boot phase.
MIPS16 Section Copier (0x9FC00C85)¶
Before NK.exe starts, the ROM's MIPS16 section copier processes the COPYentry table embedded in the NK.exe image:
- NK.exe has an
"ECEC"signature at file offset0x40 - The pTOC pointer at offset
0x44points to the ROMHDR at VA0x80655C54 - The ROMHDR contains 1 COPYentry:
| Field | Value |
|---|---|
| Source | 0x800BBA70 |
| Destination | 0x80660000 |
| Copy size | 1,029 bytes |
| Total size | 52,852 bytes (includes BSS zero-fill) |
This copies the kernel's initialized .data section and zeros the .bss section before NK.exe begins execution.
MIPS16 Boot Dispatcher (0x9FC00C21)¶
The boot dispatcher runs after the section copier and performs two critical tasks:
OEMInit Callback Table¶
The dispatcher populates a callback table at PA 0x51680 with function pointers into NK.exe OAL code. This table contains:
- 11 callback groups
- 55 non-zero words (function pointers)
- 32 entries total, each 20 bytes (some entries are empty)
- Function pointers target addresses in the
0x8007xxxxand0x800Axxxxranges
These callbacks are invoked later by NK.exe's OEMInit function (dispatcher at 0x7AB38), which walks the table and calls each registered function pointer via JALR.
NAND Driver Initialization¶
The boot dispatcher also initializes the NAND driver state, reading partition descriptors via FUN_9fc015dc (which reads partition entry 1, the SPL location) and setting up data structures for later NAND access.
Complete Handoff Timeline¶
ROM: CP0 init, HW init, cold/warm detection
ROM: Clear PA 0x2400/0x24FC (cold boot)
ROM: Set SP = 0x80003800, serial init
ROM: Load SPL from NAND into 0x80F00000
SPL: HW init (VR4131, VRC4173)
SPL: Read NK.exe from NAND, decompress to 0x80060000
SPL: Write entry to PA 0x24FC, version to PA 0x2400
SPL: Return to ROM
ROM: BINFS section copier (MIPS16) -- copy .data, zero .bss
ROM: Boot dispatcher (MIPS16) -- register callbacks at PA 0x51680
ROM: SIU poke + BCU read loop
ROM: Load PA 0x24FC → JR to NK.exe entry