From f1256c2b77e7a762082545cf992e5494fa1eca10 Mon Sep 17 00:00:00 2001 From: Sven Peter Date: Tue, 24 Feb 2009 16:20:28 +0100 Subject: [PATCH] boot2 loading and titleid patching for miniios seems to fail sometimes in dc_ functions :/ --- Makefile | 2 +- boot2.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ boot2.h | 7 ++++ crypto.c | 2 - main.c | 8 ++++ nand.c | 3 ++ nand.h | 1 + 7 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 boot2.c create mode 100644 boot2.h diff --git a/Makefile b/Makefile index 9a10393..10e94e8 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ TARGET = iosboot.bin ELF = iosboot.elf OBJECTS = start.o main.o ipc.o vsprintf.o string.o gecko.o memory.o memory_asm.o \ utils_asm.o utils.o ff.o diskio.o sdhc.o powerpc_elf.o powerpc.o panic.o irq.o irq_asm.o \ - exception.o exception_asm.o seeprom.o crypto.o nand.o + exception.o exception_asm.o seeprom.o crypto.o nand.o boot2.o $(TARGET) : $(ELF) $(ELFLOADER) @echo "MAKEBIN $@" diff --git a/boot2.c b/boot2.c new file mode 100644 index 0000000..6703af3 --- /dev/null +++ b/boot2.c @@ -0,0 +1,122 @@ +#include "types.h" +#include "nand.h" +#include "memory.h" +#include "crypto.h" +#include "string.h" +#include "gecko.h" +#include "powerpc.h" + +static u8 boot2[256 << 11] MEM2_BSS __attribute__((aligned(64))); +static u8 key[32] MEM2_BSS __attribute__((aligned(64))); +static u8 ecc[64] __attribute__((aligned(64))); +static u8 boot2_initialized = 0; +extern void *vector; + +struct wadheader { + u32 len; + u32 type; + u32 certs_len; + u32 tik_len; + u32 tmd_len; + u32 reserved; // ?? + u32 data_len; // ?? + u32 footer_len; // ?? +}; +typedef struct { + u32 hdrsize; + u32 loadersize; + u32 elfsize; + u32 argument; +} ioshdr; + +void boot2_init() { + int i; + void *ptr = boot2; + u8 *tikptr = NULL; + u8 *tmdptr = NULL; + u8 *cntptr = NULL; + u8 iv[16]; + struct wadheader *hdr = (struct wadheader *)boot2; + u32 datalen; + + for (i = 0x40; i < 0x140; i++, ptr += 2048) { + nand_read_page(i, ptr, ecc); + nand_wait(); + } + + if (hdr->len != sizeof(struct wadheader)) + return; + + tikptr = boot2 + hdr->len + hdr->certs_len; + tmdptr = tikptr + hdr->tik_len; + cntptr = ALIGN_FORWARD(tmdptr + hdr->tmd_len, 0x40); + + memset(iv, 0, 16); + memcpy(iv, tikptr + 0x1dc, 8); + + aes_reset(); + aes_set_iv(iv); + aes_set_key(otp.common_key); + memcpy(key, tikptr+0x1bf, 16); + gecko_puts("flushing now...\n"); + dc_flushrange(key, 32); + gecko_puts("dc_flush done.\n"); + aes_decrypt(key, key, 1, 0); + dc_invalidaterange(key, 32); + + memcpy(&datalen, tmdptr+0x1e4+8+4, 4); + memset(iv, 0, 16); + memcpy(iv, tmdptr + 0x1e4 + 4, 2); + + aes_reset(); + aes_set_iv(iv); + aes_set_key(key); + dc_flushrange(cntptr, ALIGN_FORWARD(datalen, 16)); + aes_decrypt(cntptr, cntptr, ALIGN_FORWARD(datalen, 16)/16, 0); + dc_invalidaterange(cntptr, ALIGN_FORWARD(datalen, 16)); + + memcpy(boot2, cntptr, datalen); + boot2_initialized = 1; +} + +static u32 match[] = { + 0xF7FFFFB8, + 0xBC024708, + 1, + 2, +}; + +static u32 patch[] = { + 0xF7FFFFB8, + 0xBC024708, + 0x10001, + 0x48415858, +}; + +int boot2_run(u32 tid_hi, u32 tid_lo) { + void *ptr; + int i; + ioshdr *hdr = (ioshdr *)boot2; + + if (boot2_initialized != 1) + return 0; + + patch[2] = tid_hi; + patch[3] = tid_lo; + + powerpc_hang(); + memcpy((void *)0x11000000, boot2, sizeof boot2); + ptr = (void *)0x11000000 + hdr->hdrsize + hdr->loadersize; + for (i = 0; i < sizeof(boot2); i += 1) { + if (memcmp(ptr+i, match, sizeof(match)) == 0) { + memcpy(ptr+i, patch, sizeof(patch)); + gecko_printf("patched data @%08x\n", ptr+i); + } + } + + hdr = (ioshdr *)0x11000000; + hdr->argument = 0x42; + vector = (void *)0x11000000 + hdr->hdrsize; + gecko_printf("boot2 is at %p\n", vector); + return 1; +} diff --git a/boot2.h b/boot2.h new file mode 100644 index 0000000..8328df6 --- /dev/null +++ b/boot2.h @@ -0,0 +1,7 @@ +#ifndef __BOOT2_H__ +#define __BOOT2_H__ + +int boot2_run(u32 tid_hi, u32 tid_lo); +void boot2_init(); + +#endif diff --git a/crypto.c b/crypto.c index 1aca8f6..e120f95 100644 --- a/crypto.c +++ b/crypto.c @@ -113,8 +113,6 @@ void aes_decrypt(u8 *src, u8 *dst, u32 blocks, u8 keep_iv) if (this_blocks > 0x80) this_blocks = 0x80; - dc_flushrange(src, this_blocks<<4); - dc_invalidaterange(dst, this_blocks<<4); write32(AES_SRC, (u32)src); write32(AES_DEST, (u32)dst); aes_command(AES_CMD_DECRYPT, keep_iv, this_blocks); diff --git a/main.c b/main.c index f1f56f6..35224e8 100644 --- a/main.c +++ b/main.c @@ -15,6 +15,7 @@ #include "exception.h" #include "crypto.h" #include "nand.h" +#include "boot2.h" void *vector; @@ -171,6 +172,12 @@ void *_main(void *base) nand_initialize(); gecko_puts("NAND initialized.\n"); + boot2_init(); + gecko_puts("Boot2 loaded to memory.\n"); + +// gecko_printf("boot2_run = %d\n", boot2_run(0x10001, 0x48415858)); +// goto end; + gecko_puts("Initializing IPC...\n"); ipc_initialize(); @@ -204,6 +211,7 @@ void *_main(void *base) mem_shutdown(); //vector = patch_boot2(base, (((u64)tidh)<<32) | tidl); +end: gecko_printf("Vectoring to %p...\n",vector); return vector; diff --git a/nand.c b/nand.c index da63a00..8eb8356 100644 --- a/nand.c +++ b/nand.c @@ -141,6 +141,9 @@ void nand_read_page(u32 pageno, void *data, void *ecc) { nand_send_command(NAND_READ_POST, 0, NAND_FLAGS_IRQ | 0xb000, 0x840); } +void nand_wait() { + __nand_wait(); +} #ifdef NAND_SUPPORT_WRITE void nand_write_page(u32 pageno, void *data, void *ecc) { diff --git a/nand.h b/nand.h index c8250e6..e0f073d 100644 --- a/nand.h +++ b/nand.h @@ -13,6 +13,7 @@ void nand_get_status(u8 *); void nand_read_page(u32 pageno, void *data, void *ecc); void nand_write_page(u32 pageno, void *data, void *ecc); void nand_erase_block(u32 pageno); +void nand_wait(void); void nand_read_cluster(u32 clusterno, void *data);