diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2009-10-27 21:15:21 +0000 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2009-10-27 21:15:21 +0000 |
commit | b82963bd9dd99c705625aceadb7118a428fc4ed2 (patch) | |
tree | 5cc54c84c908933bb79614c502a3a61f863a2650 /utils | |
parent | 806bc7947b0b03f3b2d11b38d17066d5e1e890d3 (diff) |
Move mknkboot.[ch] to beastpatcher folder.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23372 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils')
-rw-r--r-- | utils/MTP/beastpatcher/Makefile | 14 | ||||
-rw-r--r-- | utils/MTP/beastpatcher/mknkboot.c | 320 | ||||
-rw-r--r-- | utils/MTP/beastpatcher/mknkboot.h | 49 |
3 files changed, 377 insertions, 6 deletions
diff --git a/utils/MTP/beastpatcher/Makefile b/utils/MTP/beastpatcher/Makefile index 571274034b..bb908532c2 100644 --- a/utils/MTP/beastpatcher/Makefile +++ b/utils/MTP/beastpatcher/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-Wall -W -DWITH_BOOTOBJS -DBEASTPATCHER -I../../../tools +CFLAGS=-Wall -W -DWITH_BOOTOBJS -I../../../tools ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) OUTPUT=beastpatcher.exe @@ -30,17 +30,17 @@ CC = $(CROSS)gcc all: $(OUTPUT) -SOURCES = beastpatcher.c bootimg.c ../../../tools/mknkboot.c main.c -HEADERS = beastpatcher.h mtp_common.h bootimg.h ../../../tools/mknkboot.h +SOURCES = beastpatcher.c bootimg.c mknkboot.c main.c +HEADERS = beastpatcher.h mtp_common.h bootimg.h mknkboot.h MTPSRCS_W32 = mtp_win32.c MTPSRCS_MTP = mtp_libmtp.c beastpatcher: $(SOURCES) $(HEADERS) $(MTPSRCS_MTP) - gcc $(CFLAGS) -o beastpatcher $(SOURCES) $(MTPSRCS_MTP) $(LIBS) + gcc $(CFLAGS) -DBEASTPATCHER -o beastpatcher $(SOURCES) $(MTPSRCS_MTP) $(LIBS) strip beastpatcher beastpatcher.exe: $(SOURCES) $(HEADERS) $(MTPSRCS_W32) $(WINLIBS) - $(CC) $(CFLAGS) -o beastpatcher.exe $(SOURCES) $(MTPSRCS_W32) $(WINLIBS) + $(CC) $(CFLAGS) -DBEASTPATCHER -o beastpatcher.exe $(SOURCES) $(MTPSRCS_W32) $(WINLIBS) $(CROSS)strip beastpatcher.exe beastpatcher-mac: beastpatcher-i386 beastpatcher-ppc @@ -60,5 +60,7 @@ bin2c: ../../../rbutil/tools/bin2c.c bootimg.c: bootloader.bin bin2c ./bin2c bootloader.bin bootimg +mknkboot: mknkboot.c + $(SILENT)$(NATIVECC) $(CFLAGS) $+ -o $@ clean: - rm -f beastpatcher.exe beastpatcher-mac beastpatcher-i386 beastpatcher-ppc beastpatcher bin2c bootimg.c bootimg.h *~ + rm -f beastpatcher.exe beastpatcher-mac beastpatcher-i386 beastpatcher-ppc beastpatcher bin2c bootimg.c bootimg.h mknkboot *~ diff --git a/utils/MTP/beastpatcher/mknkboot.c b/utils/MTP/beastpatcher/mknkboot.c new file mode 100644 index 0000000000..6ac26428bc --- /dev/null +++ b/utils/MTP/beastpatcher/mknkboot.c @@ -0,0 +1,320 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 by Dave Chapman + * + * Based on merge0.cpp by James Espinoza, but completely rewritten. + * + * 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. + * + ****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#if defined(_MSC_VER) +#include "pstdint.h" +#else +#include <unistd.h> +#include <inttypes.h> +#endif + +#include "mknkboot.h" + +/* New entry point for nk.bin - where our dualboot code is inserted */ +#define NK_ENTRY_POINT 0x88200000 + +/* Entry point (and load address) for the main Rockbox bootloader */ +#define BL_ENTRY_POINT 0x8a000000 + +/* + +Description of nk.bin from + +http://www.xs4all.nl/~itsme/projects/xda/wince-flashfile-formats.html + +these files contain most information, several non-contigouos blocks +may be present and an entrypoint in the code. + + 1. a 7 character signature "B000FF\n" ( that is with 3 zeroes, and + ending in a linefeed ) + 2. DWORD for image start + 3. DWORD for image length + 4. followd by several records of this format: + 1. DWORD with address where this block is to be flashed to + 2. DWORD with the length of this block + 3. DWORD with the 32 bit checksum of this block, in perl: + unpack("%32C*", $data); + 4. followed by <length> bytes of data + 5. the last record has address ZERO, in the length the entrypoint + into the rom, and ZERO as checksum. + + +NOTE: The Gigabeat-S nk.bin contains 171 records, plus the EOF record. + +mknkboot.c appends two images: + +1) A "Disable" image which overwrites a word in the EBoot image +2) Our bootloader image, which has the same load address as nk.exe + +*/ + +/* win32 compatibility */ + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#define DISABLE_ADDR 0x88065A10 /* in EBoot */ +#define DISABLE_INSN 0xe3a00001 +#define DISABLE_SUM (0xe3+0xa0+0x00+0x01) + +/* Code to dual-boot - this is inserted at NK_ENTRY_POINT */ +static uint32_t dualboot[] = +{ + 0xe59f900c, /* ldr r9, [pc, #12] -> 0x53fa4000 */ + 0xe5999000, /* ldr r9, [r9] */ + 0xe3190010, /* tst r9, #16 ; 0x10 */ +#if 0 + /* Branch to Rockbox if hold is on */ + 0x159ff004, /* ldrne pc, [pc, #4] -> 0x89000000 */ +#else + /* Branch to Rockbox if hold is off */ + 0x059ff004, /* ldreq pc, [pc, #4] -> 0x89000000 */ +#endif + /* Branch to original firmware */ + 0xea0003fa, /* b 0x1000 */ + + 0x53fa4000, /* GPIO3_DR */ + BL_ENTRY_POINT /* RB bootloader load address/entry point */ +}; + + +static void put_uint32le(uint32_t x, unsigned char* p) +{ + p[0] = (unsigned char)(x & 0xff); + p[1] = (unsigned char)((x >> 8) & 0xff); + p[2] = (unsigned char)((x >> 16) & 0xff); + p[3] = (unsigned char)((x >> 24) & 0xff); +} + +#if !defined(BEASTPATCHER) +static off_t filesize(int fd) { + struct stat buf; + + if (fstat(fd,&buf) < 0) { + perror("[ERR] Checking filesize of input file"); + return -1; + } else { + return(buf.st_size); + } +} +#endif + + +int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata, + struct filebuf *outdata) +{ + int i; + unsigned char* boot; + unsigned char* boot2; + unsigned char* disable; + uint32_t sum; + + /* 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); + + if (outdata->buf==NULL) + { + printf("[ERR] Could not allocate memory, aborting\n"); + return -1; + } + + /****** STEP 1 - Read original nk.bin into buffer */ + memcpy(outdata->buf, indata->buf, indata->len); + + /****** STEP 2 - Move EOF record to the new EOF */ + 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, outdata->buf + outdata->len - 8); + + /****** STEP 3 - Create a record to disable the firmware signature + check in EBoot */ + 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 - Append the bootloader binary */ + boot = disable + 16; + memcpy(boot + 12, bootdata->buf, bootdata->len); + + /****** STEP 5 - Create header for bootloader record */ + + /* Calculate checksum */ + sum = 0; + for (i = 0; i < bootdata->len; i++) { + sum += boot[12 + i]; + } + + put_uint32le(BL_ENTRY_POINT, boot); /* Our entry point */ + put_uint32le(bootdata->len, boot + 4); + put_uint32le(sum, boot + 8); + + /****** STEP 6 - Insert our dual-boot code */ + boot2 = boot + bootdata->len + 12; + + /* Copy dual-boot code in an endian-safe way */ + for (i = 0; i < (signed int)sizeof(dualboot) / 4; i++) { + put_uint32le(dualboot[i], boot2 + 12 + i*4); + } + + /* Calculate checksum */ + sum = 0; + for (i = 0; i < (signed int)sizeof(dualboot); i++) { + sum += boot2[i+12]; + } + + put_uint32le(NK_ENTRY_POINT, boot2); /* New entry point for our nk.bin */ + put_uint32le(sizeof(dualboot), boot2 + 4); + put_uint32le(sum, boot2 + 8); + + 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 = 7; + goto quit; + } + + n = write(fdout, outdata.buf, outdata.len); + if (n != outdata.len) + { + printf("[ERR] Could not write output file %s\n",outfile); + result = 8; + goto quit; + } + +quit: + free(bootdata.buf); + free(indata.buf); + free(outdata.buf); + close(fdin); + close(fdboot); + close(fdout); + + return result; + +} +#endif + diff --git a/utils/MTP/beastpatcher/mknkboot.h b/utils/MTP/beastpatcher/mknkboot.h new file mode 100644 index 0000000000..0373421a17 --- /dev/null +++ b/utils/MTP/beastpatcher/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 + |