When the S-Gold is reset, the ROM mask enable bit is set and the lower 0×8000 bytes of memory comes from the ROM mask. The reset vector in ROM jumps to 0×400000, what we're calling the S-Gold “bootrom”. The following is pseudocode for the decisions made by the bootrom following a reset – whether to simply run the existing bootloader by jumping to the address contained at 0xA0000038 or whether to accept a serial payload and execute that instead.
Notes:
boot_based_on_reset_type() {
if (SCU_SNUM2[24]==1) { // special HWID
boot_special_iphone();
/*NOTREACHED*/
}
if (*watchdog reset*) {
boot_flag1 = 2;
set_watchdog_timer_value(3000);
run_bl_if_cjkt();
} else if (*software reset*) {
boot_flag1 = 1;
set_watchdog_timer_value(3000);
run_bl_if_cjkt();
} else if (*external reset*) {
boot_flag1 = 0;
run_bl_or_bldl();
} else {
while (1); // loop forever
}
}
static int beenhere = 0;
run_bl_if_cjkt() {
if (beenhere==1)
while (1); // loop forever
beenhere = 1;
ebu_setup_bl_memory(); // can be nor or flash or even sdram
bl_start = readbl(0xA0000038);
bl_cjkt = readbl(0xA000003C);
if ( bl_start&0x3 || bl_cjkt!="CJKT")
run_bl_or_bldl();
else
jump to bl_start;
/*NOTREACHED*/
}
external char *serialbuf;
run_bl_or_bldl() {
if (*serial port does not have "AT" waiting*) {
run_bl_if_cjkt();
/*NOTREACHED*/
}
while (*serial port still being spammed with "AT"*)
; // wait for final AT
serial_tx(0xC0); // hello
while (serial_rx() != 0x30)
; // wait for 0x30 (helloACK)
while(load_from_serial(serialbuf)==0) {
serial_tx(0x1C); // failed XOR checksum
// try again
}
serial_tx(0xC1); // passed XOR checksum
if (SCU_SNUM3[24]==1) { // special HWID
jump to serialbuf; // excecute serial payload without further checks
}
int cb = checkblank();
if (cb==-1) { // bootloader is intact
while (1); // loop forever
} else if (cb==0) { // bootloader is "empty"
jump to serialbuf; // execcute serial payload
} else if (cb==1) { // bootloader is "special"
jump to (readbl(0xA0000030));
}
}