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
This commit is contained in:
Dominik Riebeling 2009-09-20 08:28:18 +00:00
parent fc30b183c8
commit 6d1d9bed3e
5 changed files with 102 additions and 44 deletions

View file

@ -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,

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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 <bootloader.bin>\n");
fprintf(stderr," -i, --install [bootloader.bin]\n");
fprintf(stderr," -d, --dual-boot <nk.bin> [bootloader.bin]\n");
#else
fprintf(stderr," -i, --install bootloader.bin\n");
fprintf(stderr," -i, --install <bootloader.bin>\n");
fprintf(stderr," -d --dual-boot <nk.bin> <bootloader.bin>\n");
#endif
fprintf(stderr," -s, --send nk.bin\n");
fprintf(stderr," -s, --send <nk.bin>\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;
}