-------------------------------------------------------------------------------
-= NINTENDO GAMECUBE Initial Program Loader RE =-
-------------------------------------------------------------------------------
IPL, or bootrom contained inside Flipper die. bootstrap code, called "BS2" is
encrypted by LFSR + XOR algorithm. run-flow looks like this : at first Flipper
placing decrypting code at 0x80000100, its about 0x728 bytes and contain
LFSR decrypting routines. since there is no undamaged sniff-logs, its
impossible to reverse LFSR algorithm from this little program. after that,
Flipper copy crypted part of IPL to upper memory at 0x81300000, and return
control to Gekko as usual RESET.
BS2 was written by C, using official SDK libraries, probably earlier than 1.0.
__start.c seems to be same as usual, except that there is no OSInit() call (old
versions must call OSInit() in main, instead of __start).
here is the short description of start() routine (you can easily find full
version in your SDK ;) :
// 81300000
__start:
__init_registers() // set stack pointer and static bases (r2, r13)
__init_hardware() // paired-singles and cache init
__init_data() // clear bss ?
. // here goes Debug Monitor stuff
.
.
DBInit() // debug monitor init :)
__init_user() // cpp init
main() // that's actually, IPL (BS2) code
jmp exit() // halt CPU
here is the main() reversing :
------------------------------
// 813006D4
main()
{
BS2Init();
OSInit();
AD16Init();
AD16WriteReg(0x800);
DVDInit();
AD16WriteReg(0x900);
CARDInit();
AD16WriteReg(0xa00);
0x81302104(); // SRAM, real-time clock (check ?)
__VIInit(0);
VIInit();
AD16WriteReg(0xb00);
0x813004e4(); // setup perf. monitor
0x8130222c(); // update time-base by SRAM clock
0x813022c0(); // perform initial DVD actions and fall back into menu
0x8134092c(5);
0x8134052c();
AD16WriteReg(0xc00);
BS2Menu(); // here goes intro and main menu... (BIG one!)
OSPanic(__FILE__, __LINE__, "BS2 ERROR >>> SHOULD NEVER REACH HERE");
}
float NaN;
// 8130045C
void BS2Init()
{
// clear LoMem and OSMem
memset(0x80000000, 0, 256);
memset(0x80003000, 0, 256);
BATInit();
// set memory size to 24MB
*0x80000028 = 0x01800000;
// set console type to default retail 1
*0x8000002c = 1;
// upgrade retail
*0x8000002c += *0xcc00302c >> 28;
(u32)NaN = -1;
FPUInit();
}
// 813003A0
void BATInit()
{
__asm
{
isync
li r4, 0
mtspr DBAT2L, r4
mtspr DBAT2U, r4
mtspr DBAT3L, r4
mtspr DBAT3U, r4
mtspr IBAT1L, r4
mtspr IBAT1U, r4
mtspr IBAT2L, r4
mtspr IBAT2U, r4
mtspr IBAT3L, r4
mtspr IBAT3U, r4
isync
}
}
// 813003D8
void FPUInit()
{
// FPU already initialzied in __start(),
// so just invalidate all FPRs.
__asm
{
lfs f0, NaN
fmr f1, f0
fmr f2, f0
fmr f3, f0
. e
. t
. c
fmr f31, f0
}
}
// maybe later
0x81302104()
{
__OSLockSram();
__OSCheckSram();
__OSGetRTC();
OSTickToCalendarTime();
memset();
__OSUnlockSram();
__OSSyncSram();
}
// maybe later
0x813004e4()
{
OSDisableInterrupts();
OSGetTick();
OSGetTick();
OSGetTick();
__div2i();
__div2i();
PPCMtpmc1();
PPCMtmmcr0();
OSGetTick();
OSGetTick();
PPCMtmmcr0();
PPCMfpmc1();
__div2i();
__div2i();
__div2i();
OSRestoreInterrupts();
}
// maybe later
0x8130222c()
{
__OSLockSram();
__OSGetRTC();
__OSSetTime();
__OSUnlockSram();
}
static int BS2State = 0;
// just layer..
0x813022c0()
{
BS2State = BS2Mach();
}
// 81300A70
// located in __FILE__ = "BS2Mach.c"
int BS2Mach()
{
static int state = 0;
BOOL level = OSDisableInterrupts();
switch(state)
{
case 0:
[r13 - 0x7dc8] = 0x800030d4;
state = 1;
case 1:
__OSGetSystemTime();
... some checks
... lot of mulhwu, subfe and other strange instructions :)
... lazy to find corresponding macro in os.h
if(fail) break;
state = 2;
// Install DVD cover callback
case 2:
if([r13 - 0x7da8] == 0)
{
r3 = [r13 - 0x7dc8]
[r3] = 0
[r13 - 0x7dc4] = 0
[r13 - 0x7dac] = 1
DVDLowSetResetCoverCallback(0);
DVDReset();
[r13 - 0x7da8] = 1
(s64)[r13 - 0x7d9c] = __OSGetSystemTime();
break;
}
__OSGetSystemTime();
bla bla bla
another checks :)
if(fail) break;
DVDLowSetResetCoverCallback(0x813007d8);
DVDReset();
state = 3;
// Read Disk information (ID)
case 3:
DVDReadDiskID(0x8145e620 + 64, 0x80000000, 0x813007e4);
state = 4;
break;
.
.
.
.
.
.
.
// Leave immidiately ?
case 16:
break;
default:
OSPanic(__FILE__, __LINE__, "BS2 ERROR >> UNKNOWN STATE");
}
OSRestoreInterrupts(level);
return (DVDLowGetCoverStatus() == 1) ? 19 : step;
}
// 81301154
void BS2Menu()
{
BS2InitAlloc();
}
static OSHeapHandler BS2Heap;
// 81307EA8
void BS2InitAlloc()
{
u8 *arenaLo;
u8 *arenaHi;
u8 *arenaNew;
arenaLo = OSGetArenaLo();
arenaLo = (void *)OSRoundUp32B(arenaLo);
arenaHi = OSGetArenaHi();
arenaHi = (void *)OSRoundDown32B(arenaHi);
arenaNew = OSInitAlloc(0x80800000, arenaHi, 2);
OSSetArenaLo(arenaHi);
BS2Heap = OSCreateHeap(arenaLo, arenaHi);
OSSetCurrentHeap(BS2Heap);
OSAddToHeap(BS2Heap, arenaNew, 0x81100000);
BS2CheckAlloc();
}
// 81307F34
void BS2CheckAlloc()
{
OSCheckHeap(BS2Heap);
}
// 81307F58
void *OSAlloc(long size)
{
void *ptr;
if((ptr = OSAlloc(size)) == 0)
{
OSPanic(?);
}
return ptr;
}
here is the MAP of BS2 libraries code :
---------------------------------------
813014C8 DEMOInit (*)
81307F58 OSAlloc (*)
813327BC PPCMtmmcr0 ;; PPC
813327C4 PPCMfpmc1
813327CC PPCMtpmc1
81332814 OSInit ;; OS
81332EF0 OSInitAlarm
81332F3C OSCreateAlarm
81333688 OSAllocFromHeap
81333784 OSSetCurrentHeap
81333794 OSInitAlloc
81333804 OSCreateHeap
81333870 OSAddToHeap
813338D0 OSCheckHeap
813344C0 OSGetStackPointer
8133491C OSReport
8133499C OSPanic
81334AA4 PPCHalt
81334D4C EXIImm ;; OS EXI (not standalone)
81335134 EXISync
813353C8 EXIProbeReset
8133570C EXISelect
81335838 EXIDeselect
81335D6C EXILock
81335E60 EXIUnlock
81335F54 AD16Init
81336090 AD16WriteReg
813361B0 OSDisableInterrupts
813361C4 OSEnableInterrupts
813361D8 OSRestoreInterrupts
81336DD8 __OSGetRTC
813372B0 __OSLockSram
81337658 __OSUnlockSram
813376A0 __OSSyncSram
813376B0 __OSCheckSram
81338504 OSInitThreadQueue
8133939C OSGetTick
813393B8 __OSSetTime
8133943C __OSGetSystemTime
8133963C OSTicksToCalendarTime
8133AC50 DVDLowGetCoverStatus ;; DVD
8133AB18 DVDLowReset
8133ABD4 DVDLowSetResetCoverCallback
8133B5F0 DVDInit
8133CD18 DVDReadDiskID
8133D0EC DVDReset
8133DBE0 __VIInit ;; VI
8133DDC8 VIInit
8133E6C0 VIConfigure
8133F0B4 VIGetTvFormat
81343114 CARDInit ;; CARD
813480D4 GXInit ;; GX
81349148 GXInitFifoBase
81349230 GXSetCPUFifo
81349340 GXSetGPFifo
813494B8 __GXFifoInit
8134B0AC __GXPEInit
8135A178 __div2i ;; LIBC
8135A394 __mod2i
8135B494 vprintf
(*) that function was slighty modified particulary for BS2.
-------------------------------------------------------------------------------
org -- [email]kvzorganic@mail.ru[/email]
Editado: joe me equivoque y puse el apploader para el dolwin :S