comparison 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
comparison
equal deleted inserted replaced
129:605a0fc6f385 130:eb9fd8c04db3
43 // 43 //
44 //========================================================================== 44 //==========================================================================
45 45
46 #include <redboot.h> 46 #include <redboot.h>
47 #include <cyg/io/flash.h> 47 #include <cyg/io/flash.h>
48 48 #include <fis.h>
49 struct image_desc {
50 unsigned char name[16]; // Null terminated name
51 unsigned long flash_base; // Address within FLASH of image
52 unsigned long mem_base; // Address in memory where it executes
53 unsigned long size; // Length of image
54 unsigned long entry_point; // Execution entry point
55 unsigned char _pad[256-40];
56 unsigned long desc_cksum; // Checksum over image descriptor
57 unsigned long file_cksum; // Checksum over image data
58 };
59 49
60 // Exported CLI functions 50 // Exported CLI functions
61 RedBoot_cmd("fis", 51 RedBoot_cmd("fis",
62 "Manage FLASH images", 52 "Manage FLASH images",
63 "{cmds}", 53 "{cmds}",
122 fis_load, 112 fis_load,
123 FIS_cmds 113 FIS_cmds
124 ); 114 );
125 local_cmd_entry("create", 115 local_cmd_entry("create",
126 "Create an image", 116 "Create an image",
127 "-b <mem_base> -l <length> [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] <name>", 117 "-b <mem_base> -l <image_length> [-s <data_length>] [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] <name>",
128 fis_create, 118 fis_create,
129 FIS_cmds 119 FIS_cmds
130 ); 120 );
131 121
132 // Define table boundaries 122 // Define table boundaries
149 139
150 static void 140 static void
151 fis_init(int argc, char *argv[]) 141 fis_init(int argc, char *argv[])
152 { 142 {
153 int stat, img_count = 0; 143 int stat, img_count = 0;
154 struct image_desc *img; 144 struct fis_image_desc *img;
155 void *fis_base, *err_addr; 145 void *fis_base, *err_addr;
156 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG 146 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
157 void *cfg_base; 147 void *cfg_base;
158 #endif 148 #endif
159 bool full_init = false; 149 bool full_init = false;
160 struct option_info opts[1]; 150 struct option_info opts[1];
151 unsigned long redboot_image_size;
161 152
162 init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, 153 init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG,
163 (void **)&full_init, (bool *)0, "full initialization, erases all of flash"); 154 (void **)&full_init, (bool *)0, "full initialization, erases all of flash");
164 if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) 155 if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, ""))
165 { 156 {
178 } 169 }
179 } else { 170 } else {
180 printf(" Warning: device contents not erased, some blocks may not be usable\n"); 171 printf(" Warning: device contents not erased, some blocks may not be usable\n");
181 } 172 }
182 // Create a pseudo image for RedBoot 173 // Create a pseudo image for RedBoot
183 img = (struct image_desc *)fis_work_block; 174 #define MIN_REDBOOT_IMAGE_SIZE 0x20000
175 redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE;
176 img = (struct fis_image_desc *)fis_work_block;
184 memset(img, 0, sizeof(*img)); 177 memset(img, 0, sizeof(*img));
185 strcpy(img->name, "RedBoot"); 178 strcpy(img->name, "RedBoot");
186 img->flash_base = (unsigned long)flash_start; 179 img->flash_base = (unsigned long)flash_start;
187 img->mem_base = (unsigned long)flash_start; 180 img->mem_base = (unsigned long)flash_start;
188 img->size = block_size; 181 img->size = redboot_image_size;
189 img++; img_count++; 182 img++; img_count++;
190 // And a backup image 183 // And a backup image
191 memset(img, 0, sizeof(*img)); 184 memset(img, 0, sizeof(*img));
192 strcpy(img->name, "RedBoot[backup]"); 185 strcpy(img->name, "RedBoot[backup]");
193 img->flash_base = (unsigned long)flash_start+block_size; 186 img->flash_base = (unsigned long)flash_start+redboot_image_size;
194 img->mem_base = (unsigned long)flash_start+block_size; 187 img->mem_base = (unsigned long)flash_start+redboot_image_size;
195 img->size = block_size; 188 img->size = redboot_image_size;
196 img++; img_count++; 189 img++; img_count++;
197 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG 190 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
198 // And a descriptor for the configuration data 191 // And a descriptor for the configuration data
199 memset(img, 0, sizeof(*img)); 192 memset(img, 0, sizeof(*img));
200 strcpy(img->name, "RedBoot config"); 193 strcpy(img->name, "RedBoot config");
224 } 217 }
225 218
226 static void 219 static void
227 fis_list(int argc, char *argv[]) 220 fis_list(int argc, char *argv[])
228 { 221 {
229 struct image_desc *img; 222 struct fis_image_desc *img;
230 int i; 223 int i;
231 224
232 img = (struct image_desc *)((unsigned long)flash_end - block_size); 225 img = (struct fis_image_desc *)((unsigned long)flash_end - block_size);
233 printf("Name FLASH addr Mem addr Length Entry point\n"); 226 printf("Name FLASH addr Mem addr Length Entry point\n");
234 for (i = 0; i < block_size/sizeof(*img); i++, img++) { 227 for (i = 0; i < block_size/sizeof(*img); i++, img++) {
235 if (img->name[0] != (unsigned char)0xFF) { 228 if (img->name[0] != (unsigned char)0xFF) {
236 printf("%-16s 0x%08lX 0x%08lX 0x%06lX 0x%08lX\n", img->name, 229 printf("%-16s 0x%08lX 0x%08lX 0x%06lX 0x%08lX\n", img->name,
237 img->flash_base, img->mem_base, img->size, img->entry_point); 230 img->flash_base, img->mem_base, img->size, img->entry_point);
318 311
319 static void 312 static void
320 fis_create(int argc, char *argv[]) 313 fis_create(int argc, char *argv[])
321 { 314 {
322 int i, stat; 315 int i, stat;
323 unsigned long mem_addr, exec_addr, flash_addr, entry_addr, length; 316 unsigned long mem_addr, exec_addr, flash_addr, entry_addr, length, img_size;
324 char *name; 317 char *name;
325 bool mem_addr_set = false; 318 bool mem_addr_set = false;
326 bool exec_addr_set = false; 319 bool exec_addr_set = false;
327 bool entry_addr_set = false; 320 bool entry_addr_set = false;
328 bool flash_addr_set = false; 321 bool flash_addr_set = false;
329 bool length_set = false; 322 bool length_set = false;
323 bool img_size_set = false;
330 void *fis_addr, *err_addr; 324 void *fis_addr, *err_addr;
331 struct image_desc *img; 325 struct fis_image_desc *img;
332 bool slot_found; 326 bool slot_found;
333 struct option_info opts[5]; 327 struct option_info opts[6];
334 bool prog_ok; 328 bool prog_ok;
335 329
336 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 330 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM,
337 (void **)&mem_addr, (bool *)&mem_addr_set, "memory base address"); 331 (void **)&mem_addr, (bool *)&mem_addr_set, "memory base address");
338 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, 332 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM,
340 init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, 334 init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM,
341 (void **)&entry_addr, (bool *)&entry_addr_set, "entry point address"); 335 (void **)&entry_addr, (bool *)&entry_addr_set, "entry point address");
342 init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, 336 init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM,
343 (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); 337 (void **)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address");
344 init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, 338 init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM,
345 (void **)&length, (bool *)&length_set, "length"); 339 (void **)&length, (bool *)&length_set, "image length [in FLASH]");
346 if (!scan_opts(argc, argv, 2, opts, 5, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) 340 init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM,
341 (void **)&img_size, (bool *)&img_size_set, "image size [actual data]");
342 if (!scan_opts(argc, argv, 2, opts, 6, (void *)&name, OPTION_ARG_TYPE_STR, "file name"))
347 { 343 {
348 fis_usage("invalid arguments"); 344 fis_usage("invalid arguments");
349 return; 345 return;
350 } 346 }
351 347
352 if (!mem_addr_set || !length_set || !name) { 348 if (!mem_addr_set || !length_set || !name) {
353 fis_usage("required parameter missing"); 349 fis_usage("required parameter missing");
354 return; 350 return;
355 } 351 }
352 if (!img_size_set) {
353 img_size = length;
354 }
355 // 'length' is size of FLASH image, 'img_size' is actual data size
356 // Round up length to FLASH block size
357 length = ((length + block_size - 1) / block_size) * block_size;
358 if (length < img_size) {
359 printf("Invalid FLASH image size/length combination");
360 return;
361 }
356 if (flash_addr_set && 362 if (flash_addr_set &&
357 ((stat = flash_verify_addr((void *)flash_addr)) || 363 ((stat = flash_verify_addr((void *)flash_addr)) ||
358 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { 364 (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) {
359 printf("Invalid FLASH address: %p (%s)\n", (void *)flash_addr, flash_errmsg(stat)); 365 printf("Invalid FLASH address: %p (%s)\n", (void *)flash_addr, flash_errmsg(stat));
360 printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); 366 printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end);
361 return; 367 return;
362 } 368 }
363 if ((mem_addr < (unsigned long)ram_start) || 369 if ((mem_addr < (unsigned long)ram_start) ||
364 ((mem_addr+length) >= (unsigned long)ram_end)) { 370 ((mem_addr+img_size) >= (unsigned long)ram_end)) {
365 printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); 371 printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
366 printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); 372 printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
367 } 373 }
368 if (strlen(name) >= sizeof(img->name)) { 374 if (strlen(name) >= sizeof(img->name)) {
369 printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); 375 printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name));
376 // Find a slot in the directory for this entry 382 // Find a slot in the directory for this entry
377 // First, see if an image by this name is already present 383 // First, see if an image by this name is already present
378 slot_found = false; 384 slot_found = false;
379 fis_addr = (void *)((unsigned long)flash_end - block_size); 385 fis_addr = (void *)((unsigned long)flash_end - block_size);
380 memcpy(fis_work_block, fis_addr, block_size); 386 memcpy(fis_work_block, fis_addr, block_size);
381 img = (struct image_desc *)fis_work_block; 387 img = (struct fis_image_desc *)fis_work_block;
382 for (i = 0; i < block_size/sizeof(*img); i++, img++) { 388 for (i = 0; i < block_size/sizeof(*img); i++, img++) {
383 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { 389 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) {
384 if (flash_addr_set && (img->flash_base != flash_addr)) { 390 if (flash_addr_set && (img->flash_base != flash_addr)) {
385 printf("Image found, but FLASH address incorrect\n"); 391 printf("Image found, but FLASH address incorrect\n");
386 return; 392 return;
397 } 403 }
398 } 404 }
399 } 405 }
400 // If not found, try and find an empty slot 406 // If not found, try and find an empty slot
401 if (!slot_found) { 407 if (!slot_found) {
402 img = (struct image_desc *)fis_work_block; 408 img = (struct fis_image_desc *)fis_work_block;
403 for (i = 0; i < block_size/sizeof(*img); i++, img++) { 409 for (i = 0; i < block_size/sizeof(*img); i++, img++) {
404 if (img->name[0] == (unsigned char)0xFF) { 410 if (img->name[0] == (unsigned char)0xFF) {
405 slot_found = true; 411 slot_found = true;
406 break; 412 break;
407 } 413 }
408 } 414 }
409 } 415 }
410 // Safety check - make sure the address range is not within the code we're running 416 // Safety check - make sure the address range is not within the code we're running
411 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { 417 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) {
412 printf("Can't program this region - contains code in use!\n"); 418 printf("Can't program this region - contains code in use!\n");
413 return; 419 return;
414 } 420 }
415 prog_ok = true; 421 prog_ok = true;
416 if (prog_ok) { 422 if (prog_ok) {
420 prog_ok = false; 426 prog_ok = false;
421 } 427 }
422 } 428 }
423 if (prog_ok) { 429 if (prog_ok) {
424 // Now program it 430 // Now program it
425 if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { 431 if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) {
426 printf("Can't program region at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat)); 432 printf("Can't program region at %p: %x(%s)\n", err_addr, stat, flash_errmsg(stat));
427 prog_ok = false; 433 prog_ok = false;
428 } 434 }
429 } 435 }
430 // Update directory 436 // Update directory
565 fis_delete(int argc, char *argv[]) 571 fis_delete(int argc, char *argv[])
566 { 572 {
567 char *name; 573 char *name;
568 int i, stat; 574 int i, stat;
569 void *fis_addr, *err_addr; 575 void *fis_addr, *err_addr;
570 struct image_desc *img; 576 struct fis_image_desc *img;
571 bool slot_found; 577 bool slot_found;
572 578
573 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) 579 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name"))
574 { 580 {
575 fis_usage("invalid arguments"); 581 fis_usage("invalid arguments");
577 } 583 }
578 584
579 slot_found = false; 585 slot_found = false;
580 fis_addr = (void *)((unsigned long)flash_end - block_size); 586 fis_addr = (void *)((unsigned long)flash_end - block_size);
581 memcpy(fis_work_block, fis_addr, block_size); 587 memcpy(fis_work_block, fis_addr, block_size);
582 img = (struct image_desc *)fis_work_block; 588 img = (struct fis_image_desc *)fis_work_block;
583 img += 2; // Skip reserved files 589 img += 2; // Skip reserved files
584 for (i = 2; i < block_size/sizeof(*img); i++, img++) { 590 for (i = 2; i < block_size/sizeof(*img); i++, img++) {
585 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { 591 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) {
586 if (!verify_action("Delete image '%s'", name)) { 592 if (!verify_action("Delete image '%s'", name)) {
587 return; 593 return;
616 fis_load(int argc, char *argv[]) 622 fis_load(int argc, char *argv[])
617 { 623 {
618 char *name; 624 char *name;
619 int i; 625 int i;
620 void *fis_addr; 626 void *fis_addr;
621 struct image_desc *img; 627 struct fis_image_desc *img;
622 bool slot_found; 628 bool slot_found;
623 629
624 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) 630 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name"))
625 { 631 {
626 fis_usage("invalid arguments"); 632 fis_usage("invalid arguments");
628 } 634 }
629 635
630 slot_found = false; 636 slot_found = false;
631 fis_addr = (void *)((unsigned long)flash_end - block_size); 637 fis_addr = (void *)((unsigned long)flash_end - block_size);
632 memcpy(fis_work_block, fis_addr, block_size); 638 memcpy(fis_work_block, fis_addr, block_size);
633 img = (struct image_desc *)fis_work_block; 639 img = (struct fis_image_desc *)fis_work_block;
634 for (i = 0; i < block_size/sizeof(*img); i++, img++) { 640 for (i = 0; i < block_size/sizeof(*img); i++, img++) {
635 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { 641 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) {
636 slot_found = true; 642 slot_found = true;
637 break; 643 break;
638 } 644 }
726 RedBoot_config_option("Boot script", 732 RedBoot_config_option("Boot script",
727 boot_script_data, 733 boot_script_data,
728 "boot_script", true, 734 "boot_script", true,
729 CONFIG_SCRIPT 735 CONFIG_SCRIPT
730 ); 736 );
731 RedBoot_config_option("Boot script timeout", 737 // Some preprocessor magic for building the [constant] prompt string
738 #define __cat(s1,c2,s3) s1 ## #c2 ## s3
739 #define _cat(s1,c2,s3) __cat(s1,c2,s3)
740 RedBoot_config_option(_cat("Boot script timeout (",
741 CYGNUM_REDBOOT_FLASH_SCRIPT_TIMEOUT_RESOLUTION,
742 "ms resolution)"),
732 boot_script_timeout, 743 boot_script_timeout,
733 "boot_script", true, 744 "boot_script", true,
734 CONFIG_INT 745 CONFIG_INT
735 ); 746 );
747 #undef __cat
748 #undef _cat
736 749
737 CYG_HAL_TABLE_BEGIN( __CONFIG_options_TAB__, RedBoot_config_options); 750 CYG_HAL_TABLE_BEGIN( __CONFIG_options_TAB__, RedBoot_config_options);
738 CYG_HAL_TABLE_END( __CONFIG_options_TAB_END__, RedBoot_config_options); 751 CYG_HAL_TABLE_END( __CONFIG_options_TAB_END__, RedBoot_config_options);
739 752
740 extern struct config_option __CONFIG_options_TAB__[], __CONFIG_options_TAB_END__[]; 753 extern struct config_option __CONFIG_options_TAB__[], __CONFIG_options_TAB_END__[];