When the S-Gold is reset, the ROM mask enable bit is set and the lower 0x8000 bytes of memory comes from the ROM mask. The reset vector in ROM jumps to 0x400000, 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)); } }