From a1d0345ac50c93fade79ac72ad7250c4854a3902 Mon Sep 17 00:00:00 2001 From: dave Date: Sun, 9 Sep 2007 13:30:40 +0000 Subject: [PATCH] Initial version of standalone e200rpatcher tool to upload and run the e200r patching application to patch the original Sansa bootloader. This requires the patching binary (called bootloader.bin) to be in the e200rpatcher directory when compiling. Currently only tested on Linux. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14656 a1c6a512-1295-4272-9138-f99709370657 --- rbutil/e200rpatcher/Makefile | 44 ++++++++ rbutil/e200rpatcher/e200rpatcher.c | 211 +++++++++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 rbutil/e200rpatcher/Makefile create mode 100644 rbutil/e200rpatcher/e200rpatcher.c diff --git a/rbutil/e200rpatcher/Makefile b/rbutil/e200rpatcher/Makefile new file mode 100644 index 000000000..243b2e6c0 --- /dev/null +++ b/rbutil/e200rpatcher/Makefile @@ -0,0 +1,44 @@ +CFLAGS=-Wall -W + +ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN) +OUTPUT=e200rpatcher.exe +CROSS= +CFLAGS+=-mno-cygwin +else +OUTPUT=e200rpatcher +CROSS=i586-mingw32msvc- +endif + +LIBS = -lusb + +NATIVECC = gcc +CC = $(CROSS)gcc + +all: $(OUTPUT) + +e200rpatcher: e200rpatcher.c bootimg.c + gcc $(CFLAGS) $(LIBS) -o e200rpatcher e200rpatcher.c bootimg.c + strip e200rpatcher + +e200rpatcher.exe: e200rpatcher.c bootimg.c + $(CC) $(CFLAGS) $(LIBS) -o e200rpatcher.exe e200rpatcher.c bootimg.c + $(CROSS)strip e200rpatcher.exe + +e200rpatcher-mac: e200rpatcher-i386 e200rpatcher-ppc + lipo -create e200rpatcher-ppc e200rpatcher-i386 -output e200rpatcher-mac +e200rpatcher-i386: e200rpatcher.c bootimg.c + gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -o bin/i386/program -arch i386 $(CFLAGS) $(LIBS) -o e200rpatcher-i386 e200rpatcher.c bootimg.c + strip e200rpatcher-i386 + +e200rpatcher-ppc: e200rpatcher.c bootimg.c + gcc -arch ppc $(CFLAGS) $(LIBS) -o e200rpatcher-ppc e200rpatcher.c bootimg.c + strip e200rpatcher-ppc + +bin2c: ../sansapatcher/bin2c.c + $(NATIVECC) $(CFLAGS) -o bin2c ../sansapatcher/bin2c.c + +bootimg.c: bootloader.bin bin2c + ./bin2c bootloader.bin bootimg + +clean: + rm -f e200rpatcher.exe e200rpatcher-mac e200rpatcher-i386 e200rpatcher-ppc e200rpatcher bin2c bootimg.c bootimg.h *~ diff --git a/rbutil/e200rpatcher/e200rpatcher.c b/rbutil/e200rpatcher/e200rpatcher.c new file mode 100644 index 000000000..a2531e9f6 --- /dev/null +++ b/rbutil/e200rpatcher/e200rpatcher.c @@ -0,0 +1,211 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2007 Dave Chapman + * + * USB code based on ifp-line - http://ifp-driver.sourceforge.net + * + * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and + * licensed under the GPL (v2) + * + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + + +#include +#include +#include + +#include "bootimg.h" + +#define VERSION "0.1-svn" + +/* USB IDs for Manufacturing Mode */ +#define E200R_VENDORID 0x0781 +#define E200R_PRODUCTID 0x0720 + +#define E200R_BULK_TO 1 +#define TOUT 5000 +#define MAX_TRANSFER 64 /* Number of bytes to send in one write */ + +#ifndef MAX +#define MAX(a,b) (((a)>(b))?(a):(b)) +#endif + +static void put_int32le(uint32_t x, char* p) +{ + p[0] = x & 0xff; + p[1] = (x >> 8) & 0xff; + p[2] = (x >> 16) & 0xff; + p[3] = (x >> 24) & 0xff; +} + +int upload_app(usb_dev_handle* dh) +{ + char buf[4]; + int err; + int tosend; + char* p = (char*)bootimg; + int bytesleft = LEN_bootimg; + + /* Write the data length */ + + put_int32le(LEN_bootimg, buf); + + err = usb_bulk_write(dh, E200R_BULK_TO, buf, 4, TOUT); + + if (err < 0) + { + fprintf(stderr,"[ERR] Error writing data length\n"); + return -1; + } + + /* Now send the data, MAX_TRANSFER bytes at a time. */ + + while (bytesleft > 0) + { + tosend = MAX(MAX_TRANSFER, bytesleft); + + err = usb_bulk_write(dh, E200R_BULK_TO, p, tosend, TOUT); + + if (err < 0) + { + fprintf(stderr,"[ERR] Error writing data\n"); + return -1; + } + + p += tosend; + bytesleft -= tosend; + } + + return 0; +} + + +/* The main function */ + +void do_patching(void) +{ + struct usb_bus *busses; + struct usb_bus *bus; + struct usb_device *tmp_dev; + struct usb_device *dev = NULL; + usb_dev_handle *dh; + + fprintf(stderr,"[INFO] Searching for E200R\n"); + + usb_init(); + + if(usb_find_busses() < 0) { + fprintf(stderr, "[ERR] Could not find any USB busses.\n"); + return; + } + + if (usb_find_devices() < 0) { + fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n"); + return; + } + + /* C calling convention, it's not nice to use global stuff */ + busses = usb_get_busses(); + + usb_init(); + usb_find_busses(); + usb_find_devices(); + + for (bus = busses; bus; bus = bus->next) { + for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next) { + if (tmp_dev->descriptor.idVendor == E200R_VENDORID && + tmp_dev->descriptor.idProduct == E200R_PRODUCTID ) { + + dev = tmp_dev; + goto found; + + } + } + } + + if (dev == NULL) { + fprintf(stderr, "[ERR] E200R device not found.\n"); + fprintf(stderr, "[ERR] Ensure your E200R is in manufacturing mode and run e200rpatcher again.\n"); + return; + } + +found: + if ( (dh = usb_open(dev)) == NULL) { + fprintf(stderr,"[ERR] Unable to open E200R device.\n"); + return; + } + + /* "must be called" written in the libusb documentation */ + if (usb_claim_interface(dh, dev->config->interface->altsetting->bInterfaceNumber)) { + fprintf(stderr, "[ERR] Device is busy. (I was unable to claim its interface.)\n"); + usb_close(dh); + return; + } + + + fprintf(stderr,"[ERR] Found E200R, uploading patching application.\n"); + + /* Now we can transfer the application to the device. */ + + if (upload_app(dh) < 0) + { + fprintf(stderr,"[ERR] Upload of application failed.\n"); + } + else + { + fprintf(stderr,"[INFO] Patching application uploaded successfully!\n"); + } + + /* release claimed interface */ + usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber); + + usb_close(dh); +} + + +int main(int argc, char* argv[]) +{ + char input[4]; + + /* We don't use the arguments */ + (void)argc; + (void)argv; + + printf("e200rpatcher v" VERSION " - (C) 2007 Jonathan Gordon & Dave Chapman\n"); + printf("This is free software; see the source for copying conditions. There is NO\n"); + printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); + + printf("Attach your E200R in \"manufacturing mode\" as follows:\n"); + printf(" 1) Power-off your E200R\n"); + printf(" 2) Turn ON the lock/hold switch\n"); + printf(" 3) Press and hold the SELECT button and whilst it is held down,\n"); + printf(" attach your E200R to your computer via USB\n"); + printf(" 4) After attaching to USB, keep the SELECT button held for 10 seconds.\n"); + printf("\n"); + printf("NOTE: If your E200R starts in the normal Sansa firmware, you have\n"); + printf(" failed to enter manufacturing mode and should try again at step 1).\n\n"); + + printf("[INFO] Press Enter to continue:"); + fgets(input, 4, stdin); + + do_patching(); + + printf("[INFO] Press ENTER to exit: "); + fgets(input, 4, stdin); + + return 0; +} -- 2.11.4.GIT