Mercurial > ecos-v3_0-branch
diff packages/redboot/current/src/flash.c @ 130:eb9fd8c04db3 ecos-sw-2000-10-23
Merge from eCos master repository on 2000-10-23-17:01:37-BST
| author | jlarmour |
|---|---|
| date | Mon, 23 Oct 2000 17:10:57 +0000 |
| parents | 518f42066aba |
| children | 0ae0bc38e387 |
line wrap: on
line diff
--- a/packages/redboot/current/src/flash.c +++ b/packages/redboot/current/src/flash.c @@ -45,17 +45,7 @@ #include <redboot.h> #include <cyg/io/flash.h> - -struct image_desc { - unsigned char name[16]; // Null terminated name - unsigned long flash_base; // Address within FLASH of image - unsigned long mem_base; // Address in memory where it executes - unsigned long size; // Length of image - unsigned long entry_point; // Execution entry point - unsigned char _pad[256-40]; - unsigned long desc_cksum; // Checksum over image descriptor - unsigned long file_cksum; // Checksum over image data -}; +#include <fis.h> // Exported CLI functions RedBoot_cmd("fis", @@ -124,7 +114,7 @@ local_cmd_entry("load", ); local_cmd_entry("create", "Create an image", - "-b <mem_base> -l <length> [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] <name>", + "-b <mem_base> -l <image_length> [-s <data_length>] [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] <name>", fis_create, FIS_cmds ); @@ -151,13 +141,14 @@ static void fis_init(int argc, char *argv[]) { int stat, img_count = 0; - struct image_desc *img; + struct fis_image_desc *img; void *fis_base, *err_addr; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG void *cfg_base; #endif bool full_init = false; struct option_info opts[1]; + unsigned long redboot_image_size; init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, (void **)&full_init, (bool *)0, "full initialization, erases all of flash"); @@ -180,19 +171,21 @@ fis_init(int argc, char *argv[]) printf(" Warning: device contents not erased, some blocks may not be usable\n"); } // Create a pseudo image for RedBoot - img = (struct image_desc *)fis_work_block; +#define MIN_REDBOOT_IMAGE_SIZE 0x20000 + redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE; + img = (struct fis_image_desc *)fis_work_block; memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot"); img->flash_base = (unsigned long)flash_start; img->mem_base = (unsigned long)flash_start; - img->size = block_size; + img->size = redboot_image_size; img++; img_count++; // And a backup image memset(img, 0, sizeof(*img)); strcpy(img->name, "RedBoot[backup]"); - img->flash_base = (unsigned long)flash_start+block_size; - img->mem_base = (unsigned long)flash_start+block_size; - img->size = block_size; + img->flash_base = (unsigned long)flash_start+redboot_image_size; + img->mem_base = (unsigned long)flash_start+redboot_image_size; + img->size = redboot_image_size; img++; img_count++; #ifdef CYGSEM_REDBOOT_FLASH_CONFIG // And a descriptor for the configuration data @@ -226,10 +219,10 @@ fis_init(int argc, char *argv[]) static void fis_list(int argc, char *argv[]) { - struct image_desc *img; + struct fis_image_desc *img; int i; - img = (struct image_desc *)((unsigned long)flash_end - block_size); + img = (struct fis_image_desc *)((unsigned long)flash_end - block_size); printf("Name FLASH addr Mem addr Length Entry point\n"); for (i = 0; i < block_size/sizeof(*img); i++, img++) { if (img->name[0] != (unsigned char)0xFF) { @@ -320,17 +313,18 @@ static void fis_create(int argc, char *argv[]) { int i, stat; - unsigned long mem_addr, exec_addr, flash_addr, entry_addr, length; + unsigned long mem_addr, exec_addr, flash_addr, entry_addr, length, img_size; char *name; bool mem_addr_set = false; bool exec_addr_set = false; bool entry_addr_set = false; bool flash_addr_set = false; bool length_set = false; + bool img_size_set = false; void *fis_addr, *err_addr; - struct image_desc *img; + struct fis_image_desc *img; bool slot_found; - struct option_info opts[5]; + struct option_info opts[6]; bool prog_ok; init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, @@ -342,8 +336,10 @@ fis_create(int argc, char *argv[]) init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, - (void **)&length, (bool *)&length_set, "length"); - if (!scan_opts(argc, argv, 2, opts, 5, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) + (void **)&length, (bool *)&length_set, "image length [in FLASH]"); + init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, + (void **)&img_size, (bool *)&img_size_set, "image size [actual data]"); + if (!scan_opts(argc, argv, 2, opts, 6, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) { fis_usage("invalid arguments"); return; @@ -353,15 +349,25 @@ fis_create(int argc, char *argv[]) fis_usage("required parameter missing"); return; } + if (!img_size_set) { + img_size = length; + } + // 'length' is size of FLASH image, 'img_size' is actual data size + // Round up length to FLASH block size + length = ((length + block_size - 1) / block_size) * block_size; + if (length < img_size) { + printf("Invalid FLASH image size/length combination"); + return; + } if (flash_addr_set && ((stat = flash_verify_addr((void *)flash_addr)) || - (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { + (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) { printf("Invalid FLASH address: %p (%s)\n", (void *)flash_addr, flash_errmsg(stat)); printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); return; } if ((mem_addr < (unsigned long)ram_start) || - ((mem_addr+length) >= (unsigned long)ram_end)) { + ((mem_addr+img_size) >= (unsigned long)ram_end)) { printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); } @@ -378,7 +384,7 @@ fis_create(int argc, char *argv[]) slot_found = false; fis_addr = (void *)((unsigned long)flash_end - block_size); memcpy(fis_work_block, fis_addr, block_size); - img = (struct image_desc *)fis_work_block; + img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { if (flash_addr_set && (img->flash_base != flash_addr)) { @@ -399,7 +405,7 @@ fis_create(int argc, char *argv[]) } // If not found, try and find an empty slot if (!slot_found) { - img = (struct image_desc *)fis_work_block; + img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if (img->name[0] == (unsigned char)0xFF) { slot_found = true; @@ -408,7 +414,7 @@ fis_create(int argc, char *argv[]) } } // Safety check - make sure the address range is not within the code we're running - if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { + if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { printf("Can't program this region - contains code in use!\n"); return; } @@ -422,7 +428,7 @@ fis_create(int argc, char *argv[]) } if (prog_ok) { // Now program it - if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { + if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { printf("Can't program region at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); prog_ok = false; } @@ -567,7 +573,7 @@ fis_delete(int argc, char *argv[]) char *name; int i, stat; void *fis_addr, *err_addr; - struct image_desc *img; + struct fis_image_desc *img; bool slot_found; if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) @@ -579,7 +585,7 @@ fis_delete(int argc, char *argv[]) slot_found = false; fis_addr = (void *)((unsigned long)flash_end - block_size); memcpy(fis_work_block, fis_addr, block_size); - img = (struct image_desc *)fis_work_block; + img = (struct fis_image_desc *)fis_work_block; img += 2; // Skip reserved files for (i = 2; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { @@ -618,7 +624,7 @@ fis_load(int argc, char *argv[]) char *name; int i; void *fis_addr; - struct image_desc *img; + struct fis_image_desc *img; bool slot_found; if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) @@ -630,7 +636,7 @@ fis_load(int argc, char *argv[]) slot_found = false; fis_addr = (void *)((unsigned long)flash_end - block_size); memcpy(fis_work_block, fis_addr, block_size); - img = (struct image_desc *)fis_work_block; + img = (struct fis_image_desc *)fis_work_block; for (i = 0; i < block_size/sizeof(*img); i++, img++) { if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { slot_found = true; @@ -728,11 +734,18 @@ RedBoot_config_option("Boot script", "boot_script", true, CONFIG_SCRIPT ); -RedBoot_config_option("Boot script timeout", +// Some preprocessor magic for building the [constant] prompt string +#define __cat(s1,c2,s3) s1 ## #c2 ## s3 +#define _cat(s1,c2,s3) __cat(s1,c2,s3) +RedBoot_config_option(_cat("Boot script timeout (", + CYGNUM_REDBOOT_FLASH_SCRIPT_TIMEOUT_RESOLUTION, + "ms resolution)"), boot_script_timeout, "boot_script", true, CONFIG_INT ); +#undef __cat +#undef _cat CYG_HAL_TABLE_BEGIN( __CONFIG_options_TAB__, RedBoot_config_options); CYG_HAL_TABLE_END( __CONFIG_options_TAB_END__, RedBoot_config_options);
