summaryrefslogtreecommitdiff
path: root/utils/MTP/beastpatcher/beastpatcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/MTP/beastpatcher/beastpatcher.c')
-rw-r--r--utils/MTP/beastpatcher/beastpatcher.c221
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
54void 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
71static 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
79static 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
87static 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
136int 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
210int 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}