summaryrefslogtreecommitdiff
path: root/rbutil/sansapatcher/sansapatcher.c
diff options
context:
space:
mode:
authorBarry Wardell <rockbox@barrywardell.net>2007-08-02 11:39:43 +0000
committerBarry Wardell <rockbox@barrywardell.net>2007-08-02 11:39:43 +0000
commit6a0ec8bfa86e7fcf02a9179dc8adbf2f0e25e6e7 (patch)
tree6a166b874002517a623556b5fc396ac6cb967a44 /rbutil/sansapatcher/sansapatcher.c
parent744f07f55439bc4b5d99d4fe0082ab640aad476c (diff)
downloadrockbox-6a0ec8bfa86e7fcf02a9179dc8adbf2f0e25e6e7.tar.gz
rockbox-6a0ec8bfa86e7fcf02a9179dc8adbf2f0e25e6e7.zip
Add --update-original-firmware (or -of) option to sansapatcher. This allows for changing the original firmware version when the rockbox bootloader is also present.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14138 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'rbutil/sansapatcher/sansapatcher.c')
-rw-r--r--rbutil/sansapatcher/sansapatcher.c157
1 files changed, 124 insertions, 33 deletions
diff --git a/rbutil/sansapatcher/sansapatcher.c b/rbutil/sansapatcher/sansapatcher.c
index 9b52196a7b..c9f047f472 100644
--- a/rbutil/sansapatcher/sansapatcher.c
+++ b/rbutil/sansapatcher/sansapatcher.c
@@ -446,44 +446,14 @@ int sansa_scan(struct sansa_t* sansa)
446 return n; 446 return n;
447} 447}
448 448
449static int load_original_firmware(struct sansa_t* sansa, unsigned char* buf, struct mi4header_t* mi4header) 449/* Prepare original firmware for writing to the firmware partition by decrypting
450 and updating the header */
451static int prepare_original_firmware(unsigned char* buf, struct mi4header_t* mi4header)
450{ 452{
451 int ppmi_length;
452 int n;
453 unsigned char* tmpbuf; 453 unsigned char* tmpbuf;
454 int i; 454 int i;
455 int key_found; 455 int key_found;
456 456
457 /* Read 512 bytes from PPMI_OFFSET - the PPMI header plus the mi4 header */
458 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET, buf, 512) < 0) {
459 return -1;
460 }
461
462 /* No need to check PPMI magic - it's done during init to confirm
463 this is an E200 */
464 ppmi_length = le2int(buf+4);
465
466 /* Firstly look for an original firmware after the first image */
467 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, buf, 512) < 0) {
468 return -1;
469 }
470
471 if (get_mi4header(buf,mi4header)==0) {
472 /* We have a valid MI4 file after a bootloader, so we use this. */
473 if ((n = sansa_seek_and_read(sansa,
474 sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
475 buf, mi4header->mi4size)) < 0) {
476 return -1;
477 }
478 } else {
479 /* No valid MI4 file, so read the first image. */
480 if ((n = sansa_seek_and_read(sansa,
481 sansa->start + PPMI_OFFSET + 0x200,
482 buf, ppmi_length)) < 0) {
483 return -1;
484 }
485 }
486
487 get_mi4header(buf,mi4header); 457 get_mi4header(buf,mi4header);
488 458
489#if 0 459#if 0
@@ -538,6 +508,43 @@ static int load_original_firmware(struct sansa_t* sansa, unsigned char* buf, str
538 return 0; 508 return 0;
539} 509}
540 510
511static int load_original_firmware(struct sansa_t* sansa, unsigned char* buf, struct mi4header_t* mi4header)
512{
513 int ppmi_length;
514 int n;
515
516 /* Read 512 bytes from PPMI_OFFSET - the PPMI header plus the mi4 header */
517 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET, buf, 512) < 0) {
518 return -1;
519 }
520
521 /* No need to check PPMI magic - it's done during init to confirm
522 this is an E200 */
523 ppmi_length = le2int(buf+4);
524
525 /* Firstly look for an original firmware after the first image */
526 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET + 0x200 + ppmi_length, buf, 512) < 0) {
527 return -1;
528 }
529
530 if (get_mi4header(buf,mi4header)==0) {
531 /* We have a valid MI4 file after a bootloader, so we use this. */
532 if ((n = sansa_seek_and_read(sansa,
533 sansa->start + PPMI_OFFSET + 0x200 + ppmi_length,
534 buf, mi4header->mi4size)) < 0) {
535 return -1;
536 }
537 } else {
538 /* No valid MI4 file, so read the first image. */
539 if ((n = sansa_seek_and_read(sansa,
540 sansa->start + PPMI_OFFSET + 0x200,
541 buf, ppmi_length)) < 0) {
542 return -1;
543 }
544 }
545 return prepare_original_firmware(buf, mi4header);
546}
547
541int sansa_read_firmware(struct sansa_t* sansa, char* filename) 548int sansa_read_firmware(struct sansa_t* sansa, char* filename)
542{ 549{
543 int res; 550 int res;
@@ -700,3 +707,87 @@ void sansa_list_images(struct sansa_t* sansa)
700 printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size); 707 printf("[INFO] Image 2 - %d bytes\n",mi4header.mi4size);
701 } 708 }
702} 709}
710
711int sansa_update_of(struct sansa_t* sansa, char* filename)
712{
713 int n;
714 int infile = -1; /* Prevent an erroneous "may be used uninitialised" gcc warning */
715 int of_length = 0; /* Keep gcc happy when building for rbutil */
716 int ppmi_length;
717 struct mi4header_t mi4header;
718 char buf[512];
719
720 /* Step 1 - check we have an OF on the Sansa to upgrade. We expect the
721 Rockbox bootloader to be installed and the OF to be after it on disk. */
722
723 /* Read 512 bytes from PPMI_OFFSET - the PPMI header */
724 if (sansa_seek_and_read(sansa, sansa->start + PPMI_OFFSET,
725 buf, 512) < 0) {
726 return -1;
727 }
728
729 /* No need to check PPMI magic - it's done during init to confirm
730 this is an E200 */
731 ppmi_length = le2int(buf+4);
732
733 /* Look for an original firmware after the first image */
734 if (sansa_seek_and_read(sansa, sansa->start+PPMI_OFFSET+0x200+ppmi_length,
735 buf, 512) < 0) {
736 return -1;
737 }
738
739 if (get_mi4header(buf,&mi4header)!=0) {
740 /* We don't have a valid MI4 file after a bootloader, so do nothing. */
741 fprintf(stderr,"[ERR] No original firmware found at 0x%08llx\n",
742 (loff_t)(sansa->start+PPMI_OFFSET+0x200+ppmi_length));
743 return -1;
744 }
745
746 /* Step 2 - read OF into RAM. */
747 infile=open(filename,O_RDONLY|O_BINARY);
748 if (infile < 0) {
749 fprintf(stderr,"[ERR] Couldn't open input file %s\n",filename);
750 return -1;
751 }
752
753 of_length = filesize(infile);
754
755 /* Load original firmware from file */
756 memset(sectorbuf,0,0x200);
757 n = read(infile,sectorbuf,of_length);
758 close(infile);
759 if (n < of_length) {
760 fprintf(stderr,"[ERR] Short read - requested %d bytes, received %d\n"
761 , of_length, n);
762 return -1;
763 }
764
765 /* Check we have a valid MI4 file. */
766 if (get_mi4header(sectorbuf,&mi4header)!=0) {
767 fprintf(stderr,"[ERR] %s is not a valid mi4 file\n",filename);
768 return -1;
769 }
770
771 /* Decrypt and build the header */
772 if(prepare_original_firmware(sectorbuf, &mi4header)!=0){
773 fprintf(stderr,"[ERR] Unable to build decrypted mi4 from %s\n"
774 ,filename);
775 return -1;
776 }
777
778 /* Step 3 - write the OF to the Sansa */
779 if (sansa_seek(sansa, sansa->start+PPMI_OFFSET+0x200+ppmi_length) < 0) {
780 fprintf(stderr,"[ERR] Seek to 0x%08x in sansa_update_of failed.\n",
781 (unsigned int)(sansa->start+PPMI_OFFSET+0x200+ppmi_length));
782 return -1;
783 }
784
785 n=sansa_write(sansa, sectorbuf, of_length);
786 if (n < of_length) {
787 fprintf(stderr,"[ERR] Short write in sansa_update_of\n");
788 return -1;
789 }
790
791 return 0;
792}
793