summaryrefslogtreecommitdiff
path: root/utils/e200rpatcher
diff options
context:
space:
mode:
Diffstat (limited to 'utils/e200rpatcher')
-rw-r--r--utils/e200rpatcher/Makefile56
-rw-r--r--utils/e200rpatcher/README48
-rw-r--r--utils/e200rpatcher/e200rpatcher.c241
-rw-r--r--utils/e200rpatcher/e200rpatcher.manifest13
-rw-r--r--utils/e200rpatcher/e200rpatcher.rc1
5 files changed, 359 insertions, 0 deletions
diff --git a/utils/e200rpatcher/Makefile b/utils/e200rpatcher/Makefile
new file mode 100644
index 0000000000..dfe5c1e037
--- /dev/null
+++ b/utils/e200rpatcher/Makefile
@@ -0,0 +1,56 @@
1CFLAGS=-Wall -W
2
3ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
4OUTPUT=e200rpatcher.exe
5CROSS=
6CFLAGS+=-mno-cygwin
7else
8OUTPUT=e200rpatcher
9CROSS=i586-mingw32msvc-
10endif
11
12LIBS = -lusb
13WINLIBS = -I libusb-win32-device-bin-0.1.12.1/include libusb-win32-device-bin-0.1.12.1/lib/dynamic/libusb_dyn.c
14
15NATIVECC = gcc
16CC = $(CROSS)gcc
17WINDRES = $(CROSS)windres
18
19all: $(OUTPUT)
20
21e200rpatcher: e200rpatcher.c bootimg.c
22 gcc $(CFLAGS) $(LIBS) -o e200rpatcher e200rpatcher.c bootimg.c
23 strip e200rpatcher
24
25e200rpatcher.exe: e200rpatcher.c bootimg.c e200rpatcher-rc.o
26 $(CC) $(CFLAGS) $(WINLIBS) -o e200rpatcher.exe e200rpatcher.c bootimg.c e200rpatcher-rc.o
27 $(CROSS)strip e200rpatcher.exe
28
29e200rpatcher-rc.o: e200rpatcher.rc e200rpatcher.manifest
30 $(WINDRES) -i e200rpatcher.rc -o e200rpatcher-rc.o
31
32e200rpatcher-mac: e200rpatcher-i386 e200rpatcher-ppc
33 lipo -create e200rpatcher-ppc e200rpatcher-i386 -output e200rpatcher-mac
34
35e200rpatcher.dmg: e200rpatcher-mac
36 mkdir -p e200rpatcher-dmg
37 cp -p e200rpatcher-mac e200rpatcher-dmg
38 hdiutil create -srcfolder e200rpatcher-dmg e200rpatcher.dmg
39
40e200rpatcher-i386: e200rpatcher.c bootimg.c usb.h libusb-i386.a
41 gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch i386 $(CFLAGS) -o e200rpatcher-i386 e200rpatcher.c bootimg.c -I. libusb-i386.a
42 strip e200rpatcher-i386
43
44e200rpatcher-ppc: e200rpatcher.c bootimg.c usb.h libusb-ppc.a
45 gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -framework iokit -framework coreservices -arch ppc $(CFLAGS) -o e200rpatcher-ppc e200rpatcher.c bootimg.c -I. libusb-ppc.a
46 strip e200rpatcher-ppc
47
48bin2c: ../tools/bin2c.c
49 $(NATIVECC) $(CFLAGS) -o bin2c ../tools/bin2c.c
50
51bootimg.c: bootloader.bin bin2c
52 ./bin2c bootloader.bin bootimg
53
54clean:
55 rm -f e200rpatcher.exe e200rpatcher-mac e200rpatcher-i386 e200rpatcher-ppc e200rpatcher bin2c bootimg.c bootimg.h *~ e200rpatcher.dmg
56 rm -rf e200rpatcher-dmg
diff --git a/utils/e200rpatcher/README b/utils/e200rpatcher/README
new file mode 100644
index 0000000000..1942b3aa7a
--- /dev/null
+++ b/utils/e200rpatcher/README
@@ -0,0 +1,48 @@
1INTRODUCTION
2
3e200rpatcher is a tool for uploading and executing an application to
4an E200R in manufacturing mode. It is intended to be used to upload
5the patching application to allow Rockbox installs.
6
7e200rpatcher requires libusb (v0.1.2 has been tested successfully) for
8cross-platform USB access. No-one has yet successfully installed
9e200rpatcher on Windows, but it works on Linux and Mac OS X (and
10should be fine on other Unix-like systems that libusb supports).
11
12GENERAL BUILD INSTRUCTIONS
13
14A pre-requisite for compiling e200rpatcher is a file called
15"bootloader.bin" - this is the output of running an "I" (installer)
16build for the E200R target.
17
18In the Rockbox source directory, do:
19
20mkdir build-e200rbootbin
21cd build-e200rbootbin
22../tools/configure
23[Select E200R, then I for installer]
24make
25
26This should give you a bootloader/bootloader/bin file which you should
27copy to the e200rpatcher source directory.
28
29BUILDING ON LINUX
30
31The Makefile expects libusb (and the headers) to be installed on your
32system and will link dynamically. Just type "make".
33
34BUILDING ON A MAC
35
36To build the mac version (target e200rpatcher-mac in the Makefile)
37requires three files from libusb to be copied to the current
38directory:
39
40usb.h (copied from your libusb build directory)
41libusb-i386.a (copied and renamed from .libs/libusb.a in an i386 build)
42libusb-ppc.a (copied and renamed from .libs/libusb.a in a PPC build)
43
44To build the required libusb.a files, just run ./configure && make for
45libusb. If anyone knows how to cross-compile a static libusb.a please
46make the information known - this is currently done by compiling
47natively on the appropriate hardware.
48
diff --git a/utils/e200rpatcher/e200rpatcher.c b/utils/e200rpatcher/e200rpatcher.c
new file mode 100644
index 0000000000..be09370997
--- /dev/null
+++ b/utils/e200rpatcher/e200rpatcher.c
@@ -0,0 +1,241 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * USB code based on ifp-line - http://ifp-driver.sourceforge.net
13 *
14 * ifp-line is (C) Pavel Kriz, Jun Yamishiro and Joe Roback and
15 * licensed under the GPL (v2)
16 *
17 *
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
22 *
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
25 *
26 ****************************************************************************/
27
28
29#include <stdio.h>
30#include <inttypes.h>
31#include <usb.h>
32#include <string.h>
33#include "stdbool.h"
34
35#include "bootimg.h"
36
37#define VERSION "0.2"
38
39/* USB IDs for Manufacturing Mode */
40#define E200R_VENDORID 0x0781
41#define E200R_PRODUCTID 0x0720
42
43#define E200R_BULK_TO 1
44#define TOUT 5000
45#define MAX_TRANSFER 64 /* Number of bytes to send in one write */
46
47#ifndef MAX
48#define MAX(a,b) (((a)>(b))?(a):(b))
49#endif
50
51static void put_int32le(uint32_t x, char* p)
52{
53 p[0] = x & 0xff;
54 p[1] = (x >> 8) & 0xff;
55 p[2] = (x >> 16) & 0xff;
56 p[3] = (x >> 24) & 0xff;
57}
58
59int upload_app(usb_dev_handle* dh)
60{
61 char buf[4];
62 int err;
63 int tosend;
64 char* p = (char*)bootimg;
65 int bytesleft = LEN_bootimg;
66
67 /* Write the data length */
68
69 put_int32le(LEN_bootimg, buf);
70
71 err = usb_bulk_write(dh, E200R_BULK_TO, buf, 4, TOUT);
72
73 if (err < 0)
74 {
75 fprintf(stderr,"[ERR] Error writing data length\n");
76 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err));
77 return -1;
78 }
79
80 /* Now send the data, MAX_TRANSFER bytes at a time. */
81
82 while (bytesleft > 0)
83 {
84 tosend = MAX(MAX_TRANSFER, bytesleft);
85
86 err = usb_bulk_write(dh, E200R_BULK_TO, p, tosend, TOUT);
87
88 if (err < 0)
89 {
90 fprintf(stderr,"[ERR] Error writing data\n");
91 fprintf(stderr,"[ERR] Bulk write error (%d, %s)\n", err, strerror(-err));
92 return -1;
93 }
94
95 p += tosend;
96 bytesleft -= tosend;
97 }
98
99 return 0;
100}
101
102
103/* The main function */
104
105void do_patching(void)
106{
107 struct usb_bus *busses;
108 struct usb_bus *bus;
109 struct usb_device *tmp_dev;
110 struct usb_device *dev = NULL;
111 usb_dev_handle *dh;
112 int err;
113
114 fprintf(stderr,"[INFO] Searching for E200R\n");
115
116 usb_init();
117
118 if(usb_find_busses() < 0) {
119 fprintf(stderr, "[ERR] Could not find any USB busses.\n");
120 return;
121 }
122
123 if (usb_find_devices() < 0) {
124 fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n");
125 return;
126 }
127
128 /* C calling convention, it's not nice to use global stuff */
129 busses = usb_get_busses();
130
131 for (bus = busses; bus; bus = bus->next) {
132 for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next) {
133 if (tmp_dev->descriptor.idVendor == E200R_VENDORID &&
134 tmp_dev->descriptor.idProduct == E200R_PRODUCTID ) {
135
136 dev = tmp_dev;
137 goto found;
138
139 }
140 }
141 }
142
143 if (dev == NULL) {
144 fprintf(stderr, "[ERR] E200R device not found.\n");
145 fprintf(stderr, "[ERR] Ensure your E200R is in manufacturing mode and run e200rpatcher again.\n");
146 return;
147 }
148
149found:
150 if ( (dh = usb_open(dev)) == NULL) {
151 fprintf(stderr,"[ERR] Unable to open E200R device.\n");
152 return;
153 }
154
155 err = usb_set_configuration(dh, 1);
156
157 if (err < 0) {
158 fprintf(stderr, "[ERR] usb_set_configuration failed (%d)\n", err);
159 usb_close(dh);
160 return;
161 }
162
163 /* "must be called" written in the libusb documentation */
164 err = usb_claim_interface(dh, dev->config->interface->altsetting->bInterfaceNumber);
165 if (err < 0) {
166 fprintf(stderr, "[ERR] Unable to claim interface (%d)\n", err);
167 usb_close(dh);
168 return;
169 }
170
171 fprintf(stderr,"[INFO] Found E200R, uploading patching application.\n");
172
173 /* Now we can transfer the application to the device. */
174
175 if (upload_app(dh) < 0)
176 {
177 fprintf(stderr,"[ERR] Upload of application failed.\n");
178 }
179 else
180 {
181 fprintf(stderr,"[INFO] Patching application uploaded successfully!\n");
182 }
183
184 /* release claimed interface */
185 usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber);
186
187 usb_close(dh);
188}
189void print_usage(void)
190{
191 fprintf(stderr,"Usage: e200rpatcher [options]\n");
192 fprintf(stderr,"Options:\n");
193 fprintf(stderr," -s, --silent\t\tDont display instructions\n");
194}
195
196int main(int argc, char* argv[])
197{
198 char input[4];
199 int silent = 0;
200 int i;
201
202 /* check args */
203 if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) {
204 print_usage();
205 return 1;
206 }
207 for (i=1;i<argc;i++)
208 {
209 if (!strcmp(argv[i], "--silent") || !strcmp(argv[i], "-s"))
210 silent = 1;
211 }
212
213 printf("e200rpatcher v" VERSION " - (C) 2007 Jonathan Gordon & Dave Chapman\n");
214 printf("This is free software; see the source for copying conditions. There is NO\n");
215 printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
216
217 if (!silent)
218 {
219 printf("Attach your E200R in \"manufacturing mode\" as follows:\n");
220 printf(" 1) Power-off your E200R\n");
221 printf(" 2) Turn ON the lock/hold switch\n");
222 printf(" 3) Press and hold the SELECT button and whilst it is held down,\n");
223 printf(" attach your E200R to your computer via USB\n");
224 printf(" 4) After attaching to USB, keep the SELECT button held for 10 seconds.\n");
225 printf("\n");
226 printf("NOTE: If your E200R starts in the normal Sansa firmware, you have\n");
227 printf(" failed to enter manufacturing mode and should try again at step 1).\n\n");
228
229 printf("[INFO] Press Enter to continue:");
230 fgets(input, 4, stdin);
231 }
232 do_patching();
233
234 if (!silent)
235 {
236 printf("[INFO] Press ENTER to exit: ");
237 fgets(input, 4, stdin);
238 }
239
240 return 0;
241}
diff --git a/utils/e200rpatcher/e200rpatcher.manifest b/utils/e200rpatcher/e200rpatcher.manifest
new file mode 100644
index 0000000000..ec0c49df33
--- /dev/null
+++ b/utils/e200rpatcher/e200rpatcher.manifest
@@ -0,0 +1,13 @@
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
3 <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="e200rpatcher.exe" type="win32"/>
4
5 <!-- Identify the application security requirements. -->
6 <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
7 <security>
8 <requestedPrivileges>
9 <requestedExecutionLevel level="requireAdministrator"/>
10 </requestedPrivileges>
11 </security>
12 </trustInfo>
13</assembly>
diff --git a/utils/e200rpatcher/e200rpatcher.rc b/utils/e200rpatcher/e200rpatcher.rc
new file mode 100644
index 0000000000..4d80442d44
--- /dev/null
+++ b/utils/e200rpatcher/e200rpatcher.rc
@@ -0,0 +1 @@
1 24 MOVEABLE PURE "e200rpatcher.manifest"