diff options
Diffstat (limited to 'rbutil/mkamsboot/mkamsboot.c')
-rw-r--r-- | rbutil/mkamsboot/mkamsboot.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/rbutil/mkamsboot/mkamsboot.c b/rbutil/mkamsboot/mkamsboot.c index f47afe312a..ae475ed899 100644 --- a/rbutil/mkamsboot/mkamsboot.c +++ b/rbutil/mkamsboot/mkamsboot.c | |||
@@ -31,13 +31,15 @@ Layout of a Sansa AMS original firmware file: | |||
31 | ---------------------- 0x0 | 31 | ---------------------- 0x0 |
32 | | HEADER | | 32 | | HEADER | |
33 | |----------------------| 0x400 | 33 | |----------------------| 0x400 |
34 | | FIRMWARE BLOCK | (contains the OF version on some fuzev2 firmwares | ||
35 | |----------------------| 0x600 | ||
34 | | FIRMWARE BLOCK | | 36 | | FIRMWARE BLOCK | |
35 | |----------------------| 0x400 + firmware block size | 37 | |----------------------| 0x400 + firmware block size |
36 | | LIBRARIES/DATA | | 38 | | LIBRARIES/DATA | |
37 | ---------------------- END | 39 | ---------------------- END |
38 | 40 | ||
39 | We replace the main firmware block (bytes 0x400..0x400+firmware_size) | 41 | We replace the main firmware block while preserving the potential OF version |
40 | as follows: | 42 | (bytes 0x600..0x400+firmware_size) as follows: |
41 | 43 | ||
42 | 44 | ||
43 | ---------------------- 0x0 | 45 | ---------------------- 0x0 |
@@ -531,10 +533,22 @@ void patch_firmware( | |||
531 | unsigned int i; | 533 | unsigned int i; |
532 | 534 | ||
533 | /* Zero the original firmware area - not needed, but helps debugging */ | 535 | /* Zero the original firmware area - not needed, but helps debugging */ |
534 | memset(buf + 0x400, 0, firmware_size); | 536 | memset(buf + 0x600, 0, firmware_size); |
535 | 537 | ||
536 | /* Insert dual-boot bootloader at offset 0 */ | 538 | /* Insert dual-boot bootloader at offset 0x200, we preserve the OF |
537 | memcpy(buf + 0x400, bootloaders[model], bootloader_sizes[model]); | 539 | * version string located between 0x0 and 0x200 */ |
540 | memcpy(buf + 0x600, bootloaders[model], bootloader_sizes[model]); | ||
541 | |||
542 | /* Insert vectors, they won't overwrite the OF version string */ | ||
543 | |||
544 | /* Reset vector: branch 0x200 bytes away, to our dualboot code */ | ||
545 | static const uint8_t b_0x200[4] = { 0x7e, 0x00, 0x00, 0xea }; // b 0x200 | ||
546 | memcpy(buf + 0x400, b_0x200, sizeof(b_0x200)); | ||
547 | |||
548 | /* Other vectors: infinite loops */ | ||
549 | static const uint8_t b_1b[4] = { 0xfe, 0xff, 0xff, 0xea }; // 1: b 1b | ||
550 | for (i=1; i < 8; i++) | ||
551 | memcpy(buf + 0x400 + 4*i, b_1b, sizeof(b_1b)); | ||
538 | 552 | ||
539 | /* We are filling the firmware buffer backwards from the end */ | 553 | /* We are filling the firmware buffer backwards from the end */ |
540 | p = buf + 0x400 + firmware_size; | 554 | p = buf + 0x400 + firmware_size; |
@@ -556,20 +570,20 @@ void patch_firmware( | |||
556 | in each image, along with the size in bytes */ | 570 | in each image, along with the size in bytes */ |
557 | 571 | ||
558 | /* UCL unpack function */ | 572 | /* UCL unpack function */ |
559 | put_uint32le(&buf[0x420], firmware_size - 1); | 573 | put_uint32le(&buf[0x604], firmware_size - 1); |
560 | put_uint32le(&buf[0x424], sizeof(nrv2e_d8)); | 574 | put_uint32le(&buf[0x608], sizeof(nrv2e_d8)); |
561 | 575 | ||
562 | /* Compressed original firmware image */ | 576 | /* Compressed original firmware image */ |
563 | put_uint32le(&buf[0x428], firmware_size - sizeof(nrv2e_d8) - 1); | 577 | put_uint32le(&buf[0x60c], firmware_size - sizeof(nrv2e_d8) - 1); |
564 | put_uint32le(&buf[0x42c], of_packedsize); | 578 | put_uint32le(&buf[0x610], of_packedsize); |
565 | 579 | ||
566 | /* Compressed Rockbox image */ | 580 | /* Compressed Rockbox image */ |
567 | put_uint32le(&buf[0x430], firmware_size - sizeof(nrv2e_d8) - of_packedsize | 581 | put_uint32le(&buf[0x614], firmware_size - sizeof(nrv2e_d8) - of_packedsize |
568 | - 1); | 582 | - 1); |
569 | put_uint32le(&buf[0x434], rb_packedsize); | 583 | put_uint32le(&buf[0x618], rb_packedsize); |
570 | 584 | ||
571 | ucl_dest = model_memory_size(model) - 1; /* last byte of memory */ | 585 | ucl_dest = model_memory_size(model) - 1; /* last byte of memory */ |
572 | put_uint32le(&buf[0x438], ucl_dest); | 586 | put_uint32le(&buf[0x61c], ucl_dest); |
573 | 587 | ||
574 | /* Update the firmware block checksum */ | 588 | /* Update the firmware block checksum */ |
575 | sum = calc_checksum(buf + 0x400, firmware_size); | 589 | sum = calc_checksum(buf + 0x400, firmware_size); |
@@ -619,8 +633,10 @@ int check_sizes(int model, int rb_packed_size, int rb_unpacked_size, | |||
619 | return 0; \ | 633 | return 0; \ |
620 | } while(0) | 634 | } while(0) |
621 | 635 | ||
622 | /* will packed data fit in the OF file ? */ | 636 | /* will packed data fit in the OF file ? |
623 | if(packed_size > of_unpacked_size) | 637 | * XXX: we keep the first 0x200 bytes block unmodified, we just replace |
638 | * the ARM vectors */ | ||
639 | if(packed_size + 0x200 > of_unpacked_size) | ||
624 | ERROR( | 640 | ERROR( |
625 | "[ERR] Packed data (%d bytes) doesn't fit in the firmware " | 641 | "[ERR] Packed data (%d bytes) doesn't fit in the firmware " |
626 | "(%d bytes)\n", packed_size, of_unpacked_size | 642 | "(%d bytes)\n", packed_size, of_unpacked_size |