void app_booter_main(void) { void *exeBuffer = (void *) EXECUTABLE_MEM_ADDR; u32 exeEntryPointAddress = 0; entrypoint exeEntryPoint; if (valid_elf_image(exeBuffer) == 1) exeEntryPointAddress = load_elf_image(exeBuffer); else exeEntryPointAddress = load_dol_image(exeBuffer); exeEntryPoint = (entrypoint) exeEntryPointAddress; if (!exeEntryPoint) return; if (SYSTEM_ARGV->argvMagic == ARGV_MAGIC) { void *new_argv = (void *) (exeEntryPointAddress + 8); memcpy(new_argv, SYSTEM_ARGV, sizeof(struct __argv)); sync_before_exec(new_argv, sizeof(struct __argv)); } exeEntryPoint (); }
void RAMInit(void) { u32 vmode = *(vu32*)0x800000CC; _memset( (void*)0x80000020, 0, 0xE0 ); //Keep ISO Header _memset( (void*)0x80003000, 0, 0x12FD000 ); sync_before_exec( (void*)0x80003000, 0x12FD000 ); _memset( (void*)0x81310000, 0, 0x4F0000 ); sync_before_exec( (void*)0x81340000, 0x4F0000 ); *(vu32*)0x80000020 = 0x0D15EA5E; *(vu32*)0x80000028 = 0x01800000; *(vu32*)0x8000002C = *(vu32*)0xCC00302C >> 28; // console type *(vu32*)0x800000CC = vmode; //Assuming it didnt change *(vu32*)0x800000F0 = 0x01800000; *(vu16*)0xCC00501A = 156; }
static void vecmemclr(u64 dest, u64 size) { u64 end = dest+size; if (size && dest < VECSIZE) { if (end <= VECSIZE) return; dest = VECSIZE; size = end - dest; } memset((void*)dest, 0, size); sync_before_exec((void*)dest, size); }
void kernel_launch(void) { devtree_prepare(); printf("Relocating vectors...\n"); memcpy((void*)0, vec_buf, VECSIZE); sync_before_exec((void*)0, VECSIZE); printf("Letting thread1 run loose...\n"); _thread1_vector = 0x60; /* this is __secondary_hold in Linux */ _thread1_release = 1; printf("Taking the plunge...\n"); debug_shutdown(); ((kernel_entry)entry)(__devtree, entry[0], NULL); lv1_panic(0); }
u32 Apploader_Run() { app_entry appldr_entry; app_init appldr_init; app_main appldr_main; app_final appldr_final; char *dst; u32 len, offset; sync_before_read(TGCInfo, sizeof(struct _TGCInfo)); /* Read apploader header */ DVDLowRead(&apploader_hdr, 0x20, TGCInfo->tgcoffset + APPLDR_OFFSET); /* Calculate apploader length */ u32 appldr_len = apploader_hdr.size + apploader_hdr.trailersize; /* Read apploader code */ DVDLowRead(appldr, appldr_len, TGCInfo->tgcoffset + APPLDR_CODE); /* Flush into memory */ sync_before_exec(appldr, appldr_len); /* Set basic information */ *(vu32*)0x800000F8 = 243000000; // Bus Clock Speed *(vu32*)0x800000FC = 729000000; // CPU Clock Speed /* Set apploader entry function */ appldr_entry = apploader_hdr.entry; /* Call apploader entry */ appldr_entry(&appldr_init, &appldr_main, &appldr_final); /* Initialize apploader */ appldr_init(noprintf); while(appldr_main(&dst, &len, &offset)) { /* Read data from DVD */ PrepareTGC( offset ); DVDLowRead( dst, len, offset + TGCInfo->tgcoffset ); ParseTGC( dst, len, offset ); } /* Set entry point from apploader */ return (u32)appldr_final(); }
static void vecmemcpy(u64 dest, const void *src, u64 size) { const u8 *p = src; u64 end = dest+size; if (size && dest < VECSIZE) { if (end <= VECSIZE) { memcpy(vec_buf+dest, p, size); return; } else { memcpy(vec_buf+dest, p, VECSIZE-dest); p += VECSIZE-dest; dest = VECSIZE; size = end - dest; } } memcpy((void*)dest, p, size); sync_before_exec((void*)dest, size); }
void *load_elf_image (void *addr) { u32 *header = addr; u32 *phdr = addr + header[7]; u32 n = header[11] >> 16; u32 i; for (i = 0; i < n; i++, phdr += 8) { if (phdr[0] != 1) continue; u32 off = phdr[1]; void *dest = (void *)phdr[3]; u32 filesz = phdr[4]; u32 memsz = phdr[5]; memcpy(dest, addr + off, filesz); memset(dest + filesz, 0, memsz - filesz); sync_before_exec(dest, memsz); } return (void *)header[6]; }