From dad3f299936c08e8689a5db242a687fc2638002d Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Sat, 19 Sep 2009 21:29:08 +0000 Subject: Split out file access from mknkboot handling. - make main dualboot creation function work on buffers instead of files. This is to be used in beastpatcher and simplifies error handling a bit. - prepare for building with beastpatcher. - export dualboot creation function. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22740 a1c6a512-1295-4272-9138-f99709370657 --- tools/mknkboot.c | 186 ++++++++++++++++++++++++++++++------------------------- tools/mknkboot.h | 49 +++++++++++++++ 2 files changed, 151 insertions(+), 84 deletions(-) create mode 100644 tools/mknkboot.h (limited to 'tools') diff --git a/tools/mknkboot.c b/tools/mknkboot.c index 87372500e5..f17d1e9070 100644 --- a/tools/mknkboot.c +++ b/tools/mknkboot.c @@ -45,6 +45,8 @@ #include #include +#include "mknkboot.h" + /* New entry point for nk.bin - where our dualboot code is inserted */ #define NK_ENTRY_POINT 0x88200000 @@ -113,6 +115,7 @@ static uint32_t dualboot[] = BL_ENTRY_POINT /* RB bootloader load address/entry point */ }; + static void put_uint32le(uint32_t x, unsigned char* p) { p[0] = x & 0xff; @@ -121,13 +124,6 @@ static void put_uint32le(uint32_t x, unsigned char* p) p[3] = (x >> 24) & 0xff; } -static void usage(void) -{ - printf("Usage: mknkboot \n"); - - exit(1); -} - static off_t filesize(int fd) { struct stat buf; @@ -140,100 +136,62 @@ static off_t filesize(int fd) { } -int mknkboot(const char* infile, const char* bootfile, const char* outfile) +int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata, + struct filebuf *outdata) { - int fdin, fdboot = -1, fdout = -1; - int i,n; - int inlength,bootlength,newlength; - unsigned char* buf = NULL; + int i; unsigned char* boot; unsigned char* boot2; unsigned char* disable; uint32_t sum; - int result = 0; - - fdin = open(infile, O_RDONLY|O_BINARY); - if (fdin < 0) - { - perror(infile); - result = 1; - goto quit; - } - - fdboot = open(bootfile, O_RDONLY|O_BINARY); - if (fdboot < 0) - { - perror(bootfile); - close(fdin); - result = 2; - goto quit; - } - - inlength = filesize(fdin); - bootlength = filesize(fdboot); /* Create buffer for original nk.bin, plus our bootloader (with 12 byte header), plus the 16-byte "disable record", plus our dual-boot code */ + outdata->len = indata->len + (bootdata->len + 12) + 16 + (12 + 28); + outdata->buf = malloc(outdata->len); - newlength = inlength + (bootlength + 12) + 16 + (12 + 28); - buf = malloc(newlength); - - if (buf==NULL) + if (outdata->buf==NULL) { printf("[ERR] Could not allocate memory, aborting\n"); - result = 3; - goto quit; + return -1; } /****** STEP 1 - Read original nk.bin into buffer */ - - n = read(fdin, buf, inlength); - if (n != inlength) - { - printf("[ERR] Could not read from %s\n",infile); - result = 4; - goto quit; - } + memcpy(outdata->buf, indata->buf, indata->len); /****** STEP 2 - Move EOF record to the new EOF */ - memcpy(buf + newlength - 12, buf + inlength - 12, 12); + memcpy(outdata->buf + outdata->len - 12, outdata->buf + indata->len - 12, 12); /* Overwrite default entry point with NK_ENTRY_POINT */ - put_uint32le(NK_ENTRY_POINT, buf + newlength - 8); + put_uint32le(NK_ENTRY_POINT, outdata->buf + outdata->len - 8); /****** STEP 3 - Create a record to disable the firmware signature check in EBoot */ - disable = buf + inlength - 12; + disable = outdata->buf + indata->len - 12; put_uint32le(DISABLE_ADDR, disable); put_uint32le(4, disable + 4); put_uint32le(DISABLE_SUM, disable + 8); put_uint32le(DISABLE_INSN, disable + 12); - /****** STEP 4 - Read the bootloader binary */ + /****** STEP 4 - Append the bootloader binary */ boot = disable + 16; - n = read(fdboot, boot + 12, bootlength); - if (n != bootlength) - { - printf("[ERR] Could not read from %s\n",bootfile); - result = 5; - goto quit; - } + memcpy(boot + 12, bootdata->buf, bootdata->len); /****** STEP 5 - Create header for bootloader record */ /* Calculate checksum */ sum = 0; - for (i = 0; i < bootlength; i++) { + for (i = 0; i < bootdata->len; i++) { sum += boot[12 + i]; } put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */ - put_uint32le(bootlength, boot + 4); + put_uint32le(bootdata->len, boot + 4); put_uint32le(sum, boot + 8); /****** STEP 6 - Insert our dual-boot code */ - boot2 = boot + bootlength + 12; + boot2 = boot + bootdata->len + 12; /* Copy dual-boot code in an endian-safe way */ for (i = 0; i < (signed int)sizeof(dualboot) / 4; i++) { @@ -250,47 +208,107 @@ int mknkboot(const char* infile, const char* bootfile, const char* outfile) put_uint32le(sizeof(dualboot), boot2 + 4); put_uint32le(sum, boot2 + 8); - /****** STEP 7 - Now write the output file */ + return 0; +} + +#if !defined(BEASTPATCHER) +static void usage(void) +{ + printf("Usage: mknkboot \n"); + + exit(1); +} + + +int main(int argc, char* argv[]) +{ + char *infile, *bootfile, *outfile; + int fdin = -1, fdboot = -1, fdout = -1; + int n; + struct filebuf indata = {0, NULL}, bootdata = {0, NULL}, outdata = {0, NULL}; + int result = 0; + + if(argc < 4) { + usage(); + } + + infile = argv[1]; + bootfile = argv[2]; + outfile = argv[3]; + + fdin = open(infile, O_RDONLY|O_BINARY); + if (fdin < 0) + { + perror(infile); + result = 2; + goto quit; + } + + fdboot = open(bootfile, O_RDONLY|O_BINARY); + if (fdboot < 0) + { + perror(bootfile); + close(fdin); + result = 3; + goto quit; + } + + indata.len = filesize(fdin); + bootdata.len = filesize(fdboot); + indata.buf = (unsigned char*)malloc(indata.len); + bootdata.buf = (unsigned char*)malloc(bootdata.len); + if(indata.buf == NULL || bootdata.buf == NULL) + { + printf("[ERR] Could not allocate memory, aborting\n"); + result = 4; + goto quit; + } + n = read(fdin, indata.buf, indata.len); + if (n != indata.len) + { + printf("[ERR] Could not read from %s\n",infile); + result = 5; + goto quit; + } + n = read(fdboot, bootdata.buf, bootdata.len); + if (n != bootdata.len) + { + printf("[ERR] Could not read from %s\n",bootfile); + result = 6; + goto quit; + } + result = mknkboot(&indata, &bootdata, &outdata); + if(result != 0) + { + goto quit; + } fdout = open(outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); if (fdout < 0) { perror(outfile); - result = 6; + result = 7; goto quit; } - n = write(fdout, buf, newlength); - if (n != newlength) + n = write(fdout, outdata.buf, outdata.len); + if (n != outdata.len) { printf("[ERR] Could not write output file %s\n",outfile); - result = 7; + result = 8; goto quit; } quit: - if(buf != NULL) - free(buf); + free(bootdata.buf); + free(indata.buf); + free(outdata.buf); close(fdin); close(fdboot); close(fdout); - - return result; -} - -int main(int argc, char* argv[]) -{ - char *infile, *bootfile, *outfile; - if(argc < 4) { - usage(); - } - - infile = argv[1]; - bootfile = argv[2]; - outfile = argv[3]; - - return mknkboot(infile, bootfile, outfile); + return result; } +#endif diff --git a/tools/mknkboot.h b/tools/mknkboot.h new file mode 100644 index 0000000000..0373421a17 --- /dev/null +++ b/tools/mknkboot.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Dave Chapman + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef MKNKBOOT_H +#define MKNKBOOT_H + +struct filebuf { + off_t len; + unsigned char* buf; +}; + +int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata, + struct filebuf *outdata); +#endif + -- cgit v1.2.3