summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDominik Riebeling <Dominik.Riebeling@gmail.com>2009-09-19 21:29:08 +0000
committerDominik Riebeling <Dominik.Riebeling@gmail.com>2009-09-19 21:29:08 +0000
commitdad3f299936c08e8689a5db242a687fc2638002d (patch)
tree09a596137673bc1710f2a9134c05a3f921403866 /tools
parentd0b048e82d4dbb41302201f7b4b9c96d499312d9 (diff)
downloadrockbox-dad3f299936c08e8689a5db242a687fc2638002d.tar.gz
rockbox-dad3f299936c08e8689a5db242a687fc2638002d.tar.bz2
rockbox-dad3f299936c08e8689a5db242a687fc2638002d.zip
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
Diffstat (limited to 'tools')
-rw-r--r--tools/mknkboot.c186
-rw-r--r--tools/mknkboot.h49
2 files changed, 151 insertions, 84 deletions
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 <unistd.h>
#include <inttypes.h>
+#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 <firmware file> <boot file> <output file>\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 <firmware file> <boot file> <output file>\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
+