diff options
Diffstat (limited to 'rbutil/mks5lboot/mkdfu.c')
-rw-r--r-- | rbutil/mks5lboot/mkdfu.c | 318 |
1 files changed, 0 insertions, 318 deletions
diff --git a/rbutil/mks5lboot/mkdfu.c b/rbutil/mks5lboot/mkdfu.c deleted file mode 100644 index bb1929bffd..0000000000 --- a/rbutil/mks5lboot/mkdfu.c +++ /dev/null @@ -1,318 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2015 by Cástor Muñoz - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <stdbool.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> - -#include "mks5lboot.h" - -/* Header for ARM code binaries */ -#include "dualboot.h" - -/* Win32 compatibility */ -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -/* - * This code is based on emCORE, adds a couple of improvements thanks to - * some extra features in Apple's ROM: - * - Generic Im3Info header valid for all payloads. It is done by moving - * the certificate to a fixed position (before data), and using a 'magic' - * value (0x300) for signature offset. - * - Some integer overflows in ROM make it possible to use the free space - * available in Im3Hdr, resulting a maximum payload size of: - * 128 KiB - 0x50 bytes (IM3INFO_SZ) - 700 bytes (CERT_SIZE). - */ - -const struct ipod_models ipod_identity[] = -{ - [MODEL_IPOD6G] = { - "Classic 6G", "ipod6g", "ip6g", 71, - dualboot_install_ipod6g, sizeof(dualboot_install_ipod6g), - dualboot_uninstall_ipod6g, sizeof(dualboot_uninstall_ipod6g) }, -}; - -struct Im3Info s5l8702hdr = -{ - .ident = IM3_IDENT, - .version = IM3_VERSION, - .enc_type = 3, - .u.enc34 = { - .sign_off = "\x00\x03\x00\x00", - .cert_off = "\x50\xF8\xFF\xFF", /* -0x800 + CERT_OFFSET */ - .cert_sz = "\xBA\x02\x00\x00", /* CERT_SIZE */ - }, - .info_sign = "\xC2\x54\x51\x31\xDC\xC0\x84\xA4" - "\x7F\xD1\x45\x08\xE8\xFF\xE8\x1D", -}; - -unsigned char s5l8702pwnage[/*CERT_SIZE*/] = -{ - "\x30\x82\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86" - "\xF7\x0D\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55" - "\x04\x03\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13" - "\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01" - "\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09" - "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82" - "\x00\x7A\x30\x66\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D" - "\x01\x01\x05\x05\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03" - "\x13\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x30\x0B\x31\x09\x30\x07\x06\x03\x55\x04\x03\x13\x00\x30" - "\x19\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01\x05\x00" - "\x03\x08\x00\x30\x05\x02\x01\x00\x02\x00\x30\x0D\x06\x09\x2A\x86" - "\x48\x86\xF7\x0D\x01\x01\x05\x05\x00\x03\x01\x00\x30\x82\x01\xBA" - "\x30\x50\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01" - "\x05\x05\x00\x30\x00\x30\x1E\x17\x0D\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x17\x0D\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x30\x00\x30\x19\x30\x0D\x06\x09\x2A\x86\x48" - "\x86\xF7\x0D\x01\x01\x01\x05\x00\x03\x08\x00\x30\x05\x02\x01\x00" - "\x02\x00\x30\x0D\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05\x05" - "\x00\x03\x82\x01\x55" -}; - -static uint32_t get_uint32le(unsigned char* p) -{ - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); -} - -static uint32_t get_uint32be(unsigned char* p) -{ - return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; -} - -static void put_uint32le(unsigned char* p, uint32_t x) -{ - p[0] = x & 0xff; - p[1] = (x >> 8) & 0xff; - p[2] = (x >> 16) & 0xff; - p[3] = (x >> 24) & 0xff; -} - -#define _ERR(format, ...) \ - do { \ - snprintf(errstr, errstrsize, "[ERR] "format, __VA_ARGS__); \ - goto error; \ - } while(0) - -static unsigned char *load_file(char *filename, int *bufsize, - const struct ipod_models** model, - char* errstr, int errstrsize) -{ - int fd, i; - struct stat s; - unsigned char header[8]; - unsigned char *buf = NULL; - bool is_rbbl = (model); - - fd = open(filename, O_RDONLY|O_BINARY); - if (fd < 0) - _ERR("Could not open %s for reading", filename); - - if (fstat(fd, &s) < 0) - _ERR("Checking filesize of input file %s", filename); - *bufsize = s.st_size; - - if (is_rbbl) { - /* Read Rockbox header */ - if (read(fd, header, sizeof(header)) != sizeof(header)) - _ERR("Could not read file %s", filename); - *bufsize -= sizeof(header); - - for (i = 0; i < NUM_MODELS; i++) - if (memcmp(ipod_identity[i].rb_model_name, header + 4, 4) == 0) - break; - - if (i == NUM_MODELS) - _ERR("Model name \"%4.4s\" unknown. " - "Is this really a rockbox bootloader?", header + 4); - - *model = &ipod_identity[i]; - } - - buf = malloc(*bufsize); - if (buf == NULL) - _ERR("Could not allocate memory for %s", filename); - - if (read(fd, buf, *bufsize) != *bufsize) - _ERR("Could not read file %s", filename); - - if (is_rbbl) { - /* Check checksum */ - uint32_t sum = (*model)->rb_model_num; - for (i = 0; i < *bufsize; i++) { - /* add 8 unsigned bits but keep a 32 bit sum */ - sum += buf[i]; - } - if (sum != get_uint32be(header)) - _ERR("Checksum mismatch in %s", filename); - } - - close(fd); - return buf; - -error: - if (fd >= 0) - close(fd); - if (buf) - free(buf); - return NULL; -} - -unsigned char *mkdfu(int dfu_type, char *dfu_arg, int* dfu_size, - char* errstr, int errstrsize) -{ - const struct ipod_models *model = NULL; - unsigned char *dfu_buf = NULL; - unsigned char *f_buf; - int f_size; - uint32_t padded_bl_size; - uint32_t cert_off, cert_sz; - off_t cur_off; - char *dfu_desc; - int i; - - switch (dfu_type) - { - case DFU_INST: - case DFU_INST_SINGLE: - f_buf = load_file(dfu_arg, &f_size, &model, errstr, errstrsize); - if (f_buf == NULL) - goto error; - /* IM3 data size should be padded to 16 */ - padded_bl_size = ((f_size + 0xf) & ~0xf); - *dfu_size = BIN_OFFSET + (model->dualboot_install_size + - (IM3HDR_SZ - (int)IM3INFO_SZ) + (int)padded_bl_size); - dfu_desc = (dfu_type == DFU_INST_SINGLE) ? "BL installer (single)" - : "BL installer"; - break; - - case DFU_UNINST: - for (i = 0; i < NUM_MODELS; i++) { - if (!strcmp(ipod_identity[i].platform_name, dfu_arg)) { - model = &ipod_identity[i]; - break; - } - } - if (!model) - _ERR("Platform name \"%s\" unknown", dfu_arg); - - *dfu_size = BIN_OFFSET + model->dualboot_uninstall_size; - dfu_desc = "BL uninstaller"; - break; - - case DFU_RAW: - default: - f_buf = load_file(dfu_arg, &f_size, NULL, errstr, errstrsize); - if (f_buf == NULL) - goto error; - /* IM3 data size should be padded to 16 */ - *dfu_size = BIN_OFFSET + ((f_size + 0xf) & ~0xf); - dfu_desc = "raw binary"; - break; - } - - printf("[INFO] Building DFU:\n"); - printf("[INFO] type: %s\n", dfu_desc); - if ((dfu_type == DFU_INST) || (dfu_type == DFU_INST_SINGLE)) - printf("[INFO] BL size: %d\n", f_size); - if (dfu_type == DFU_RAW) - printf("[INFO] BIN size: %d\n", f_size); - printf("[INFO] DFU size: %d\n", *dfu_size); - if (model) { - printf("[INFO] model name: %s\n", model->model_name); - printf("[INFO] platform: %s\n", model->platform_name); - printf("[INFO] RB name: %s\n", model->rb_model_name); - printf("[INFO] RB num: %d\n", model->rb_model_num); - } - - if (*dfu_size > DFU_MAXSIZE) - _ERR("DFU image (%d bytes) too big", *dfu_size); - - dfu_buf = calloc(*dfu_size, 1); - if (!dfu_buf) - _ERR("Could not allocate %d bytes for DFU image", *dfu_size); - - cert_off = get_uint32le(s5l8702hdr.u.enc34.cert_off); - cert_sz = get_uint32le(s5l8702hdr.u.enc34.cert_sz); - - memcpy(dfu_buf, &s5l8702hdr, sizeof(s5l8702hdr)); - - cur_off = IM3HDR_SZ + cert_off; - - memcpy(dfu_buf + cur_off, s5l8702pwnage, sizeof(s5l8702pwnage)); - - /* set entry point */ - cur_off += cert_sz - 4; - put_uint32le(dfu_buf + cur_off, DFU_LOADADDR + BIN_OFFSET); - - cur_off = BIN_OFFSET; - - switch (dfu_type) - { - case DFU_INST: - case DFU_INST_SINGLE: - /* copy the dualboot installer binary */ - memcpy(dfu_buf + cur_off, model->dualboot_install, - model->dualboot_install_size); - /* point to the start of the included IM3 header info */ - cur_off += model->dualboot_install_size - IM3INFO_SZ; - /* set bootloader data size */ - struct Im3Info *bl_info = (struct Im3Info*)(dfu_buf + cur_off); - put_uint32le(bl_info->data_sz, padded_bl_size); - /* use info_sign to pass params to the dualboot installer */ - if (dfu_type == DFU_INST_SINGLE) - bl_info->info_sign[0] = 0x1; - /* add bootloader binary */ - cur_off += IM3HDR_SZ; - memcpy(dfu_buf + cur_off, f_buf, f_size); - break; - - case DFU_UNINST: - /* copy the dualboot uninstaller binary */ - memcpy(dfu_buf + cur_off, model->dualboot_uninstall, - model->dualboot_uninstall_size); - break; - - case DFU_RAW: - default: - /* add raw binary */ - memcpy(dfu_buf + cur_off, f_buf, f_size); - break; - } - - return dfu_buf; - -error: - if (dfu_buf) - free(dfu_buf); - return NULL; -} |