diff options
Diffstat (limited to 'utils/MTP/beastpatcher/beastpatcher.c')
-rw-r--r-- | utils/MTP/beastpatcher/beastpatcher.c | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/utils/MTP/beastpatcher/beastpatcher.c b/utils/MTP/beastpatcher/beastpatcher.c new file mode 100644 index 0000000000..8043ebadc2 --- /dev/null +++ b/utils/MTP/beastpatcher/beastpatcher.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * $Id:$ | ||
10 | * | ||
11 | * Copyright (c) 2009, Dave Chapman | ||
12 | * All rights reserved. | ||
13 | * | ||
14 | * Redistribution and use in source and binary forms, with or without | ||
15 | * modification, are permitted provided that the following conditions are | ||
16 | * met: | ||
17 | * | ||
18 | * * Redistributions of source code must retain the above copyright | ||
19 | * notice, this list of conditions and the following disclaimer. | ||
20 | * | ||
21 | * * Redistributions in binary form must reproduce the above | ||
22 | * copyright notice, this list of conditions and the following | ||
23 | * disclaimer in the documentation and/or other materials provided | ||
24 | * with the distribution. | ||
25 | * | ||
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
27 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
28 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
29 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
30 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
31 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
32 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
33 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
34 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
35 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
36 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
37 | * | ||
38 | ****************************************************************************/ | ||
39 | |||
40 | #include <stdio.h> | ||
41 | #include <unistd.h> | ||
42 | #include <fcntl.h> | ||
43 | #include <string.h> | ||
44 | #include <stdlib.h> | ||
45 | #include <inttypes.h> | ||
46 | #include <sys/types.h> | ||
47 | #include <sys/stat.h> | ||
48 | |||
49 | #include "mtp_common.h" | ||
50 | #include "bootimg.h" | ||
51 | |||
52 | #define VERSION "1.0 with v1 bootloader" | ||
53 | |||
54 | void print_usage(void) | ||
55 | { | ||
56 | fprintf(stderr,"Usage: beastpatcher [action]\n"); | ||
57 | fprintf(stderr,"\n"); | ||
58 | fprintf(stderr,"Where [action] is one of the following options:\n"); | ||
59 | fprintf(stderr," --install (default)\n"); | ||
60 | fprintf(stderr," -?, --help\n"); | ||
61 | fprintf(stderr,"\n"); | ||
62 | } | ||
63 | |||
64 | /* Code to create a single-boot bootloader. | ||
65 | Based on tools/gigabeats.c by Will Robertson. | ||
66 | */ | ||
67 | |||
68 | /* Entry point (and load address) for the main Rockbox bootloader */ | ||
69 | #define BL_ENTRY_POINT 0x8a000000 | ||
70 | |||
71 | static void put_uint32le(uint32_t x, unsigned char* p) | ||
72 | { | ||
73 | p[0] = x & 0xff; | ||
74 | p[1] = (x >> 8) & 0xff; | ||
75 | p[2] = (x >> 16) & 0xff; | ||
76 | p[3] = (x >> 24) & 0xff; | ||
77 | } | ||
78 | |||
79 | static uint32_t calc_csum(const unsigned char* pb, int cb) | ||
80 | { | ||
81 | uint32_t l = 0; | ||
82 | while (cb--) | ||
83 | l += *pb++; | ||
84 | return l; | ||
85 | } | ||
86 | |||
87 | static void create_single_boot(unsigned char* boot, int bootlen, | ||
88 | unsigned char** fwbuf, int* fwsize) | ||
89 | { | ||
90 | unsigned char* buf; | ||
91 | |||
92 | /* 15 bytes for header, 16 for signature bypass, | ||
93 | * 12 for record header, size of bootloader, 12 for footer */ | ||
94 | *fwsize = 15 + 16 + 12 + bootlen + 12; | ||
95 | *fwbuf = malloc(*fwsize); | ||
96 | |||
97 | if(buf == NULL) { | ||
98 | fprintf(stderr, "[ERR] Cannot allocate memory.\n" ); | ||
99 | *fwbuf = NULL; | ||
100 | *fwsize = 0; | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | buf = *fwbuf; | ||
105 | |||
106 | /* Copy bootloader image. */ | ||
107 | memcpy(buf + 43, boot, bootlen); | ||
108 | |||
109 | /* Step 2: Create the file header */ | ||
110 | sprintf((char *)buf, "B000FF\n"); | ||
111 | put_uint32le(0x88200000, buf+7); | ||
112 | |||
113 | /* If the value below is too small, the update will attempt to flash. | ||
114 | * Be careful when changing this (leaving it as is won't cause issues) */ | ||
115 | put_uint32le(0xCC0CD8, buf+11); | ||
116 | |||
117 | /* Step 3: Add the signature bypass record */ | ||
118 | put_uint32le(0x88065A10, buf+15); | ||
119 | put_uint32le(4, buf+19); | ||
120 | put_uint32le(0xE3A00001, buf+27); | ||
121 | put_uint32le(calc_csum(buf+27,4), buf+23); | ||
122 | |||
123 | /* Step 4: Create a record for the actual code */ | ||
124 | put_uint32le(BL_ENTRY_POINT, buf+31); | ||
125 | put_uint32le(bootlen, buf+35); | ||
126 | put_uint32le(calc_csum(buf + 43, bootlen), buf+39); | ||
127 | |||
128 | /* Step 5: Write the footer */ | ||
129 | put_uint32le(0, buf+*fwsize-12); | ||
130 | put_uint32le(BL_ENTRY_POINT, buf+*fwsize-8); | ||
131 | put_uint32le(0, buf+*fwsize-4); | ||
132 | |||
133 | return; | ||
134 | } | ||
135 | |||
136 | int beastpatcher(int argc, char* argv[]) | ||
137 | { | ||
138 | char yesno[4]; | ||
139 | unsigned char* fwbuf; | ||
140 | int fwsize; | ||
141 | struct mtp_info_t mtp_info; | ||
142 | |||
143 | (void)argv; | ||
144 | |||
145 | fprintf(stderr,"beastpatcher v" VERSION " - (C) 2009 by the Rockbox developers\n"); | ||
146 | fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n"); | ||
147 | fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); | ||
148 | |||
149 | /* No options are currently implemented, so just display help if any are | ||
150 | provided. */ | ||
151 | |||
152 | if (argc > 1) { | ||
153 | print_usage(); | ||
154 | return 1; | ||
155 | } | ||
156 | |||
157 | if (mtp_init(&mtp_info) < 0) { | ||
158 | fprintf(stderr,"[ERR] Can not init MTP\n"); | ||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | /* Scan for attached MTP devices. */ | ||
163 | if (mtp_scan(&mtp_info) < 0) | ||
164 | { | ||
165 | fprintf(stderr,"[ERR] No devices found\n"); | ||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | printf("[INFO] Found device \"%s - %s\"\n", mtp_info.manufacturer, | ||
170 | mtp_info.modelname); | ||
171 | printf("[INFO] Device version: \"%s\"\n",mtp_info.version); | ||
172 | |||
173 | |||
174 | printf("\nEnter i to install the Rockbox bootloader or c to cancel and do nothing (i/c): "); | ||
175 | |||
176 | if (fgets(yesno,4,stdin)) | ||
177 | { | ||
178 | if (yesno[0]=='i') | ||
179 | { | ||
180 | /* Create a single-boot bootloader from the embedded bootloader */ | ||
181 | create_single_boot(bootimg, LEN_bootimg, &fwbuf, &fwsize); | ||
182 | |||
183 | if (fwbuf == NULL) | ||
184 | return 1; | ||
185 | |||
186 | if (mtp_send_firmware(&mtp_info, fwbuf, fwsize) == 0) | ||
187 | { | ||
188 | fprintf(stderr,"[INFO] Bootloader installed successfully.\n"); | ||
189 | } | ||
190 | else | ||
191 | { | ||
192 | fprintf(stderr,"[ERR] Bootloader install failed.\n"); | ||
193 | } | ||
194 | |||
195 | /* We are now done with the firmware image */ | ||
196 | free(fwbuf); | ||
197 | } | ||
198 | else | ||
199 | { | ||
200 | fprintf(stderr,"[INFO] Installation cancelled.\n"); | ||
201 | } | ||
202 | } | ||
203 | |||
204 | mtp_finished(&mtp_info); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | |||
210 | int main(int argc, char* argv[]) | ||
211 | { | ||
212 | int res; | ||
213 | char yesno[4]; | ||
214 | |||
215 | res = beastpatcher(argc, argv); | ||
216 | |||
217 | printf("\nPress ENTER to exit beastpatcher: "); | ||
218 | fgets(yesno,4,stdin); | ||
219 | |||
220 | return res; | ||
221 | } | ||