summaryrefslogtreecommitdiffstats
path: root/rbutil
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil')
-rw-r--r--rbutil/e200rpatcher/Makefile44
-rw-r--r--rbutil/e200rpatcher/e200rpatcher.c211
2 files changed, 255 insertions, 0 deletions
diff --git a/rbutil/e200rpatcher/Makefile b/rbutil/e200rpatcher/Makefile
new file mode 100644
index 0000000000..243b2e6c09
--- /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 0000000000..a2531e9f6d
--- /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 <stdio.h>
+#include <inttypes.h>
+#include <usb.h>
+
+#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;
+}