Mercurial > ecos
comparison packages/redboot/current/src/load.c @ 117:bd1a71e3e476 ecos-sw-2000-08-25
Merge from eCos master repository on 2000-08-25-19:22:58-BST
| author | jlarmour |
|---|---|
| date | Fri, 25 Aug 2000 19:17:22 +0000 |
| parents | 6ed91473a1cd |
| children | 0ec04793409a |
comparison
equal
deleted
inserted
replaced
| 116:a0f9581a3a09 | 117:bd1a71e3e476 |
|---|---|
| 46 #include <redboot.h> | 46 #include <redboot.h> |
| 47 | 47 |
| 48 // Exported CLI function | 48 // Exported CLI function |
| 49 RedBoot_cmd("load", | 49 RedBoot_cmd("load", |
| 50 "Load a file", | 50 "Load a file", |
| 51 "[-raw] [-b <mem_addr>]]", | 51 "[-v] [-r] [-b <mem_addr>] <file_name>", |
| 52 do_load | 52 do_load |
| 53 ); | 53 ); |
| 54 | 54 |
| 55 static void | 55 static void |
| 56 load_elf_image(int (*getc)(void)) | 56 load_elf_image(int (*getc)(void)) |
| 111 | 111 |
| 112 while ((c = (*getc)()) > 0) { | 112 while ((c = (*getc)()) > 0) { |
| 113 lp = line; len = 0; | 113 lp = line; len = 0; |
| 114 // Start of line | 114 // Start of line |
| 115 if (c != 'S') { | 115 if (c != 'S') { |
| 116 printf("Invalid S-record at offset 0x%lx, input: %c\n", | 116 printf("Invalid S-record at offset %p, input: %c\n", |
| 117 (unsigned long)offset, c); | 117 (void *)offset, c); |
| 118 return; | 118 return; |
| 119 } | 119 } |
| 120 type = (*getc)(); | 120 type = (*getc)(); |
| 121 offset += 2; | 121 offset += 2; |
| 122 sum = 0; | 122 sum = 0; |
| 123 if ((count = _hex2(getc, 1, &sum)) < 0) { | 123 if ((count = _hex2(getc, 1, &sum)) < 0) { |
| 124 printf("Bad S-record count at offset 0x%lx\n", (unsigned long)offset); | 124 printf("Bad S-record count at offset %p\n", (void *)offset); |
| 125 return; | 125 return; |
| 126 } | 126 } |
| 127 offset += 1; | 127 offset += 1; |
| 128 switch (type) { | 128 switch (type) { |
| 129 case '0': | 129 case '0': |
| 134 base_addr = addr = (unsigned char *)_hex2(getc, (type-'1'+2), &sum); | 134 base_addr = addr = (unsigned char *)_hex2(getc, (type-'1'+2), &sum); |
| 135 offset += (type-'1'+2); | 135 offset += (type-'1'+2); |
| 136 if (first_addr) { | 136 if (first_addr) { |
| 137 if (base) { | 137 if (base) { |
| 138 addr_offset = (unsigned long)base - (unsigned long)addr; | 138 addr_offset = (unsigned long)base - (unsigned long)addr; |
| 139 printf("Address offset = %lx\n", (unsigned long)addr_offset); | 139 printf("Address offset = %p\n", (void *)addr_offset); |
| 140 } else { | 140 } else { |
| 141 addr_offset = 0; | 141 addr_offset = 0; |
| 142 } | 142 } |
| 143 first_addr = false; | 143 first_addr = false; |
| 144 } | 144 } |
| 211 if (getc_info.verbose) printf("\n"); | 211 if (getc_info.verbose) printf("\n"); |
| 212 return -1; | 212 return -1; |
| 213 } | 213 } |
| 214 getc_info.bufp = getc_info.buf; | 214 getc_info.bufp = getc_info.buf; |
| 215 getc_info.len = (*getc_info.fun)(getc_info.bufp, BUF_SIZE, &getc_info.err); | 215 getc_info.len = (*getc_info.fun)(getc_info.bufp, BUF_SIZE, &getc_info.err); |
| 216 if ((getc_info.avail = getc_info.len) < 0) { | 216 if ((getc_info.avail = getc_info.len) <= 0) { |
| 217 if (getc_info.verbose) printf("\n"); | 217 if (getc_info.verbose) printf("\n"); |
| 218 return -1; | 218 return -1; |
| 219 } | 219 } |
| 220 } | 220 } |
| 221 getc_info.avail--; | 221 getc_info.avail--; |
| 243 #define MODE_ZMODEM 1 | 243 #define MODE_ZMODEM 1 |
| 244 | 244 |
| 245 void | 245 void |
| 246 do_load(int argc, char *argv[]) | 246 do_load(int argc, char *argv[]) |
| 247 { | 247 { |
| 248 int i, res, err; | 248 int i, res, err, num_options; |
| 249 int mode; | 249 int mode; |
| 250 int verbose = 0; | 250 bool verbose, raw; |
| 251 bool raw = false; | 251 bool base_addr_set, mode_str_set; |
| 252 bool base_addr_set = false; | 252 char *mode_str; |
| 253 #ifdef CYGPKG_REDBOOT_NETWORKING | 253 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 254 struct sockaddr_in host; | 254 struct sockaddr_in host; |
| 255 bool hostname_set; | |
| 256 char *hostname; | |
| 255 #endif | 257 #endif |
| 256 unsigned long base = 0; | 258 unsigned long base = 0; |
| 257 char type[4]; | 259 char type[4]; |
| 258 char *filename = 0; | 260 char *filename = 0; |
| 259 char *usage = "usage: load <file_name> [-r] [-v] [-h <host>] [-m {TFTP | ZMODEM}] [-b <base_address>]\n"; | 261 char *usage = "usage: load <file_name> [-r] [-v] [-h <host>] [-m {TFTP | ZMODEM}] [-b <base_address>]\n"; |
| 262 struct option_info opts[5]; | |
| 260 | 263 |
| 261 #ifdef CYGPKG_REDBOOT_NETWORKING | 264 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 262 memset((char *)&host, 0, sizeof(host)); | 265 memset((char *)&host, 0, sizeof(host)); |
| 263 host.sin_len = sizeof(host); | 266 host.sin_len = sizeof(host); |
| 264 host.sin_family = AF_INET; | 267 host.sin_family = AF_INET; |
| 268 #ifdef CYGPKG_REDBOOT_NETWORKING | 271 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 269 mode = MODE_TFTP; | 272 mode = MODE_TFTP; |
| 270 #else | 273 #else |
| 271 mode = MODE_ZMODEM; | 274 mode = MODE_ZMODEM; |
| 272 #endif | 275 #endif |
| 273 for (i = 1; i < argc; i++) { | 276 |
| 274 if (argv[i][0] == '-') { | 277 init_opts(&opts[0], 'v', false, OPTION_ARG_TYPE_FLG, |
| 275 // Option | 278 (void **)&verbose, 0, "verbose"); |
| 276 switch (argv[i][1]) { | 279 init_opts(&opts[1], 'r', false, OPTION_ARG_TYPE_FLG, |
| 277 case 'v': | 280 (void **)&raw, 0, "load raw data"); |
| 278 verbose++; | 281 init_opts(&opts[2], 'b', true, OPTION_ARG_TYPE_NUM, |
| 279 break; | 282 (void **)&base, (bool *)&base_addr_set, "load address"); |
| 280 case 'r': | 283 init_opts(&opts[3], 'm', true, OPTION_ARG_TYPE_STR, |
| 281 raw = true; | 284 (void **)&mode_str, (bool *)&mode_str_set, "download mode (TFTP or ZMODEM)"); |
| 282 break; | 285 num_options = 4; |
| 283 #ifdef CYGPKG_REDBOOT_NETWORKING | 286 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 284 case 'h': | 287 init_opts(&opts[4], 'h', true, OPTION_ARG_TYPE_STR, |
| 285 if ((i+1) >= argc) { | 288 (void **)&hostname, (bool *)&hostname_set, "host name (IP address)"); |
| 286 printf("Invalid option: %s\n", argv[i]); | 289 num_options = 5; |
| 287 printf(usage); | 290 #endif |
| 288 return; | 291 if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&filename, OPTION_ARG_TYPE_STR, "file name")) |
| 289 } | 292 { |
| 290 if (!inet_aton(argv[i+1], (in_addr_t *)&host)) { | 293 return; |
| 291 printf("Invalid IP address: %s\n", argv[i+1]); | 294 } |
| 292 return; | 295 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 293 } | 296 if (hostname_set) { |
| 294 i++; // Skip parameter | 297 if (!inet_aton(hostname, (in_addr_t *)&host)) { |
| 295 break; | 298 printf("Invalid IP address: %s\n", hostname); |
| 296 #endif | 299 return; |
| 297 case 'm': | 300 } |
| 298 if ((i+1) >= argc) { | 301 } |
| 299 printf("Invalid option: %s\n", argv[i]); | 302 #endif |
| 300 printf(usage); | 303 if (mode_str_set) { |
| 301 return; | 304 if (strcmpci(mode_str, "zmodem") == 0) { |
| 302 } | 305 mode = MODE_ZMODEM; |
| 303 if (strcmpci(argv[i+1], "zmodem") == 0) { | 306 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 304 mode = MODE_ZMODEM; | 307 } else if (strcmpci(mode_str, "tftp") == 0) { |
| 305 #ifdef CYGPKG_REDBOOT_NETWORKING | 308 mode = MODE_TFTP; |
| 306 } else if (strcmpci(argv[i+1], "tftp") == 0) { | 309 if (!have_net) { |
| 307 mode = MODE_TFTP; | 310 printf("TFTP mode requires a working network\n"); |
| 308 if (!have_net) { | |
| 309 printf("TFTP mode requires a working network\n"); | |
| 310 return; | |
| 311 } | |
| 312 #endif | |
| 313 } else { | |
| 314 printf("Invalid 'mode': %s\n", argv[i+1]); | |
| 315 return; | |
| 316 } | |
| 317 i++; // Skip parameter | |
| 318 break; | |
| 319 case 'b': | |
| 320 if ((i+1) >= argc) { | |
| 321 printf("Invalid option: %s\n", argv[i]); | |
| 322 printf(usage); | |
| 323 return; | |
| 324 } | |
| 325 if (!parse_num(argv[i+1], &base, 0, 0)) { | |
| 326 printf("Invalid offset: %s\n", argv[i+1]); | |
| 327 printf(usage); | |
| 328 return; | |
| 329 } | |
| 330 base_addr_set = true; | |
| 331 i++; // Skip parameter | |
| 332 break; | |
| 333 default: | |
| 334 printf("Invalid option: %s\n", argv[i]); | |
| 335 printf(usage); | |
| 336 return; | 311 return; |
| 337 } | 312 } |
| 313 #endif | |
| 338 } else { | 314 } else { |
| 339 if (filename) { | 315 printf("Invalid 'mode': %s\n", mode_str); |
| 340 printf("Only one file name allowed\n"); | 316 return; |
| 341 printf(usage); | |
| 342 return; | |
| 343 } | |
| 344 filename = argv[i]; | |
| 345 } | 317 } |
| 346 } | 318 } |
| 347 if ((mode == MODE_TFTP) && !filename) { | 319 if ((mode == MODE_TFTP) && !filename) { |
| 348 printf("File name missing\n"); | 320 printf("File name missing\n"); |
| 349 printf(usage); | 321 printf(usage); |
