summaryrefslogtreecommitdiff
path: root/rbutil/mkamsboot/mkamsboot.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2008-10-12 19:34:47 +0000
committerDave Chapman <dave@dchapman.com>2008-10-12 19:34:47 +0000
commit6bbe66afa03c6c6728bfc90d340ddf391ef94fbc (patch)
tree5842704a432c1877636c94e8c3181f1c4629845a /rbutil/mkamsboot/mkamsboot.c
parentf958717d43420655519ae079ef0d35aa912411b2 (diff)
downloadrockbox-6bbe66afa03c6c6728bfc90d340ddf391ef94fbc.tar.gz
rockbox-6bbe66afa03c6c6728bfc90d340ddf391ef94fbc.zip
Make mkamsboot safer by introducing the use of ".sansa" files to store Sansa V2 bootloader and firmware files. These files are the same format (a simple 8-byte header consisting of a 32-bit checksum followed by 4-char model name is prepended to the binary data) as that used by lots of other Rockbox targets (.ipod, iriver etc). Support added to scramble/mkamsboot for both clip and e200v2, even though the latter is not in SVN yet. Also add a check of the whole-file original firmware checksum to mkamsboot and add a new $scramblebitmaptools toolset variable in configure. The output of this version of mkamsboot is confirmed to be md5sum-identical to the previous version.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18789 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'rbutil/mkamsboot/mkamsboot.c')
-rw-r--r--rbutil/mkamsboot/mkamsboot.c111
1 files changed, 102 insertions, 9 deletions
diff --git a/rbutil/mkamsboot/mkamsboot.c b/rbutil/mkamsboot/mkamsboot.c
index 0dac0e2c72..17f894d77f 100644
--- a/rbutil/mkamsboot/mkamsboot.c
+++ b/rbutil/mkamsboot/mkamsboot.c
@@ -140,6 +140,30 @@ static const int bootloader_sizes[] =
140 0 140 0
141}; 141};
142 142
143/* Model names used in the Rockbox header in ".sansa" files - these match the
144 -add parameter to the "scramble" tool */
145static const char* rb_model_names[] =
146{
147 NULL,
148 "clip",
149 NULL,
150 "e2v2",
151 NULL,
152 NULL
153};
154
155/* Model numbers used to initialise the checksum in the Rockbox header in
156 ".sansa" files - these are the same as MODEL_NUMBER in config-target.h */
157static const int rb_model_num[] =
158{
159 0,
160 50,
161 0,
162 51,
163 0,
164 0
165};
166
143 167
144static off_t filesize(int fd) { 168static off_t filesize(int fd) {
145 struct stat buf; 169 struct stat buf;
@@ -157,6 +181,11 @@ static uint32_t get_uint32le(unsigned char* p)
157 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 181 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
158} 182}
159 183
184static uint32_t get_uint32be(unsigned char* p)
185{
186 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
187}
188
160static void put_uint32le(unsigned char* p, uint32_t x) 189static void put_uint32le(unsigned char* p, uint32_t x)
161{ 190{
162 p[0] = x & 0xff; 191 p[0] = x & 0xff;
@@ -165,7 +194,7 @@ static void put_uint32le(unsigned char* p, uint32_t x)
165 p[3] = (x >> 24) & 0xff; 194 p[3] = (x >> 24) & 0xff;
166} 195}
167 196
168static int calc_checksum(unsigned char* buf, uint32_t n) 197static uint32_t calc_checksum(unsigned char* buf, uint32_t n)
169{ 198{
170 uint32_t sum = 0; 199 uint32_t sum = 0;
171 uint32_t i; 200 uint32_t i;
@@ -264,6 +293,65 @@ static unsigned char* load_file(char* filename, off_t* bufsize)
264} 293}
265 294
266 295
296static unsigned char* load_rockbox_file(char* filename, int model, off_t* bufsize)
297{
298 int fd;
299 unsigned char* buf;
300 unsigned char header[8];
301 uint32_t sum;
302 off_t n;
303 int i;
304
305 fd = open(filename, O_RDONLY|O_BINARY);
306 if (fd < 0)
307 {
308 fprintf(stderr,"[ERR] Could not open %s for reading\n",filename);
309 return NULL;
310 }
311
312 /* Read Rockbox header */
313 n = read(fd, header, sizeof(header));
314 if (n != sizeof(header)) {
315 fprintf(stderr,"[ERR] Could not read file %s\n",filename);
316 return NULL;
317 }
318
319 /* Check for correct model string */
320 if (memcmp(rb_model_names[model],header + 4,4)!=0) {
321 fprintf(stderr,"[ERR] Model name \"%s\" not found in %s\n",
322 rb_model_names[model],filename);
323 }
324
325 *bufsize = filesize(fd) - sizeof(header);
326
327 buf = malloc(*bufsize);
328 if (buf == NULL) {
329 fprintf(stderr,"[ERR] Could not allocate memory for %s\n",filename);
330 return NULL;
331 }
332
333 n = read(fd, buf, *bufsize);
334
335 if (n != *bufsize) {
336 fprintf(stderr,"[ERR] Could not read file %s\n",filename);
337 return NULL;
338 }
339
340 /* Check checksum */
341 sum = rb_model_num[model];
342 for (i = 0; i < *bufsize; i++) {
343 /* add 8 unsigned bits but keep a 32 bit sum */
344 sum += buf[i];
345 }
346
347 if (sum != get_uint32be(header)) {
348 fprintf(stderr,"[ERR] Checksum mismatch in %s\n",filename);
349 return NULL;
350 }
351 return buf;
352}
353
354
267int main(int argc, char* argv[]) 355int main(int argc, char* argv[])
268{ 356{
269 char *infile, *bootfile, *outfile; 357 char *infile, *bootfile, *outfile;
@@ -299,13 +387,6 @@ int main(int argc, char* argv[])
299 bootfile = argv[2]; 387 bootfile = argv[2];
300 outfile = argv[3]; 388 outfile = argv[3];
301 389
302 /* Load bootloader file */
303 rb_unpacked = load_file(bootfile, &bootloader_size);
304 if (rb_unpacked == NULL) {
305 fprintf(stderr,"[ERR] Could not load %s\n",bootfile);
306 return 1;
307 }
308
309 /* Load original firmware file */ 390 /* Load original firmware file */
310 buf = load_file(infile, &len); 391 buf = load_file(infile, &len);
311 392
@@ -314,7 +395,12 @@ int main(int argc, char* argv[])
314 return 1; 395 return 1;
315 } 396 }
316 397
317 /* TODO: Do some more sanity checks on the OF image - e.g. checksum */ 398 /* TODO: Do some more sanity checks on the OF image */
399
400 if (get_uint32le(buf + len - 4) != calc_checksum(buf, len - 4)) {
401 fprintf(stderr,"[ERR] Whole file checksum failed - %s\n",infile);
402 return 1;
403 }
318 404
319 if (get_uint32le(&buf[0x204])==0x0000f000) { 405 if (get_uint32le(&buf[0x204])==0x0000f000) {
320 fw_version = 2; 406 fw_version = 2;
@@ -338,6 +424,13 @@ int main(int argc, char* argv[])
338 return 1; 424 return 1;
339 } 425 }
340 426
427 /* Load bootloader file */
428 rb_unpacked = load_rockbox_file(bootfile, model, &bootloader_size);
429 if (rb_unpacked == NULL) {
430 fprintf(stderr,"[ERR] Could not load %s\n",bootfile);
431 return 1;
432 }
433
341 printf("[INFO] Patching %s firmware\n",model_names[model]); 434 printf("[INFO] Patching %s firmware\n",model_names[model]);
342 435
343 /* Get the firmware size */ 436 /* Get the firmware size */