summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-09-09 13:30:40 +0000
committerDave Chapman <dave@dchapman.com>2007-09-09 13:30:40 +0000
commitdd998b7f94a18b1af83334457cff7129e7791258 (patch)
tree05f3c4469dc1a3e1f9ae76dc7047b7437a2850e0
parentcce117240c8f647aa0aee19c93b5f149e99fdc61 (diff)
downloadrockbox-dd998b7f94a18b1af83334457cff7129e7791258.tar.gz
rockbox-dd998b7f94a18b1af83334457cff7129e7791258.zip
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
-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 @@
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
13
14NATIVECC = gcc
15CC = $(CROSS)gcc
16
17all: $(OUTPUT)
18
19e200rpatcher: e200rpatcher.c bootimg.c
20 gcc $(CFLAGS) $(LIBS) -o e200rpatcher e200rpatcher.c bootimg.c
21 strip e200rpatcher
22
23e200rpatcher.exe: e200rpatcher.c bootimg.c
24 $(CC) $(CFLAGS) $(LIBS) -o e200rpatcher.exe e200rpatcher.c bootimg.c
25 $(CROSS)strip e200rpatcher.exe
26
27e200rpatcher-mac: e200rpatcher-i386 e200rpatcher-ppc
28 lipo -create e200rpatcher-ppc e200rpatcher-i386 -output e200rpatcher-mac
29e200rpatcher-i386: e200rpatcher.c bootimg.c
30 gcc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -o bin/i386/program -arch i386 $(CFLAGS) $(LIBS) -o e200rpatcher-i386 e200rpatcher.c bootimg.c
31 strip e200rpatcher-i386
32
33e200rpatcher-ppc: e200rpatcher.c bootimg.c
34 gcc -arch ppc $(CFLAGS) $(LIBS) -o e200rpatcher-ppc e200rpatcher.c bootimg.c
35 strip e200rpatcher-ppc
36
37bin2c: ../sansapatcher/bin2c.c
38 $(NATIVECC) $(CFLAGS) -o bin2c ../sansapatcher/bin2c.c
39
40bootimg.c: bootloader.bin bin2c
41 ./bin2c bootloader.bin bootimg
42
43clean:
44 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 @@
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 * All files in this archive are subject to the GNU General Public License.
19 * See the file COPYING in the source tree root for full license agreement.
20 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25
26
27#include <stdio.h>
28#include <inttypes.h>
29#include <usb.h>
30
31#include "bootimg.h"
32
33#define VERSION "0.1-svn"
34
35/* USB IDs for Manufacturing Mode */
36#define E200R_VENDORID 0x0781
37#define E200R_PRODUCTID 0x0720
38
39#define E200R_BULK_TO 1
40#define TOUT 5000
41#define MAX_TRANSFER 64 /* Number of bytes to send in one write */
42
43#ifndef MAX
44#define MAX(a,b) (((a)>(b))?(a):(b))
45#endif
46
47static void put_int32le(uint32_t x, char* p)
48{
49 p[0] = x & 0xff;
50 p[1] = (x >> 8) & 0xff;
51 p[2] = (x >> 16) & 0xff;
52 p[3] = (x >> 24) & 0xff;
53}
54
55int upload_app(usb_dev_handle* dh)
56{
57 char buf[4];
58 int err;
59 int tosend;
60 char* p = (char*)bootimg;
61 int bytesleft = LEN_bootimg;
62
63 /* Write the data length */
64
65 put_int32le(LEN_bootimg, buf);
66
67 err = usb_bulk_write(dh, E200R_BULK_TO, buf, 4, TOUT);
68
69 if (err < 0)
70 {
71 fprintf(stderr,"[ERR] Error writing data length\n");
72 return -1;
73 }
74
75 /* Now send the data, MAX_TRANSFER bytes at a time. */
76
77 while (bytesleft > 0)
78 {
79 tosend = MAX(MAX_TRANSFER, bytesleft);
80
81 err = usb_bulk_write(dh, E200R_BULK_TO, p, tosend, TOUT);
82
83 if (err < 0)
84 {
85 fprintf(stderr,"[ERR] Error writing data\n");
86 return -1;
87 }
88
89 p += tosend;
90 bytesleft -= tosend;
91 }
92
93 return 0;
94}
95
96
97/* The main function */
98
99void do_patching(void)
100{
101 struct usb_bus *busses;
102 struct usb_bus *bus;
103 struct usb_device *tmp_dev;
104 struct usb_device *dev = NULL;
105 usb_dev_handle *dh;
106
107 fprintf(stderr,"[INFO] Searching for E200R\n");
108
109 usb_init();
110
111 if(usb_find_busses() < 0) {
112 fprintf(stderr, "[ERR] Could not find any USB busses.\n");
113 return;
114 }
115
116 if (usb_find_devices() < 0) {
117 fprintf(stderr, "[ERR] USB devices not found(nor hubs!).\n");
118 return;
119 }
120
121 /* C calling convention, it's not nice to use global stuff */
122 busses = usb_get_busses();
123
124 usb_init();
125 usb_find_busses();
126 usb_find_devices();
127
128 for (bus = busses; bus; bus = bus->next) {
129 for (tmp_dev = bus->devices; tmp_dev; tmp_dev = tmp_dev->next) {
130 if (tmp_dev->descriptor.idVendor == E200R_VENDORID &&
131 tmp_dev->descriptor.idProduct == E200R_PRODUCTID ) {
132
133 dev = tmp_dev;
134 goto found;
135
136 }
137 }
138 }
139
140 if (dev == NULL) {
141 fprintf(stderr, "[ERR] E200R device not found.\n");
142 fprintf(stderr, "[ERR] Ensure your E200R is in manufacturing mode and run e200rpatcher again.\n");
143 return;
144 }
145
146found:
147 if ( (dh = usb_open(dev)) == NULL) {
148 fprintf(stderr,"[ERR] Unable to open E200R device.\n");
149 return;
150 }
151
152 /* "must be called" written in the libusb documentation */
153 if (usb_claim_interface(dh, dev->config->interface->altsetting->bInterfaceNumber)) {
154 fprintf(stderr, "[ERR] Device is busy. (I was unable to claim its interface.)\n");
155 usb_close(dh);
156 return;
157 }
158
159
160 fprintf(stderr,"[ERR] Found E200R, uploading patching application.\n");
161
162 /* Now we can transfer the application to the device. */
163
164 if (upload_app(dh) < 0)
165 {
166 fprintf(stderr,"[ERR] Upload of application failed.\n");
167 }
168 else
169 {
170 fprintf(stderr,"[INFO] Patching application uploaded successfully!\n");
171 }
172
173 /* release claimed interface */
174 usb_release_interface(dh, dev->config->interface->altsetting->bInterfaceNumber);
175
176 usb_close(dh);
177}
178
179
180int main(int argc, char* argv[])
181{
182 char input[4];
183
184 /* We don't use the arguments */
185 (void)argc;
186 (void)argv;
187
188 printf("e200rpatcher v" VERSION " - (C) 2007 Jonathan Gordon & Dave Chapman\n");
189 printf("This is free software; see the source for copying conditions. There is NO\n");
190 printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
191
192 printf("Attach your E200R in \"manufacturing mode\" as follows:\n");
193 printf(" 1) Power-off your E200R\n");
194 printf(" 2) Turn ON the lock/hold switch\n");
195 printf(" 3) Press and hold the SELECT button and whilst it is held down,\n");
196 printf(" attach your E200R to your computer via USB\n");
197 printf(" 4) After attaching to USB, keep the SELECT button held for 10 seconds.\n");
198 printf("\n");
199 printf("NOTE: If your E200R starts in the normal Sansa firmware, you have\n");
200 printf(" failed to enter manufacturing mode and should try again at step 1).\n\n");
201
202 printf("[INFO] Press Enter to continue:");
203 fgets(input, 4, stdin);
204
205 do_patching();
206
207 printf("[INFO] Press ENTER to exit: ");
208 fgets(input, 4, stdin);
209
210 return 0;
211}