Implement sendfirm functionality in beastpatcher. Set svn:eol-style properties.
[kugel-rb.git] / utils / MTP / beastpatcher / beastpatcher.c
blobf0d9394f11cff8b2789ce4721026b2264b070baf
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * $Id$
11 * Copyright (c) 2009, Dave Chapman
12 * All rights reserved.
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met:
18 * * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
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.
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.
38 ****************************************************************************/
40 #include <stdio.h>
41 #if !defined(_MSC_VER)
42 #include <unistd.h>
43 #include <fcntl.h>
44 #endif
45 #include <string.h>
46 #include <stdlib.h>
47 #if !defined(_MSC_VER)
48 #include <inttypes.h>
49 #else
50 #include "pstdint.h"
51 #endif
52 #include <sys/types.h>
53 #include <sys/stat.h>
55 #include "mtp_common.h"
56 #include "bootimg.h"
58 /* Code to create a single-boot bootloader.
59 Based on tools/gigabeats.c by Will Robertson.
62 /* Entry point (and load address) for the main Rockbox bootloader */
63 #define BL_ENTRY_POINT 0x8a000000
65 static void put_uint32le(uint32_t x, unsigned char* p)
67 p[0] = (unsigned char)(x & 0xff);
68 p[1] = (unsigned char)((x >> 8) & 0xff);
69 p[2] = (unsigned char)((x >> 16) & 0xff);
70 p[3] = (unsigned char)((x >> 24) & 0xff);
73 static uint32_t calc_csum(const unsigned char* pb, int cb)
75 uint32_t l = 0;
76 while (cb--)
77 l += *pb++;
78 return l;
81 static void create_single_boot(unsigned char* boot, int bootlen,
82 unsigned char** fwbuf, int* fwsize)
84 unsigned char* buf;
86 /* 15 bytes for header, 16 for signature bypass,
87 * 12 for record header, size of bootloader, 12 for footer */
88 *fwsize = 15 + 16 + 12 + bootlen + 12;
89 *fwbuf = malloc(*fwsize);
91 if(fwbuf == NULL) {
92 fprintf(stderr, "[ERR] Cannot allocate memory.\n" );
93 *fwbuf = NULL;
94 *fwsize = 0;
95 return;
98 buf = *fwbuf;
100 /* Copy bootloader image. */
101 memcpy(buf + 43, boot, bootlen);
103 /* Step 2: Create the file header */
104 sprintf((char *)buf, "B000FF\n");
105 put_uint32le(0x88200000, buf+7);
107 /* If the value below is too small, the update will attempt to flash.
108 * Be careful when changing this (leaving it as is won't cause issues) */
109 put_uint32le(0xCC0CD8, buf+11);
111 /* Step 3: Add the signature bypass record */
112 put_uint32le(0x88065A10, buf+15);
113 put_uint32le(4, buf+19);
114 put_uint32le(0xE3A00001, buf+27);
115 put_uint32le(calc_csum(buf+27,4), buf+23);
117 /* Step 4: Create a record for the actual code */
118 put_uint32le(BL_ENTRY_POINT, buf+31);
119 put_uint32le(bootlen, buf+35);
120 put_uint32le(calc_csum(buf + 43, bootlen), buf+39);
122 /* Step 5: Write the footer */
123 put_uint32le(0, buf+*fwsize-12);
124 put_uint32le(BL_ENTRY_POINT, buf+*fwsize-8);
125 put_uint32le(0, buf+*fwsize-4);
127 return;
130 int beastpatcher(void)
132 char yesno[4];
133 unsigned char* fwbuf;
134 int fwsize;
135 struct mtp_info_t mtp_info;
137 if (mtp_init(&mtp_info) < 0) {
138 fprintf(stderr,"[ERR] Can not init MTP\n");
139 return 1;
142 /* Scan for attached MTP devices. */
143 if (mtp_scan(&mtp_info) < 0)
145 fprintf(stderr,"[ERR] No devices found\n");
146 return 1;
149 printf("[INFO] Found device \"%s - %s\"\n", mtp_info.manufacturer,
150 mtp_info.modelname);
151 printf("[INFO] Device version: \"%s\"\n",mtp_info.version);
154 printf("\nEnter i to install the Rockbox bootloader or c to cancel and do nothing (i/c): ");
156 if (fgets(yesno,4,stdin))
158 if (yesno[0]=='i')
160 /* Create a single-boot bootloader from the embedded bootloader */
161 create_single_boot(bootimg, LEN_bootimg, &fwbuf, &fwsize);
163 if (fwbuf == NULL)
164 return 1;
166 if (mtp_send_firmware(&mtp_info, fwbuf, fwsize) == 0)
168 fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
170 else
172 fprintf(stderr,"[ERR] Bootloader install failed.\n");
175 /* We are now done with the firmware image */
176 free(fwbuf);
178 else
180 fprintf(stderr,"[INFO] Installation cancelled.\n");
184 mtp_finished(&mtp_info);
186 return 0;