? packages/redboot/current/include/memory_write.h ? packages/redboot/current/src/memory_write.c Index: packages/io/flash/current/src/flash.c =================================================================== RCS file: /cvs/ecos/ecos/packages/io/flash/current/src/flash.c,v retrieving revision 1.26 diff -u -r1.26 flash.c --- packages/io/flash/current/src/flash.c 20 Jun 2004 12:46:17 -0000 1.26 +++ packages/io/flash/current/src/flash.c 14 Jan 2006 00:38:16 -0000 @@ -87,8 +87,8 @@ { int err; - if (flash_info.init) return FLASH_ERR_OK; flash_info.pf = pf; // Do this before calling into the driver + if (flash_info.init) return FLASH_ERR_OK; if ((err = flash_hwr_init()) != FLASH_ERR_OK) { return err; } Index: packages/redboot/current/cdl/redboot.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/redboot/current/cdl/redboot.cdl,v retrieving revision 1.73 diff -u -r1.73 redboot.cdl --- packages/redboot/current/cdl/redboot.cdl 8 Sep 2005 12:14:29 -0000 1.73 +++ packages/redboot/current/cdl/redboot.cdl 14 Jan 2006 00:38:28 -0000 @@ -626,6 +600,21 @@ to manage images in FLASH memory. These images can be loaded into memory for execution or executed in place." compile -library=libextras.a flash.c + + cdl_option CYGSEM_REDBOOT_FLASH_LOADS { + display "Allow the load-command write to Flash." + flavor bool + default_value 1 + description " + Write images direct to Flash via the load command. + This option needs a flash-driver. + If the validate RAM option is active, then load get + the new option -f to control if the validation should + be done against the RAM or to the flash-space. + \"load -m xmodem\" will validate RAM and + \"load -f -m xmodem\" to Flash." + compile memory_write.c + } cdl_option CYGOPT_REDBOOT_FLASH_BYTEORDER { display "Byte order used to store info in flash." Index: packages/redboot/current/include/redboot.h =================================================================== RCS file: /cvs/ecos/ecos/packages/redboot/current/include/redboot.h,v retrieving revision 1.35 diff -u -r1.35 redboot.h --- packages/redboot/current/include/redboot.h 8 Sep 2005 12:14:31 -0000 1.35 +++ packages/redboot/current/include/redboot.h 14 Jan 2006 00:38:29 -0000 @@ -125,6 +125,10 @@ EXTERN unsigned char *fis_zlib_common_buffer; #endif +#ifdef CYGSEM_REDBOOT_FLASH_LOADS +EXTERN unsigned char *memory_write_flash_buffer; +#endif + #ifdef CYGSEM_REDBOOT_PLF_STARTUP EXTERN void cyg_plf_redboot_startup(void); #endif Index: packages/redboot/current/src/flash.c =================================================================== RCS file: /cvs/ecos/ecos/packages/redboot/current/src/flash.c,v retrieving revision 1.76 diff -u -r1.76 flash.c --- packages/redboot/current/src/flash.c 8 Sep 2005 12:14:33 -0000 1.76 +++ packages/redboot/current/src/flash.c 14 Jan 2006 00:38:38 -0000 @@ -101,20 +101,30 @@ static char fis_load_usage[] = #ifdef CYGPRI_REDBOOT_ZLIB_FLASH - "[-d] " + "[-d] " #endif - "[-b ] [-c] name"; +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + "[-o] " +#endif + "[-b ] [-c] name"; local_cmd_entry("load", +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + "Load image into RAM, or start it from flash", +#else "Load image from FLASH Image System [FIS] into RAM", +#endif fis_load_usage, fis_load, FIS_cmds ); local_cmd_entry("create", "Create an image", - "[-b ] [-l ] [-s ]\n" - " [-f ] [-e ] [-r ] [-n] ", + "[-b ] [-l ] [-s ]" +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + " [-o]" +#endif + "\n [-f ] [-e ] [-r ] [-n] ", fis_create, FIS_cmds ); @@ -739,10 +749,17 @@ bool length_set = false; bool img_size_set = false; bool no_copy = false; +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + bool load_addresses = false; +#endif void *err_addr; struct fis_image_desc *img = NULL; bool defaults_assumed; +#ifdef CYGSEM_REDBOOT_FLASH_LOADS struct option_info opts[7]; +#else + struct option_info opts[8]; +#endif bool prog_ok = true; init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, @@ -759,7 +776,13 @@ (void *)&img_size, (bool *)&img_size_set, "image size [actual data]"); init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, (void *)&no_copy, (bool *)0, "don't copy from RAM to FLASH, just update directory"); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + init_opts(&opts[7], 'o', false, OPTION_ARG_TYPE_FLG, + (void *)&load_addresses, (bool *)0, "take addresses from load tor flash"); + if (!scan_opts(argc, argv, 2, opts, 8, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) +#else if (!scan_opts(argc, argv, 2, opts, 7, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) +#endif { fis_usage("invalid arguments"); return; @@ -811,6 +834,21 @@ } } +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if (load_addresses){ + if (mem_addr_set || exec_addr_set || entry_addr_set || flash_addr_set || length_set || img_size_set || no_copy){ + fis_usage("-o don't accept any other option"); + return; + } + + no_copy = true; + flash_addr = load_address; + flash_addr_set = true; + length = load_address_end - load_address; + length_set = true; + } +#endif + if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) || !length_set || !name) { fis_usage("required parameter missing"); @@ -1034,6 +1072,9 @@ #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) || defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) bool decompress = false; #endif +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + bool run_in_flash = false; +#endif void *err_addr; init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, @@ -1046,6 +1087,11 @@ (void *)&decompress, 0, "decompress"); num_options++; #endif +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + init_opts(&opts[num_options], 'o', false, OPTION_ARG_TYPE_FLG, + (void *)&run_in_flash, 0, "run in the flash"); + num_options++; +#endif CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); @@ -1054,10 +1100,31 @@ fis_usage("invalid arguments"); return; } +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if (run_in_flash){ + if (mem_addr_set +#ifdef CYGPRI_REDBOOT_ZLIB_FLASH + || decompress +#endif + ){ + diag_printf("illegal option combination\n"); + return; + } + } +#endif if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) { diag_printf("No image '%s' found\n", name); return; } +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if (run_in_flash){ + load_address = img->flash_base; + load_address_end = load_address + img->data_length; + entry_address = img->entry_point; + + return; + } +#endif if (!mem_addr_set) { mem_addr = img->mem_base; } Index: packages/redboot/current/src/load.c =================================================================== RCS file: /cvs/ecos/ecos/packages/redboot/current/src/load.c,v retrieving revision 1.45 diff -u -r1.45 load.c --- packages/redboot/current/src/load.c 9 Sep 2005 13:26:03 -0000 1.45 +++ packages/redboot/current/src/load.c 14 Jan 2006 00:38:40 -0000 @@ -53,6 +53,8 @@ // //========================================================================== +//#define CYGSEM_REDBOOT_FLASH_LOADS + #include #include #ifdef CYGBLD_BUILD_REDBOOT_WITH_XYZMODEM @@ -74,6 +76,10 @@ #endif #include // assertion macros +#ifdef CYGSEM_REDBOOT_FLASH_LOADS +#include +#endif + static char usage[] = "[-r] [-v] " #ifdef CYGBLD_BUILD_REDBOOT_WITH_ZLIB "[-d] " @@ -85,6 +91,11 @@ #if CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS > 1 "[-c ] " #endif +#ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + "[-f] " +#endif +#endif "\n [-b ] "; // Exported CLI function @@ -119,6 +130,14 @@ #endif } getc_info; + +#ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS +bool do_flash_validate; +#endif +#endif + + typedef int (*getc_t)(void); // @@ -399,18 +411,34 @@ // Copy data into memory while (len-- > 0) { #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if ((!flash_valid_address(addr) && do_flash_validate || !valid_address(addr) && !do_flash_validate)){ +#else if (!valid_address(addr)) { +#endif redboot_getc_terminate(true); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if (do_flash_validate){ + diag_printf("*** Abort! ELF-data is not in flash, address: %p \n", (void*)addr); + } else { + diag_printf("*** Abort! ELF-data is not in RAM, address: %p \n", (void*)addr); + } +#else diag_printf("*** Abort! Attempt to load ELF data to address: %p which is not in RAM\n", (void*)addr); +#endif return 0; } #endif if ((ch = (*getc)()) < 0) { diag_printf(SHORT_DATA); redboot_getc_terminate(true); return 0; } +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write(addr, ch); + addr++; +#else *addr++ = ch; +#endif offset++; if ((unsigned long)(addr-addr_offset) > highest_address) { highest_address = (unsigned long)(addr - addr_offset); @@ -430,10 +458,7 @@ entry_address = ehdr.e_entry; } // nak everything to stop the transfer, since redboot // usually doesn't read all the way to the end of the // elf files. redboot_getc_terminate(true); if (addr_offset) diag_printf("Address offset = %p\n", (void *)addr_offset); diag_printf("Entry point: %p, address range: %p-%p\n", (void*)entry_address, (void *)load_address, (void *)load_address_end); @@ -531,11 +556,23 @@ lowest_address = (unsigned long)(addr - addr_offset); } #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if ((!flash_valid_address(addr) && do_flash_validate || !valid_address(addr) && !do_flash_validate)){ +#else if (!valid_address(addr)) { - // Only if there is no need to stop the download before printing - // output can we ask confirmation questions. +#endif + // Only if there is no need to stop the download before printing + // output can we ask confirmation questions. redboot_getc_terminate(true); - diag_printf("*** Abort! Attempt to load S-record to address: %p, which is not in RAM\n",(void*)addr); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if (do_flash_validate){ + diag_printf("*** Abort! S-Rec data is not in flash, address: %p \n", (void*)addr); + } else { + diag_printf("*** Abort! S-Rec data is not in RAM, address: %p \n", (void*)addr); + } +#else + diag_printf("*** Abort! Attempt to load S-record to address: %p, which is not in RAM\n",(void*)addr); +#endif return 0; } #endif @@ -543,7 +580,12 @@ offset += count; while (count-- > 0) { val = _hex2(getc, 1, &sum); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write(addr, val); + addr++; +#else *addr++ = val; +#endif } cksum = _hex2(getc, 1, 0); offset += 1; @@ -631,6 +673,11 @@ #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS bool spillover_ok = false; #endif +#ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + do_flash_validate = false; +#endif +#endif #ifdef CYGPKG_REDBOOT_NETWORKING memset((char *)&host, 0, sizeof(host)); @@ -667,6 +714,13 @@ (void *)&decompress, 0, "decompress"); num_options++; #endif +#ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + init_opts(&opts[num_options], 'f', false, OPTION_ARG_TYPE_FLG, + (void *)&do_flash_validate, 0, "flash validate"); + num_options++; +#endif +#endif CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); @@ -689,7 +743,7 @@ } } if (port_set) - host.sin_port = port; + host.sin_port = port; #endif if (chan >= CYGNUM_HAL_VIRTUAL_VECTOR_NUM_CHANNELS) { diag_printf("Invalid I/O channel: %d\n", chan); @@ -734,10 +788,10 @@ #endif #ifdef CYGPKG_REDBOOT_FILEIO // Make file I/O default if mounted - if (fileio_mounted) { - which = "file"; - io = &fileio_io; - } + if (fileio_mounted) { + which = "file"; + io = &fileio_io; + } #endif if (!io) { #ifdef CYGBLD_BUILD_REDBOOT_WITH_XYZMODEM @@ -752,8 +806,13 @@ diag_printf("Using default protocol (%s)\n", which); } #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if ((!flash_valid_address((cyg_uint8 *) base) && do_flash_validate || !valid_address((cyg_uint8 *) base) && !do_flash_validate) && base_addr_set){ + if (!verify_action("Specified address (%p) is not believed to be right", (void*)base)) +#else if (base_addr_set && !valid_address((unsigned char *)base)) { if (!verify_action("Specified address (%p) is not believed to be in RAM", (void*)base)) +#endif return; spillover_ok = true; } @@ -777,20 +836,44 @@ if (raw) { unsigned char *mp = (unsigned char *)base; err = 0; +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write_init(); +#endif while ((res = redboot_getc()) >= 0) { #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if ((!flash_valid_address(mp) && do_flash_validate || !valid_address(mp) && !do_flash_validate) && !spillover_ok){ +#else if (!valid_address(mp) && !spillover_ok) { +#endif // Only if there is no need to stop the download // before printing output can we ask confirmation // questions. redboot_getc_terminate(true); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + if (do_flash_validate){ + diag_printf("*** Abort! RAW data out of flash at %p\n",(void*)mp); + } else { + diag_printf("*** Abort! RAW data out of RAM at %p\n",(void*)mp); + } +#else diag_printf("*** Abort! RAW data spills over limit of user RAM at %p\n",(void*)mp); +#endif err = -1; break; } #endif + +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write(mp, res); + mp++; +#else *mp++ = res; +#endif } +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write_fini(); +#endif end = (unsigned long) mp; // Save load base/top @@ -815,10 +898,22 @@ redboot_getc_rewind(); // Restore header to stream // Treat data as some sort of executable image if (strncmp(&type[1], "ELF", 3) == 0) { +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write_init(); +#endif end = load_elf_image(redboot_getc, base); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write_fini(); +#endif } else if ((type[0] == 'S') && ((type[1] >= '0') && (type[1] <= '9'))) { - end = load_srec_image(redboot_getc, base); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write_init(); +#endif + end = load_srec_image(redboot_getc, base); +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write_fini(); +#endif } else { redboot_getc_terminate(true); diag_printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type); Index: packages/redboot/current/src/main.c =================================================================== RCS file: /cvs/ecos/ecos/packages/redboot/current/src/main.c,v retrieving revision 1.63 diff -u -r1.63 main.c --- packages/redboot/current/src/main.c 7 Jun 2005 18:55:52 -0000 1.63 +++ packages/redboot/current/src/main.c 14 Jan 2006 00:38:42 -0000 @@ -65,6 +65,10 @@ #include // Logical driver interfaces #endif +#ifdef CYGSEM_REDBOOT_FLASH_LOADS +#include //For flash_get_block_info(); +#endif + #include #include // assertion macros #include @@ -308,6 +312,11 @@ workspace_end -= CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE; #endif +#ifdef CYGSEM_REDBOOT_FLASH_LOADS + memory_write_flash_buffer = + workspace_end -= memory_write_init(); /* Returns flash-segment size */ +#endif + #ifdef CYGFUN_REDBOOT_BOOT_SCRIPT script_timeout = CYGNUM_REDBOOT_BOOT_SCRIPT_DEFAULT_TIMEOUT; #endif @@ -362,6 +371,7 @@ } #endif + CYG_ASSERT(workspace_start < workspace_end, "ERROR: negative workspace size!"); while (true) { if (prompt) { diag_printf("RedBoot> ");