Mercurial > ecos
comparison packages/redboot/current/src/flash.c @ 162:2395031e7a66
Merge from eCos master repository on 2001-06-15-06:43:03-BST
| author | jlarmour |
|---|---|
| date | Fri, 15 Jun 2001 22:45:04 +0000 |
| parents | ac086aa3217e |
| children | d63db767121d |
comparison
equal
deleted
inserted
replaced
| 161:ac086aa3217e | 162:2395031e7a66 |
|---|---|
| 45 | 45 |
| 46 #include <redboot.h> | 46 #include <redboot.h> |
| 47 #include <cyg/io/flash.h> | 47 #include <cyg/io/flash.h> |
| 48 #include <fis.h> | 48 #include <fis.h> |
| 49 | 49 |
| 50 // Exported CLI functions | 50 // CLI function |
| 51 static cmd_fun do_fis; | 51 static cmd_fun do_fis; |
| 52 RedBoot_cmd("fis", | 52 RedBoot_cmd("fis", |
| 53 "Manage FLASH images", | 53 "Manage FLASH images", |
| 54 "{cmds}", | 54 "{cmds}", |
| 55 do_fis | 55 do_fis |
| 56 ); | 56 ); |
| 57 | 57 |
| 58 // Internal commands | 58 #ifdef CYGOPT_REDBOOT_FIS |
| 59 // Image management functions | |
| 59 local_cmd_entry("init", | 60 local_cmd_entry("init", |
| 60 "Initialize FLASH Image System [FIS]", | 61 "Initialize FLASH Image System [FIS]", |
| 61 "[-f]", | 62 "[-f]", |
| 62 fis_init, | 63 fis_init, |
| 63 FIS_cmds | 64 FIS_cmds |
| 64 ); | 65 ); |
| 65 | |
| 66 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK | 66 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK |
| 67 # define FIS_LIST_OPTS "[-c] [-d]" | 67 # define FIS_LIST_OPTS "[-c] [-d]" |
| 68 #else | 68 #else |
| 69 # define FIS_LIST_OPTS "[-d]" | 69 # define FIS_LIST_OPTS "[-d]" |
| 70 #endif | 70 #endif |
| 71 | |
| 72 local_cmd_entry("list", | 71 local_cmd_entry("list", |
| 73 "Display contents of FLASH Image System [FIS]", | 72 "Display contents of FLASH Image System [FIS]", |
| 74 FIS_LIST_OPTS, | 73 FIS_LIST_OPTS, |
| 75 fis_list, | 74 fis_list, |
| 76 FIS_cmds | 75 FIS_cmds |
| 79 "Display free [available] locations within FLASH Image System [FIS]", | 78 "Display free [available] locations within FLASH Image System [FIS]", |
| 80 "", | 79 "", |
| 81 fis_free, | 80 fis_free, |
| 82 FIS_cmds | 81 FIS_cmds |
| 83 ); | 82 ); |
| 83 local_cmd_entry("delete", | |
| 84 "Display an image from FLASH Image System [FIS]", | |
| 85 "name", | |
| 86 fis_delete, | |
| 87 FIS_cmds | |
| 88 ); | |
| 89 | |
| 90 static char fis_load_usage[] = | |
| 91 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 92 "[-d] " | |
| 93 #endif | |
| 94 "[-b <memory_load_address>] [-c] name"; | |
| 95 | |
| 96 local_cmd_entry("load", | |
| 97 "Load image from FLASH Image System [FIS] into RAM", | |
| 98 fis_load_usage, | |
| 99 fis_load, | |
| 100 FIS_cmds | |
| 101 ); | |
| 102 local_cmd_entry("create", | |
| 103 "Create an image", | |
| 104 "-b <mem_base> -l <image_length> [-s <data_length>]\n" | |
| 105 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", | |
| 106 fis_create, | |
| 107 FIS_cmds | |
| 108 ); | |
| 109 #endif | |
| 110 | |
| 111 // Raw flash access functions | |
| 84 local_cmd_entry("erase", | 112 local_cmd_entry("erase", |
| 85 "Erase FLASH contents", | 113 "Erase FLASH contents", |
| 86 "-f <flash_addr> -l <length>", | 114 "-f <flash_addr> -l <length>", |
| 87 fis_erase, | 115 fis_erase, |
| 88 FIS_cmds | 116 FIS_cmds |
| 99 "-f <flash_addr> -l <length>", | 127 "-f <flash_addr> -l <length>", |
| 100 fis_unlock, | 128 fis_unlock, |
| 101 FIS_cmds | 129 FIS_cmds |
| 102 ); | 130 ); |
| 103 #endif | 131 #endif |
| 104 local_cmd_entry("delete", | |
| 105 "Display an image from FLASH Image System [FIS]", | |
| 106 "name", | |
| 107 fis_delete, | |
| 108 FIS_cmds | |
| 109 ); | |
| 110 | |
| 111 static char fis_load_usage[] = | |
| 112 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 113 "[-d] " | |
| 114 #endif | |
| 115 "[-b <memory_load_address>] [-c] name"; | |
| 116 | |
| 117 local_cmd_entry("load", | |
| 118 "Load image from FLASH Image System [FIS] into RAM", | |
| 119 fis_load_usage, | |
| 120 fis_load, | |
| 121 FIS_cmds | |
| 122 ); | |
| 123 local_cmd_entry("create", | |
| 124 "Create an image", | |
| 125 "-b <mem_base> -l <image_length> [-s <data_length>]\n" | |
| 126 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", | |
| 127 fis_create, | |
| 128 FIS_cmds | |
| 129 ); | |
| 130 local_cmd_entry("write", | 132 local_cmd_entry("write", |
| 131 "Write raw data directly to FLASH", | 133 "Write raw data directly to FLASH", |
| 132 "-f <flash_addr> -b <mem_base> -l <image_length>", | 134 "-f <flash_addr> -b <mem_base> -l <image_length>", |
| 133 fis_write, | 135 fis_write, |
| 134 FIS_cmds | 136 FIS_cmds |
| 143 // Local data used by these routines | 145 // Local data used by these routines |
| 144 static void *flash_start, *flash_end; | 146 static void *flash_start, *flash_end; |
| 145 static int block_size, blocks; | 147 static int block_size, blocks; |
| 146 static void *fis_work_block; | 148 static void *fis_work_block; |
| 147 | 149 |
| 150 static void | |
| 151 fis_usage(char *why) | |
| 152 { | |
| 153 printf("*** invalid 'fis' command: %s\n", why); | |
| 154 cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); | |
| 155 } | |
| 156 | |
| 157 #ifdef CYGOPT_REDBOOT_FIS | |
| 148 struct fis_image_desc * | 158 struct fis_image_desc * |
| 149 fis_lookup(char *name) | 159 fis_lookup(char *name) |
| 150 { | 160 { |
| 151 int i; | 161 int i; |
| 152 void *fis_addr; | 162 void *fis_addr; |
| 159 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 169 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 160 return img; | 170 return img; |
| 161 } | 171 } |
| 162 } | 172 } |
| 163 return (struct fis_image_desc *)0; | 173 return (struct fis_image_desc *)0; |
| 164 } | |
| 165 | |
| 166 static void | |
| 167 fis_usage(char *why) | |
| 168 { | |
| 169 printf("*** invalid 'fis' command: %s\n", why); | |
| 170 cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); | |
| 171 } | 174 } |
| 172 | 175 |
| 173 static void | 176 static void |
| 174 fis_init(int argc, char *argv[]) | 177 fis_init(int argc, char *argv[]) |
| 175 { | 178 { |
| 492 if (!length_set) { | 495 if (!length_set) { |
| 493 length_set = true; | 496 length_set = true; |
| 494 length = img->size; | 497 length = img->size; |
| 495 defaults_assumed = true; | 498 defaults_assumed = true; |
| 496 } | 499 } |
| 497 // img_size can also be handled below, set from length | |
| 498 if (!img_size_set && 0 < img->data_length) { | |
| 499 img_size_set = true; | |
| 500 img_size = img->data_length; | |
| 501 defaults_assumed = true; | |
| 502 } | |
| 503 if (!exec_addr_set) { | 500 if (!exec_addr_set) { |
| 504 // Preserve "normal" behaviour | 501 // Preserve "normal" behaviour |
| 505 exec_addr_set = true; | 502 exec_addr_set = true; |
| 506 exec_addr = flash_addr_set ? flash_addr : mem_addr; | 503 exec_addr = flash_addr_set ? flash_addr : mem_addr; |
| 507 } | 504 } |
| 646 flash_lock((void *)fis_addr, block_size, (void **)&err_addr); | 643 flash_lock((void *)fis_addr, block_size, (void **)&err_addr); |
| 647 #endif | 644 #endif |
| 648 } | 645 } |
| 649 | 646 |
| 650 static void | 647 static void |
| 648 fis_delete(int argc, char *argv[]) | |
| 649 { | |
| 650 char *name; | |
| 651 int i, stat; | |
| 652 void *fis_addr, *err_addr; | |
| 653 struct fis_image_desc *img; | |
| 654 bool slot_found; | |
| 655 | |
| 656 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) | |
| 657 { | |
| 658 fis_usage("invalid arguments"); | |
| 659 return; | |
| 660 } | |
| 661 | |
| 662 slot_found = false; | |
| 663 fis_addr = (void *)((unsigned long)flash_end - block_size); | |
| 664 memcpy(fis_work_block, fis_addr, block_size); | |
| 665 img = (struct fis_image_desc *)fis_work_block; | |
| 666 i = 0; | |
| 667 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE | |
| 668 i++; | |
| 669 #endif | |
| 670 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT | |
| 671 i++; | |
| 672 #endif | |
| 673 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP | |
| 674 i++; | |
| 675 #endif | |
| 676 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST | |
| 677 i++; | |
| 678 #endif | |
| 679 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | |
| 680 i++; | |
| 681 #endif | |
| 682 #if 1 // And the descriptor for the descriptor table itself | |
| 683 i++; | |
| 684 #endif | |
| 685 img += i; // Skip reserved files | |
| 686 | |
| 687 for ( /* i, img */; i < block_size/sizeof(*img); i++, img++) { | |
| 688 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | |
| 689 if (!verify_action("Delete image '%s'", name)) { | |
| 690 return; | |
| 691 } else { | |
| 692 slot_found = true; | |
| 693 break; | |
| 694 } | |
| 695 } | |
| 696 } | |
| 697 if (!slot_found) { | |
| 698 printf("No image '%s' found\n", name); | |
| 699 return; | |
| 700 } | |
| 701 // Erase Data blocks (free space) | |
| 702 if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) { | |
| 703 printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); | |
| 704 } | |
| 705 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | |
| 706 // Insure [quietly] that the directory is unlocked before trying to update | |
| 707 flash_unlock((void *)fis_addr, block_size, (void **)&err_addr); | |
| 708 #endif | |
| 709 // Update directory | |
| 710 memset(img, 0xFF, sizeof(*img)); | |
| 711 if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) { | |
| 712 printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); | |
| 713 // Don't try to program if the erase failed | |
| 714 } else { | |
| 715 // Now program it | |
| 716 if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) { | |
| 717 printf("Error programming at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); | |
| 718 } | |
| 719 } | |
| 720 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | |
| 721 // Insure [quietly] that the directory is locked after the update | |
| 722 flash_lock((void *)fis_addr, block_size, (void **)&err_addr); | |
| 723 #endif | |
| 724 } | |
| 725 | |
| 726 static void | |
| 727 fis_load(int argc, char *argv[]) | |
| 728 { | |
| 729 char *name; | |
| 730 struct fis_image_desc *img; | |
| 731 unsigned long mem_addr; | |
| 732 bool mem_addr_set = false; | |
| 733 bool show_cksum = false; | |
| 734 struct option_info opts[3]; | |
| 735 #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK | |
| 736 unsigned long cksum; | |
| 737 #endif | |
| 738 int num_options; | |
| 739 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 740 bool decompress = false; | |
| 741 #endif | |
| 742 | |
| 743 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, | |
| 744 (void **)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); | |
| 745 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, | |
| 746 (void **)&show_cksum, (bool *)0, "display checksum"); | |
| 747 num_options = 2; | |
| 748 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 749 init_opts(&opts[2], 'd', false, OPTION_ARG_TYPE_FLG, | |
| 750 (void **)&decompress, 0, "decompress"); | |
| 751 num_options++; | |
| 752 #endif | |
| 753 | |
| 754 if (!scan_opts(argc, argv, 2, opts, num_options, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) | |
| 755 { | |
| 756 fis_usage("invalid arguments"); | |
| 757 return; | |
| 758 } | |
| 759 if ((img = fis_lookup(name)) == (struct fis_image_desc *)0) { | |
| 760 printf("No image '%s' found\n", name); | |
| 761 return; | |
| 762 } | |
| 763 if (!mem_addr_set) { | |
| 764 mem_addr = img->mem_base; | |
| 765 } | |
| 766 // Load image from FLASH into RAM | |
| 767 if ((mem_addr < (unsigned long)user_ram_start) || | |
| 768 ((mem_addr+img->size) >= (unsigned long)user_ram_end)) { | |
| 769 printf("Not a loadable image\n"); | |
| 770 return; | |
| 771 } | |
| 772 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 773 if (decompress) { | |
| 774 int err; | |
| 775 _pipe_t fis_load_pipe; | |
| 776 _pipe_t* p = &fis_load_pipe; | |
| 777 p->out_buf = (unsigned char*) mem_addr; | |
| 778 p->out_size = -1; | |
| 779 p->in_buf = (unsigned char*) img->flash_base; | |
| 780 p->in_avail = img->data_length; | |
| 781 | |
| 782 err = (*_dc_init)(p); | |
| 783 | |
| 784 if (0 == err) | |
| 785 err = (*_dc_inflate)(p); | |
| 786 | |
| 787 // Free used resources, do final translation of | |
| 788 // error value. | |
| 789 err = (*_dc_close)(p, err); | |
| 790 | |
| 791 if (0 != err && p->msg) { | |
| 792 printf("decompression error: %s\n", p->msg); | |
| 793 } else { | |
| 794 printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf); | |
| 795 } | |
| 796 | |
| 797 } else // dangling block | |
| 798 #endif | |
| 799 { | |
| 800 memcpy((void *)mem_addr, (void *)img->flash_base, img->data_length); | |
| 801 } | |
| 802 entry_address = (unsigned long *)img->entry_point; | |
| 803 #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK | |
| 804 cksum = crc32((unsigned char *)mem_addr, img->data_length); | |
| 805 if (show_cksum) { | |
| 806 printf("Checksum: 0x%08lx\n", cksum); | |
| 807 } | |
| 808 // When decompressing, leave CRC checking to decompressor | |
| 809 if (!decompress && img->file_cksum) { | |
| 810 if (cksum != img->file_cksum) { | |
| 811 printf("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", | |
| 812 img->file_cksum, cksum); | |
| 813 } | |
| 814 } | |
| 815 #endif | |
| 816 } | |
| 817 #endif // CYGOPT_REDBOOT_FIS | |
| 818 | |
| 819 static void | |
| 651 fis_write(int argc, char *argv[]) | 820 fis_write(int argc, char *argv[]) |
| 652 { | 821 { |
| 653 int stat; | 822 int stat; |
| 654 unsigned long mem_addr, flash_addr, length; | 823 unsigned long mem_addr, flash_addr, length; |
| 655 bool mem_addr_set = false; | 824 bool mem_addr_set = false; |
| 669 { | 838 { |
| 670 fis_usage("invalid arguments"); | 839 fis_usage("invalid arguments"); |
| 671 return; | 840 return; |
| 672 } | 841 } |
| 673 | 842 |
| 674 if (!mem_addr_set || !flash_addr_set || !length_set) | 843 if (!mem_addr_set || !flash_addr_set || !length_set) { |
| 675 fis_usage("required parameter missing"); | 844 fis_usage("required parameter missing"); |
| 845 return; | |
| 846 } | |
| 676 | 847 |
| 677 // Round up length to FLASH block size | 848 // Round up length to FLASH block size |
| 678 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken | 849 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken |
| 679 length = ((length + block_size - 1) / block_size) * block_size; | 850 length = ((length + block_size - 1) / block_size) * block_size; |
| 680 #endif | 851 #endif |
| 831 printf("Error unlocking at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); | 1002 printf("Error unlocking at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); |
| 832 } | 1003 } |
| 833 } | 1004 } |
| 834 #endif | 1005 #endif |
| 835 | 1006 |
| 836 static void | |
| 837 fis_delete(int argc, char *argv[]) | |
| 838 { | |
| 839 char *name; | |
| 840 int i, stat; | |
| 841 void *fis_addr, *err_addr; | |
| 842 struct fis_image_desc *img; | |
| 843 bool slot_found; | |
| 844 | |
| 845 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) | |
| 846 { | |
| 847 fis_usage("invalid arguments"); | |
| 848 return; | |
| 849 } | |
| 850 | |
| 851 slot_found = false; | |
| 852 fis_addr = (void *)((unsigned long)flash_end - block_size); | |
| 853 memcpy(fis_work_block, fis_addr, block_size); | |
| 854 img = (struct fis_image_desc *)fis_work_block; | |
| 855 i = 0; | |
| 856 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE | |
| 857 i++; | |
| 858 #endif | |
| 859 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT | |
| 860 i++; | |
| 861 #endif | |
| 862 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP | |
| 863 i++; | |
| 864 #endif | |
| 865 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST | |
| 866 i++; | |
| 867 #endif | |
| 868 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | |
| 869 i++; | |
| 870 #endif | |
| 871 #if 1 // And the descriptor for the descriptor table itself | |
| 872 i++; | |
| 873 #endif | |
| 874 img += i; // Skip reserved files | |
| 875 | |
| 876 for ( /* i, img */; i < block_size/sizeof(*img); i++, img++) { | |
| 877 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | |
| 878 if (!verify_action("Delete image '%s'", name)) { | |
| 879 return; | |
| 880 } else { | |
| 881 slot_found = true; | |
| 882 break; | |
| 883 } | |
| 884 } | |
| 885 } | |
| 886 if (!slot_found) { | |
| 887 printf("No image '%s' found\n", name); | |
| 888 return; | |
| 889 } | |
| 890 // Erase Data blocks (free space) | |
| 891 if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) { | |
| 892 printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); | |
| 893 } | |
| 894 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | |
| 895 // Insure [quietly] that the directory is unlocked before trying to update | |
| 896 flash_unlock((void *)fis_addr, block_size, (void **)&err_addr); | |
| 897 #endif | |
| 898 // Update directory | |
| 899 memset(img, 0xFF, sizeof(*img)); | |
| 900 if ((stat = flash_erase((void *)fis_addr, block_size, (void **)&err_addr)) != 0) { | |
| 901 printf("Error erasing at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); | |
| 902 // Don't try to program if the erase failed | |
| 903 } else { | |
| 904 // Now program it | |
| 905 if ((stat = flash_program((void *)fis_addr, (void *)fis_work_block, block_size, (void **)&err_addr)) != 0) { | |
| 906 printf("Error programming at %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat)); | |
| 907 } | |
| 908 } | |
| 909 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | |
| 910 // Insure [quietly] that the directory is locked after the update | |
| 911 flash_lock((void *)fis_addr, block_size, (void **)&err_addr); | |
| 912 #endif | |
| 913 } | |
| 914 | |
| 915 static void | |
| 916 fis_load(int argc, char *argv[]) | |
| 917 { | |
| 918 char *name; | |
| 919 struct fis_image_desc *img; | |
| 920 unsigned long mem_addr; | |
| 921 bool mem_addr_set = false; | |
| 922 bool show_cksum = false; | |
| 923 struct option_info opts[3]; | |
| 924 #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK | |
| 925 unsigned long cksum; | |
| 926 #endif | |
| 927 int num_options; | |
| 928 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 929 bool decompress = false; | |
| 930 #endif | |
| 931 | |
| 932 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, | |
| 933 (void **)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); | |
| 934 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, | |
| 935 (void **)&show_cksum, (bool *)0, "display checksum"); | |
| 936 num_options = 2; | |
| 937 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 938 init_opts(&opts[2], 'd', false, OPTION_ARG_TYPE_FLG, | |
| 939 (void **)&decompress, 0, "decompress"); | |
| 940 num_options++; | |
| 941 #endif | |
| 942 | |
| 943 if (!scan_opts(argc, argv, 2, opts, num_options, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) | |
| 944 { | |
| 945 fis_usage("invalid arguments"); | |
| 946 return; | |
| 947 } | |
| 948 if ((img = fis_lookup(name)) == (struct fis_image_desc *)0) { | |
| 949 printf("No image '%s' found\n", name); | |
| 950 return; | |
| 951 } | |
| 952 if (!mem_addr_set) { | |
| 953 mem_addr = img->mem_base; | |
| 954 } | |
| 955 // Load image from FLASH into RAM | |
| 956 if ((mem_addr < (unsigned long)user_ram_start) || | |
| 957 ((mem_addr+img->size) >= (unsigned long)user_ram_end)) { | |
| 958 printf("Not a loadable image\n"); | |
| 959 return; | |
| 960 } | |
| 961 #ifdef CYGPKG_COMPRESS_ZLIB | |
| 962 if (decompress) { | |
| 963 int err; | |
| 964 _pipe_t fis_load_pipe; | |
| 965 _pipe_t* p = &fis_load_pipe; | |
| 966 p->out_buf = (unsigned char*) mem_addr; | |
| 967 p->out_size = -1; | |
| 968 p->in_buf = (unsigned char*) img->flash_base; | |
| 969 p->in_avail = img->data_length; | |
| 970 | |
| 971 err = (*_dc_init)(p); | |
| 972 | |
| 973 if (0 == err) | |
| 974 err = (*_dc_inflate)(p); | |
| 975 | |
| 976 // Free used resources, do final translation of | |
| 977 // error value. | |
| 978 err = (*_dc_close)(p, err); | |
| 979 | |
| 980 if (0 != err && p->msg) { | |
| 981 printf("decompression error: %s\n", p->msg); | |
| 982 } else { | |
| 983 printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf); | |
| 984 } | |
| 985 | |
| 986 } else // dangling block | |
| 987 #endif | |
| 988 { | |
| 989 memcpy((void *)mem_addr, (void *)img->flash_base, img->data_length); | |
| 990 } | |
| 991 entry_address = (unsigned long *)img->entry_point; | |
| 992 #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK | |
| 993 cksum = crc32((unsigned char *)mem_addr, img->data_length); | |
| 994 if (show_cksum) { | |
| 995 printf("Checksum: 0x%08lx\n", cksum); | |
| 996 } | |
| 997 // When decompressing, leave CRC checking to decompressor | |
| 998 if (!decompress && img->file_cksum) { | |
| 999 if (cksum != img->file_cksum) { | |
| 1000 printf("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", | |
| 1001 img->file_cksum, cksum); | |
| 1002 } | |
| 1003 } | |
| 1004 #endif | |
| 1005 } | |
| 1006 | |
| 1007 static bool | 1007 static bool |
| 1008 do_flash_init(void) | 1008 do_flash_init(void) |
| 1009 { | 1009 { |
| 1010 int stat; | 1010 int stat; |
| 1011 static int init = 0; | 1011 static int init = 0; |
| 1012 | 1012 |
| 1013 if (!init) { | 1013 if (!init) { |
| 1014 init = 1; | 1014 init = 1; |
| 1015 if ((stat = flash_init((void *)(workspace_end-FLASH_MIN_WORKSPACE), | 1015 if ((stat = flash_init((void *)(workspace_end-FLASH_MIN_WORKSPACE), |
| 1016 FLASH_MIN_WORKSPACE)) != 0) { | 1016 FLASH_MIN_WORKSPACE, printf)) != 0) { |
| 1017 printf("FLASH: driver init failed!, status: 0x%x\n", stat); | 1017 printf("FLASH: driver init failed!, status: 0x%x\n", stat); |
| 1018 return false; | 1018 return false; |
| 1019 } | 1019 } |
| 1020 flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); | 1020 flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); |
| 1021 flash_get_block_info(&block_size, &blocks); | 1021 flash_get_block_info(&block_size, &blocks); |
