diff options
author | Jörg Hohensohn <hohensoh@rockbox.org> | 2003-10-26 21:23:04 +0000 |
---|---|---|
committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2003-10-26 21:23:04 +0000 |
commit | a63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5 (patch) | |
tree | e3531598d0f0a09f226657c16f4ac68038291cbf /apps/plugins/firmware_flash.c | |
parent | f11d07c61f4d30c0f47a1a3685e116670bab29ca (diff) | |
download | rockbox-a63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5.tar.gz rockbox-a63cf9b392f1d3cf241bfab0e6badd0acc3cf6a5.zip |
the plugin is now prepared to flash the "V2" variant: boxes without boot ROM which start from flash mirrored to address zero
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3988 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/firmware_flash.c')
-rw-r--r-- | apps/plugins/firmware_flash.c | 141 |
1 files changed, 106 insertions, 35 deletions
diff --git a/apps/plugins/firmware_flash.c b/apps/plugins/firmware_flash.c index d24a174c12..2574cb9f38 100644 --- a/apps/plugins/firmware_flash.c +++ b/apps/plugins/firmware_flash.c | |||
@@ -39,13 +39,13 @@ | |||
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #if defined(ARCHOS_PLAYER) | 41 | #if defined(ARCHOS_PLAYER) |
42 | #define FILENAME "/firmware_play.bin" | 42 | #define FILE_TYPE "player" |
43 | #define KEEP VERSION_ADR /* keep the firmware version */ | 43 | #define KEEP VERSION_ADR /* keep the firmware version */ |
44 | #elif defined(ARCHOS_RECORDER) | 44 | #elif defined(ARCHOS_RECORDER) |
45 | #define FILENAME "/firmware_rec.bin" | 45 | #define FILE_TYPE "rec" |
46 | #define KEEP MASK_ADR /* keep the mask value */ | 46 | #define KEEP MASK_ADR /* keep the mask value */ |
47 | #elif defined(ARCHOS_FMRECORDER) | 47 | #elif defined(ARCHOS_FMRECORDER) |
48 | #define FILENAME "/firmware_fm.bin" | 48 | #define FILE_TYPE "fm" |
49 | #define KEEP MASK_ADR /* keep the mask value */ | 49 | #define KEEP MASK_ADR /* keep the mask value */ |
50 | #else | 50 | #else |
51 | #error ("No known platform given!") | 51 | #error ("No known platform given!") |
@@ -63,6 +63,14 @@ typedef enum | |||
63 | eCrcErr, | 63 | eCrcErr, |
64 | } tCheckResult; | 64 | } tCheckResult; |
65 | 65 | ||
66 | /* result of the CheckBootROM() function */ | ||
67 | typedef enum | ||
68 | { | ||
69 | eBootROM, /* the supported boot ROM */ | ||
70 | eUnknown, /* unknown boot ROM */ | ||
71 | eROMless, /* flash mapped to zero */ | ||
72 | } tCheckROM; | ||
73 | |||
66 | typedef struct | 74 | typedef struct |
67 | { | 75 | { |
68 | UINT8 manufacturer; | 76 | UINT8 manufacturer; |
@@ -244,7 +252,7 @@ unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32) | |||
244 | 252 | ||
245 | /*********** Firmware File Functions ************/ | 253 | /*********** Firmware File Functions ************/ |
246 | 254 | ||
247 | tCheckResult CheckFirmwareFile(char* filename, int chipsize) | 255 | tCheckResult CheckFirmwareFile(char* filename, int chipsize, bool is_romless) |
248 | { | 256 | { |
249 | int i; | 257 | int i; |
250 | int fd; | 258 | int fd; |
@@ -296,20 +304,31 @@ tCheckResult CheckFirmwareFile(char* filename, int chipsize) | |||
296 | if (has_crc) | 304 | if (has_crc) |
297 | crc32 = crc_32(sector, SEC_SIZE, crc32); /* checksum */ | 305 | crc32 = crc_32(sector, SEC_SIZE, crc32); /* checksum */ |
298 | 306 | ||
299 | /* compare some bytes which have to be identical */ | 307 | if (is_romless) |
300 | if (*(UINT32*)sector != 0x41524348) /* "ARCH" */ | 308 | { /* in this case, there is not much we can check */ |
301 | { | 309 | if (*(UINT32*)sector != 0x00000200) /* reset vector */ |
302 | rb->close(fd); | 310 | { |
303 | return eBadContent; | 311 | rb->close(fd); |
312 | return eBadContent; | ||
313 | } | ||
304 | } | 314 | } |
305 | 315 | else | |
306 | for (i = 0x30; i<MASK_ADR-1; i++) /* leave one byte for me */ | ||
307 | { | 316 | { |
308 | if (sector[i] != FB[i]) | 317 | /* compare some bytes which have to be identical */ |
318 | if (*(UINT32*)sector != 0x41524348) /* "ARCH" */ | ||
309 | { | 319 | { |
310 | rb->close(fd); | 320 | rb->close(fd); |
311 | return eBadContent; | 321 | return eBadContent; |
312 | } | 322 | } |
323 | |||
324 | for (i = 0x30; i<MASK_ADR-1; i++) /* leave one byte for me */ | ||
325 | { | ||
326 | if (sector[i] != FB[i]) | ||
327 | { | ||
328 | rb->close(fd); | ||
329 | return eBadContent; | ||
330 | } | ||
331 | } | ||
313 | } | 332 | } |
314 | 333 | ||
315 | /* check if we can read the whole file, and do checksum */ | 334 | /* check if we can read the whole file, and do checksum */ |
@@ -431,6 +450,32 @@ unsigned VerifyFirmwareFile(char* filename) | |||
431 | return failures; | 450 | return failures; |
432 | } | 451 | } |
433 | 452 | ||
453 | /***************** Support Functions *****************/ | ||
454 | |||
455 | /* check if we have "normal" boot ROM or flash mirrored to zero */ | ||
456 | tCheckROM CheckBootROM(void) | ||
457 | { | ||
458 | unsigned boot_crc; | ||
459 | unsigned* pFlash = (unsigned*)FB; | ||
460 | unsigned* pRom = (unsigned*)0x0; | ||
461 | unsigned i; | ||
462 | |||
463 | boot_crc = crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF); | ||
464 | if (boot_crc == 0x56DBA4EE) /* the known boot ROM */ | ||
465 | return eBootROM; | ||
466 | |||
467 | /* check if ROM is a flash mirror */ | ||
468 | for (i=0; i<256*1024/sizeof(unsigned); i++) | ||
469 | { | ||
470 | if (*pRom++ != *pFlash++) | ||
471 | { /* difference means no mirror */ | ||
472 | return eUnknown; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | return eROMless; | ||
477 | } | ||
478 | |||
434 | 479 | ||
435 | /***************** User Interface Functions *****************/ | 480 | /***************** User Interface Functions *****************/ |
436 | 481 | ||
@@ -484,24 +529,39 @@ void ShowFlashInfo(tFlashInfo* pInfo) | |||
484 | 529 | ||
485 | 530 | ||
486 | /* Kind of our main function, defines the application flow. */ | 531 | /* Kind of our main function, defines the application flow. */ |
487 | void DoUserDialog(void) | 532 | void DoUserDialog(char* filename) |
488 | { | 533 | { |
489 | tFlashInfo FlashInfo; | 534 | tFlashInfo FlashInfo; |
490 | char buf[32]; | 535 | char buf[32]; |
536 | char default_filename[32]; | ||
491 | int button; | 537 | int button; |
492 | int rc; /* generic return code */ | 538 | int rc; /* generic return code */ |
493 | int memleft; | 539 | int memleft; |
494 | unsigned boot_crc; | 540 | tCheckROM result; |
541 | bool is_romless; | ||
495 | 542 | ||
496 | rb->lcd_setfont(FONT_SYSFIXED); | 543 | rb->lcd_setfont(FONT_SYSFIXED); |
497 | 544 | ||
498 | /* check boot ROM */ | 545 | /* check boot ROM */ |
499 | boot_crc = crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF); | 546 | result = CheckBootROM(); |
500 | if (boot_crc != 0x56DBA4EE) /* Version 1 */ | 547 | if (result == eUnknown) |
501 | { /* no support for any other yet */ | 548 | { /* no support for any other yet */ |
502 | rb->splash(HZ*3, 0, true, "Wrong boot ROM"); | 549 | rb->splash(HZ*3, 0, true, "Wrong boot ROM"); |
503 | return; /* exit */ | 550 | return; /* exit */ |
504 | } | 551 | } |
552 | is_romless = (result == eROMless); | ||
553 | |||
554 | /* compose filename if none given */ | ||
555 | if (filename == NULL) | ||
556 | { | ||
557 | rb->snprintf( | ||
558 | default_filename, | ||
559 | sizeof(default_filename), | ||
560 | "/firmware_%s%s.bin", | ||
561 | FILE_TYPE, | ||
562 | is_romless ? "_norom" : ""); | ||
563 | filename = default_filename; | ||
564 | } | ||
505 | 565 | ||
506 | /* "allocate" memory */ | 566 | /* "allocate" memory */ |
507 | sector = rb->plugin_get_buffer(&memleft); | 567 | sector = rb->plugin_get_buffer(&memleft); |
@@ -520,7 +580,7 @@ void DoUserDialog(void) | |||
520 | } | 580 | } |
521 | 581 | ||
522 | rb->lcd_puts(0, 3, "using file:"); | 582 | rb->lcd_puts(0, 3, "using file:"); |
523 | rb->lcd_puts(0, 4, FILENAME); | 583 | rb->lcd_puts_scroll(0, 4, filename); |
524 | rb->lcd_puts(0, 6, "[F1] to check file"); | 584 | rb->lcd_puts(0, 6, "[F1] to check file"); |
525 | rb->lcd_puts(0, 7, "other key to exit"); | 585 | rb->lcd_puts(0, 7, "other key to exit"); |
526 | rb->lcd_update(); | 586 | rb->lcd_update(); |
@@ -535,7 +595,7 @@ void DoUserDialog(void) | |||
535 | rb->lcd_puts(0, 0, "checking..."); | 595 | rb->lcd_puts(0, 0, "checking..."); |
536 | rb->lcd_update(); | 596 | rb->lcd_update(); |
537 | 597 | ||
538 | rc = CheckFirmwareFile(FILENAME, FlashInfo.size); | 598 | rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless); |
539 | rb->lcd_puts(0, 0, "checked:"); | 599 | rb->lcd_puts(0, 0, "checked:"); |
540 | switch (rc) | 600 | switch (rc) |
541 | { | 601 | { |
@@ -545,7 +605,7 @@ void DoUserDialog(void) | |||
545 | case eFileNotFound: | 605 | case eFileNotFound: |
546 | rb->lcd_puts(0, 1, "File not found."); | 606 | rb->lcd_puts(0, 1, "File not found."); |
547 | rb->lcd_puts(0, 2, "Put this in root:"); | 607 | rb->lcd_puts(0, 2, "Put this in root:"); |
548 | rb->lcd_puts(0, 4, FILENAME); | 608 | rb->lcd_puts_scroll(0, 4, filename); |
549 | break; | 609 | break; |
550 | case eTooBig: | 610 | case eTooBig: |
551 | rb->lcd_puts(0, 1, "File too big,"); | 611 | rb->lcd_puts(0, 1, "File too big,"); |
@@ -611,7 +671,7 @@ void DoUserDialog(void) | |||
611 | rb->lcd_puts(0, 0, "Programming..."); | 671 | rb->lcd_puts(0, 0, "Programming..."); |
612 | rb->lcd_update(); | 672 | rb->lcd_update(); |
613 | 673 | ||
614 | rc = ProgramFirmwareFile(FILENAME, FlashInfo.size); | 674 | rc = ProgramFirmwareFile(filename, FlashInfo.size); |
615 | if (rc) | 675 | if (rc) |
616 | { /* errors */ | 676 | { /* errors */ |
617 | rb->lcd_clear_display(); | 677 | rb->lcd_clear_display(); |
@@ -627,7 +687,7 @@ void DoUserDialog(void) | |||
627 | rb->lcd_puts(0, 0, "Verifying..."); | 687 | rb->lcd_puts(0, 0, "Verifying..."); |
628 | rb->lcd_update(); | 688 | rb->lcd_update(); |
629 | 689 | ||
630 | rc = VerifyFirmwareFile(FILENAME); | 690 | rc = VerifyFirmwareFile(filename); |
631 | 691 | ||
632 | rb->lcd_clear_display(); | 692 | rb->lcd_clear_display(); |
633 | if (rc == 0) | 693 | if (rc == 0) |
@@ -681,22 +741,37 @@ void ShowFlashInfo(tFlashInfo* pInfo) | |||
681 | } | 741 | } |
682 | 742 | ||
683 | 743 | ||
684 | void DoUserDialog(void) | 744 | void DoUserDialog(char* filename) |
685 | { | 745 | { |
686 | tFlashInfo FlashInfo; | 746 | tFlashInfo FlashInfo; |
687 | char buf[32]; | 747 | char buf[32]; |
748 | char default_filename[32]; | ||
688 | int button; | 749 | int button; |
689 | int rc; /* generic return code */ | 750 | int rc; /* generic return code */ |
690 | int memleft; | 751 | int memleft; |
691 | unsigned boot_crc; | 752 | tCheckROM result; |
753 | bool is_romless; | ||
692 | 754 | ||
693 | /* check boot ROM */ | 755 | /* check boot ROM */ |
694 | boot_crc = crc_32((unsigned char*)0x0, 64*1024, 0xFFFFFFFF); | 756 | result = CheckBootROM(); |
695 | if (boot_crc != 0x56DBA4EE) /* Version 1 */ | 757 | if (result == eUnknown) |
696 | { /* no support for any other yet */ | 758 | { /* no support for any other yet */ |
697 | rb->splash(HZ*3, 0, true, "Wrong boot ROM"); | 759 | rb->splash(HZ*3, 0, true, "Wrong boot ROM"); |
698 | return; /* exit */ | 760 | return; /* exit */ |
699 | } | 761 | } |
762 | is_romless = (result == eROMless); | ||
763 | |||
764 | /* compose filename if none given */ | ||
765 | if (filename == NULL) | ||
766 | { | ||
767 | rb->snprintf( | ||
768 | default_filename, | ||
769 | sizeof(default_filename), | ||
770 | "/firmware_%s%s.bin", | ||
771 | FILE_TYPE, | ||
772 | is_romless ? "_norom" : ""); | ||
773 | filename = default_filename; | ||
774 | } | ||
700 | 775 | ||
701 | /* "allocate" memory */ | 776 | /* "allocate" memory */ |
702 | sector = rb->plugin_get_buffer(&memleft); | 777 | sector = rb->plugin_get_buffer(&memleft); |
@@ -714,7 +789,7 @@ void DoUserDialog(void) | |||
714 | return; /* exit */ | 789 | return; /* exit */ |
715 | } | 790 | } |
716 | 791 | ||
717 | rb->lcd_puts_scroll(0, 0, FILENAME); | 792 | rb->lcd_puts_scroll(0, 0, filename); |
718 | rb->lcd_puts_scroll(0, 1, "[Menu] to check"); | 793 | rb->lcd_puts_scroll(0, 1, "[Menu] to check"); |
719 | 794 | ||
720 | button = WaitForButton(); | 795 | button = WaitForButton(); |
@@ -726,7 +801,7 @@ void DoUserDialog(void) | |||
726 | rb->lcd_clear_display(); | 801 | rb->lcd_clear_display(); |
727 | rb->lcd_puts(0, 0, "Checking..."); | 802 | rb->lcd_puts(0, 0, "Checking..."); |
728 | 803 | ||
729 | rc = CheckFirmwareFile(FILENAME, FlashInfo.size); | 804 | rc = CheckFirmwareFile(filename, FlashInfo.size, is_romless); |
730 | rb->lcd_puts(0, 0, "Checked:"); | 805 | rb->lcd_puts(0, 0, "Checked:"); |
731 | switch (rc) | 806 | switch (rc) |
732 | { | 807 | { |
@@ -735,7 +810,7 @@ void DoUserDialog(void) | |||
735 | break; | 810 | break; |
736 | case eFileNotFound: | 811 | case eFileNotFound: |
737 | rb->lcd_puts_scroll(0, 0, "File not found:"); | 812 | rb->lcd_puts_scroll(0, 0, "File not found:"); |
738 | rb->lcd_puts_scroll(0, 1, FILENAME); | 813 | rb->lcd_puts_scroll(0, 1, filename); |
739 | break; | 814 | break; |
740 | case eTooBig: | 815 | case eTooBig: |
741 | rb->lcd_puts_scroll(0, 0, "File too big,"); | 816 | rb->lcd_puts_scroll(0, 0, "File too big,"); |
@@ -794,7 +869,7 @@ void DoUserDialog(void) | |||
794 | rb->lcd_clear_display(); | 869 | rb->lcd_clear_display(); |
795 | rb->lcd_puts_scroll(0, 0, "Programming..."); | 870 | rb->lcd_puts_scroll(0, 0, "Programming..."); |
796 | 871 | ||
797 | rc = ProgramFirmwareFile(FILENAME, FlashInfo.size); | 872 | rc = ProgramFirmwareFile(filename, FlashInfo.size); |
798 | 873 | ||
799 | if (rc) | 874 | if (rc) |
800 | { /* errors */ | 875 | { /* errors */ |
@@ -808,7 +883,7 @@ void DoUserDialog(void) | |||
808 | rb->lcd_clear_display(); | 883 | rb->lcd_clear_display(); |
809 | rb->lcd_puts_scroll(0, 0, "Verifying..."); | 884 | rb->lcd_puts_scroll(0, 0, "Verifying..."); |
810 | 885 | ||
811 | rc = VerifyFirmwareFile(FILENAME); | 886 | rc = VerifyFirmwareFile(filename); |
812 | 887 | ||
813 | rb->lcd_clear_display(); | 888 | rb->lcd_clear_display(); |
814 | 889 | ||
@@ -838,14 +913,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
838 | matches the machine it is running on */ | 913 | matches the machine it is running on */ |
839 | TEST_PLUGIN_API(api); | 914 | TEST_PLUGIN_API(api); |
840 | 915 | ||
841 | /* if you don't use the parameter, you can do like | ||
842 | this to avoid the compiler warning about it */ | ||
843 | (void)parameter; | ||
844 | |||
845 | rb = api; /* copy to global api pointer */ | 916 | rb = api; /* copy to global api pointer */ |
846 | 917 | ||
847 | /* now go ahead and have fun! */ | 918 | /* now go ahead and have fun! */ |
848 | DoUserDialog(); | 919 | DoUserDialog((char*) parameter); |
849 | 920 | ||
850 | return PLUGIN_OK; | 921 | return PLUGIN_OK; |
851 | } | 922 | } |