From 6d1d9bed3ea567c74d787c0450c6de193e232851 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Sun, 20 Sep 2009 08:28:18 +0000 Subject: [PATCH] Integrate mknkboot into beastpatcher. Add a new option to beastpatcher to patch and upload an original firmware file. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22745 a1c6a512-1295-4272-9138-f99709370657 --- tools/mknkboot.c | 2 + utils/MTP/beastpatcher/Makefile | 15 +++-- utils/MTP/beastpatcher/beastpatcher.c | 94 ++++++++++++++++++--------- utils/MTP/beastpatcher/beastpatcher.h | 2 +- utils/MTP/beastpatcher/main.c | 33 ++++++++-- 5 files changed, 102 insertions(+), 44 deletions(-) diff --git a/tools/mknkboot.c b/tools/mknkboot.c index f17d1e9070..e63840427e 100644 --- a/tools/mknkboot.c +++ b/tools/mknkboot.c @@ -124,6 +124,7 @@ static void put_uint32le(uint32_t x, unsigned char* p) p[3] = (x >> 24) & 0xff; } +#if !defined(BEASTPATCHER) static off_t filesize(int fd) { struct stat buf; @@ -134,6 +135,7 @@ static off_t filesize(int fd) { return(buf.st_size); } } +#endif int mknkboot(const struct filebuf *indata, const struct filebuf *bootdata, diff --git a/utils/MTP/beastpatcher/Makefile b/utils/MTP/beastpatcher/Makefile index 52887f06b2..571274034b 100644 --- a/utils/MTP/beastpatcher/Makefile +++ b/utils/MTP/beastpatcher/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-Wall -W -DWITH_BOOTOBJS +CFLAGS=-Wall -W -DWITH_BOOTOBJS -DBEASTPATCHER -I../../../tools ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) OUTPUT=beastpatcher.exe @@ -30,12 +30,17 @@ CC = $(CROSS)gcc all: $(OUTPUT) -beastpatcher: beastpatcher.c bootimg.c mtp_common.h mtp_libmtp.c main.c - gcc $(CFLAGS) -o beastpatcher beastpatcher.c bootimg.c mtp_libmtp.c main.c $(LIBS) +SOURCES = beastpatcher.c bootimg.c ../../../tools/mknkboot.c main.c +HEADERS = beastpatcher.h mtp_common.h bootimg.h ../../../tools/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) strip beastpatcher -beastpatcher.exe: beastpatcher.c bootimg.c mtp_common.h mtp_win32.c main.c $(WINLIBS) - $(CC) $(CFLAGS) -o beastpatcher.exe beastpatcher.c bootimg.c mtp_win32.c main.c $(WINLIBS) +beastpatcher.exe: $(SOURCES) $(HEADERS) $(MTPSRCS_W32) $(WINLIBS) + $(CC) $(CFLAGS) -o beastpatcher.exe $(SOURCES) $(MTPSRCS_W32) $(WINLIBS) $(CROSS)strip beastpatcher.exe beastpatcher-mac: beastpatcher-i386 beastpatcher-ppc diff --git a/utils/MTP/beastpatcher/beastpatcher.c b/utils/MTP/beastpatcher/beastpatcher.c index bd49e87f6d..9d216d37bf 100644 --- a/utils/MTP/beastpatcher/beastpatcher.c +++ b/utils/MTP/beastpatcher/beastpatcher.c @@ -54,6 +54,7 @@ #include "mtp_common.h" #include "bootimg.h" +#include "mknkboot.h" /* Code to create a single-boot bootloader. Based on tools/gigabeats.c by Will Robertson. @@ -79,7 +80,7 @@ static uint32_t calc_csum(const unsigned char* pb, int cb) } static void create_single_boot(unsigned char* boot, int bootlen, - unsigned char** fwbuf, int* fwsize) + unsigned char** fwbuf, off_t* fwsize) { unsigned char* buf; @@ -127,37 +128,53 @@ static void create_single_boot(unsigned char* boot, int bootlen, return; } -int beastpatcher(const char* bootfile) +static int readfile(const char* filename, struct filebuf *buf) +{ + int res; + FILE* fp; + size_t bread; +#ifdef _LARGEFILE64_SOURCE + struct stat64 sb; + res = stat64(filename, &sb); +#else + struct stat sb; + res = stat(filename, &sb); +#endif + if(res == -1) { + fprintf(stderr, "[ERR] Getting firmware file size failed!\n"); + return 1; + } + buf->len = sb.st_size; + buf->buf = (unsigned char*)malloc(buf->len); + /* load firmware binary to memory. */ + fp = fopen(filename, "rb"); + bread = fread(buf->buf, sizeof(unsigned char), buf->len, fp); + if((off_t)(bread * sizeof(unsigned char)) != buf->len) { + fprintf(stderr, "[ERR] Error reading file %s!\n", filename); + return 1; + } + fclose(fp); + return 0; +} + + +int beastpatcher(const char* bootfile, const char* firmfile) { char yesno[4]; - unsigned char* fwbuf; - int fwsize; struct mtp_info_t mtp_info; - unsigned char* bootloader = bootimg; - unsigned int len_bootloader = LEN_bootimg; + struct filebuf bootloader; + struct filebuf firmware; + struct filebuf fw; + bootloader.buf = bootimg; + bootloader.len = LEN_bootimg; if (bootfile) { - int res; - FILE* fp; - size_t bread; -#ifdef _LARGEFILE64_SOURCE - struct stat64 sb; - res = stat64(bootfile, &sb); -#else - struct stat sb; - res = stat(bootfile, &sb); -#endif - if(res == -1) { - fprintf(stderr, "[ERR] Getting bootloader file size failed!\n"); + if(readfile(bootfile, &bootloader) != 0) { return 1; } - len_bootloader = sb.st_size; - bootloader = (unsigned char*)malloc(len_bootloader); - /* load bootloader binary to memory. */ - fp = fopen(bootfile, "rb"); - bread = fread(bootloader, sizeof(unsigned char), len_bootloader, fp); - if(bread * sizeof(unsigned char) != len_bootloader) { - fprintf(stderr, "[ERR] Error reading firmware file!\n"); + } + if (firmfile) { + if(readfile(firmfile, &firmware) != 0) { return 1; } } @@ -178,20 +195,30 @@ int beastpatcher(const char* bootfile) mtp_info.modelname); printf("[INFO] Device version: \"%s\"\n",mtp_info.version); - - printf("\nEnter i to install the Rockbox bootloader or c to cancel and do nothing (i/c): "); + if(firmfile) { + printf("\nEnter i to install the Rockbox dualboot bootloader or c to cancel and do nothing (i/c): "); + } + else { + printf("\nEnter i to install the Rockbox bootloader or c to cancel and do nothing (i/c): "); + } if (fgets(yesno,4,stdin)) { if (yesno[0]=='i') { + if(firmfile) { + /* if a firmware file is given create a dualboot image. */ + mknkboot(&firmware, &bootloader, &fw); + } + else { /* Create a single-boot bootloader from the embedded bootloader */ - create_single_boot(bootloader, len_bootloader, &fwbuf, &fwsize); + create_single_boot(bootloader.buf, bootloader.len, &fw.buf, &fw.len); + } - if (fwbuf == NULL) + if (fw.buf == NULL) return 1; - if (mtp_send_firmware(&mtp_info, fwbuf, fwsize) == 0) + if (mtp_send_firmware(&mtp_info, fw.buf, fw.len) == 0) { fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); } @@ -201,7 +228,7 @@ int beastpatcher(const char* bootfile) } /* We are now done with the firmware image */ - free(fwbuf); + free(fw.buf); } else { @@ -209,7 +236,10 @@ int beastpatcher(const char* bootfile) } } if(bootfile) { - free(bootloader); + free(bootloader.buf); + } + if(firmfile) { + free(firmware.buf); } mtp_finished(&mtp_info); diff --git a/utils/MTP/beastpatcher/beastpatcher.h b/utils/MTP/beastpatcher/beastpatcher.h index 899393272f..79246dbb17 100644 --- a/utils/MTP/beastpatcher/beastpatcher.h +++ b/utils/MTP/beastpatcher/beastpatcher.h @@ -40,7 +40,7 @@ #ifndef BEASTPATCHER_H #define BEASTPATCHER_H -int beastpatcher(const char* bootfile); +int beastpatcher(const char* bootfile, const char* firmfile); int sendfirm(const char* filename); #endif diff --git a/utils/MTP/beastpatcher/main.c b/utils/MTP/beastpatcher/main.c index 873dad5c7f..315f78b264 100644 --- a/utils/MTP/beastpatcher/main.c +++ b/utils/MTP/beastpatcher/main.c @@ -56,6 +56,7 @@ enum actions { NONE, INSTALL, + DUALBOOT, SEND, HELP }; @@ -66,11 +67,13 @@ static void print_usage(void) fprintf(stderr,"\n"); fprintf(stderr,"Where [action] is one of the following options:\n"); #ifdef WITH_BOOTOBJS - fprintf(stderr," -i, --install \n"); + fprintf(stderr," -i, --install [bootloader.bin]\n"); + fprintf(stderr," -d, --dual-boot [bootloader.bin]\n"); #else - fprintf(stderr," -i, --install bootloader.bin\n"); + fprintf(stderr," -i, --install \n"); + fprintf(stderr," -d --dual-boot \n"); #endif - fprintf(stderr," -s, --send nk.bin\n"); + fprintf(stderr," -s, --send \n"); fprintf(stderr," -h, --help\n"); fprintf(stderr,"\n"); #ifdef WITH_BOOTOBJS @@ -88,9 +91,9 @@ int main(int argc, char* argv[]) char* bootloader = NULL; char* firmware = NULL; #ifdef WITH_BOOTOBJS - int action = INSTALL; + enum actions action = INSTALL; #else - int action = NONE; + enum actions action = NONE; #endif fprintf(stderr,"beastpatcher v" VERSION " - (C) 2009 by the Rockbox developers\n"); @@ -113,6 +116,20 @@ int main(int argc, char* argv[]) } #endif } + else if(strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--dual-boot") == 0) { + action = DUALBOOT; + if(((i + 1) < argc) && argv[i + 1][0] != '-') { + firmware = argv[++i]; +#ifndef WITH_BOOTOBJS + if(((i + 1) < argc) && argv[i + 1][0] != '-') { + bootloader = argv[++i]; + } +#endif + } + else { + action = NONE; + } + } else if(((strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--send") == 0) && (i + 1) < argc)) { action = SEND; @@ -132,8 +149,11 @@ int main(int argc, char* argv[]) else if(action == SEND) { res = sendfirm(firmware); } + else if(action == DUALBOOT) { + res = beastpatcher(bootloader, firmware); + } else if(action == INSTALL) { - res = beastpatcher(bootloader); + res = beastpatcher(bootloader, NULL); /* don't ask for enter if started with command line arguments */ if(argc == 1) { printf("\nPress ENTER to exit beastpatcher: "); @@ -142,3 +162,4 @@ int main(int argc, char* argv[]) } return res; } +