comparison packages/redboot/current/src/load.c @ 156:b939e9cada46

Merge from eCos master repository on 2001-03-29-21:44:39-BST
author jlarmour
date Fri, 06 Apr 2001 17:20:13 +0000
parents e2d866e32dac
children b65ec671dd4c
comparison
equal deleted inserted replaced
155:70a4cc6d69d2 156:b939e9cada46
44 //========================================================================== 44 //==========================================================================
45 45
46 #include <redboot.h> 46 #include <redboot.h>
47 #include <xyzModem.h> 47 #include <xyzModem.h>
48 48
49 #ifdef CYGPKG_COMPRESS_ZLIB
50 static unsigned char _buffer[CYGNUM_REDBOOT_LOAD_ZLIB_BUFFER];
51 static _pipe_t load_pipe;
52 #endif
53
49 // Buffer used by redboot_getc 54 // Buffer used by redboot_getc
50 getc_info_t getc_info; 55 getc_info_t getc_info;
51 56
52 static char usage[] = "[-r] [-v] [-h <host>] [-m {TFTP | xyzMODEM}]\n" 57 static char usage[] = "[-r] [-v] "
58 #ifdef CYGPKG_COMPRESS_ZLIB
59 "[-d] "
60 #endif
61 "[-h <host>] [-m {TFTP | xyzMODEM}]\n"
53 " [-b <base_address>] <file_name>"; 62 " [-b <base_address>] <file_name>";
54 63
55 // Exported CLI function 64 // Exported CLI function
56 RedBoot_cmd("load", 65 RedBoot_cmd("load",
57 "Load a file", 66 "Load a file",
58 usage, 67 usage,
59 do_load 68 do_load
60 ); 69 );
61 70
62 static void 71 static unsigned long
63 load_elf_image(int (*getc)(void)) 72 load_elf_image(int (*getc)(void))
64 { 73 {
65 printf("ELF images not supported\n"); 74 printf("ELF images not supported\n");
75 return 0;
66 } 76 }
67 77
68 // 78 //
69 // Scan a string of hex bytes and update the checksum 79 // Scan a string of hex bytes and update the checksum
70 // 80 //
100 // pieces of data, they will end up relocated in the same fashion. 110 // pieces of data, they will end up relocated in the same fashion.
101 // Because of this, "base" probably only makes sense for a set of 111 // Because of this, "base" probably only makes sense for a set of
102 // data which has only one section, e.g. a ROM image. 112 // data which has only one section, e.g. a ROM image.
103 // 113 //
104 #define MAX_LINE 80 114 #define MAX_LINE 80
105 static void 115 static unsigned long
106 load_srec_image(int (*getc)(void), unsigned long base) 116 load_srec_image(int (*getc)(void), unsigned long base)
107 { 117 {
108 char line[MAX_LINE]; 118 char line[MAX_LINE];
109 char *lp; 119 char *lp;
110 int c, len; 120 int c, len;
120 lp = line; len = 0; 130 lp = line; len = 0;
121 // Start of line 131 // Start of line
122 if (c != 'S') { 132 if (c != 'S') {
123 printf("Invalid S-record at offset %p, input: %c\n", 133 printf("Invalid S-record at offset %p, input: %c\n",
124 (void *)offset, c); 134 (void *)offset, c);
125 return; 135 return 0;
126 } 136 }
127 type = (*getc)(); 137 type = (*getc)();
128 offset += 2; 138 offset += 2;
129 sum = 0; 139 sum = 0;
130 if ((count = _hex2(getc, 1, &sum)) < 0) { 140 if ((count = _hex2(getc, 1, &sum)) < 0) {
131 printf("Bad S-record count at offset %p\n", (void *)offset); 141 printf("Bad S-record count at offset %p\n", (void *)offset);
132 return; 142 return 0;
133 } 143 }
134 offset += 1; 144 offset += 1;
135 switch (type) { 145 switch (type) {
136 case '0': 146 case '0':
137 break; 147 break;
151 } 161 }
152 addr += addr_offset; 162 addr += addr_offset;
153 if ((unsigned long)(addr-addr_offset) < lowest_address) { 163 if ((unsigned long)(addr-addr_offset) < lowest_address) {
154 lowest_address = (unsigned long)(addr - addr_offset); 164 lowest_address = (unsigned long)(addr - addr_offset);
155 } 165 }
156 if ((addr < ram_start) || (addr > ram_end)) { 166 if ((addr < user_ram_start) || (addr > user_ram_end)) {
157 printf("Attempt to load S-record data to address: %p [not in RAM]\n", (void*)addr); 167 printf("Attempt to load S-record data to address: %p [not in RAM]\n", (void*)addr);
158 return; 168 return 0;
159 } 169 }
160 count -= ((type-'1'+2)+1); 170 count -= ((type-'1'+2)+1);
161 offset += count; 171 offset += count;
162 while (count-- > 0) { 172 while (count-- > 0) {
163 val = _hex2(getc, 1, &sum); 173 val = _hex2(getc, 1, &sum);
168 sum = sum & 0xFF; 178 sum = sum & 0xFF;
169 cksum = (~cksum & 0xFF); 179 cksum = (~cksum & 0xFF);
170 if (cksum != sum) { 180 if (cksum != sum) {
171 printf("*** Warning! Checksum failure - Addr: %lx, %02lX <> %02lX\n", 181 printf("*** Warning! Checksum failure - Addr: %lx, %02lX <> %02lX\n",
172 (unsigned long)base_addr, sum, cksum); 182 (unsigned long)base_addr, sum, cksum);
173 return; 183 return 0;
174 } 184 }
175 if ((unsigned long)(addr-addr_offset) > highest_address) { 185 if ((unsigned long)(addr-addr_offset) > highest_address) {
176 highest_address = (unsigned long)(addr - addr_offset); 186 highest_address = (unsigned long)(addr - addr_offset);
177 } 187 }
178 break; 188 break;
183 offset += ('9'-type+2); 193 offset += ('9'-type+2);
184 entry_address = (unsigned long *)addr; 194 entry_address = (unsigned long *)addr;
185 printf("Entry point: %p, address range: %p-%p\n", 195 printf("Entry point: %p, address range: %p-%p\n",
186 (void*)entry_address, (void *)lowest_address, (void *)highest_address); 196 (void*)entry_address, (void *)lowest_address, (void *)highest_address);
187 while ((c = (*getc)()) > 0) ; // Swallow rest of data 197 while ((c = (*getc)()) > 0) ; // Swallow rest of data
188 return; 198 return highest_address;
189 default: 199 default:
190 printf("Invalid S-record at offset 0x%lx, type: %x\n", 200 printf("Invalid S-record at offset 0x%lx, type: %x\n",
191 (unsigned long)offset, type); 201 (unsigned long)offset, type);
192 return; 202 return 0;
193 } 203 }
194 while ((c = (*getc)()) != '\n') offset++; 204 while ((c = (*getc)()) != '\n') offset++;
195 } 205 }
206 return 0;
196 } 207 }
197 208
198 209
199 int 210 int
200 redboot_getc(void) 211 redboot_getc(void)
259 #ifdef CYGPKG_REDBOOT_NETWORKING 270 #ifdef CYGPKG_REDBOOT_NETWORKING
260 struct sockaddr_in host; 271 struct sockaddr_in host;
261 bool hostname_set; 272 bool hostname_set;
262 char *hostname; 273 char *hostname;
263 #endif 274 #endif
275 #ifdef CYGPKG_COMPRESS_ZLIB
276 bool decompress;
277 #endif
264 unsigned long base = 0; 278 unsigned long base = 0;
279 unsigned long end = 0;
265 char type[4]; 280 char type[4];
266 char *filename = 0; 281 char *filename = 0;
267 struct option_info opts[5]; 282 struct option_info opts[6];
268 283
269 #ifdef CYGPKG_REDBOOT_NETWORKING 284 #ifdef CYGPKG_REDBOOT_NETWORKING
270 memset((char *)&host, 0, sizeof(host)); 285 memset((char *)&host, 0, sizeof(host));
271 host.sin_len = sizeof(host); 286 host.sin_len = sizeof(host);
272 host.sin_family = AF_INET; 287 host.sin_family = AF_INET;
289 (void **)&mode_str, (bool *)&mode_str_set, "download mode (TFTP or xyzMODEM)"); 304 (void **)&mode_str, (bool *)&mode_str_set, "download mode (TFTP or xyzMODEM)");
290 num_options = 4; 305 num_options = 4;
291 #ifdef CYGPKG_REDBOOT_NETWORKING 306 #ifdef CYGPKG_REDBOOT_NETWORKING
292 init_opts(&opts[4], 'h', true, OPTION_ARG_TYPE_STR, 307 init_opts(&opts[4], 'h', true, OPTION_ARG_TYPE_STR,
293 (void **)&hostname, (bool *)&hostname_set, "host name (IP address)"); 308 (void **)&hostname, (bool *)&hostname_set, "host name (IP address)");
294 num_options = 5; 309 num_options++;
295 #endif 310 #endif
311 #ifdef CYGPKG_COMPRESS_ZLIB
312 init_opts(&opts[5], 'd', false, OPTION_ARG_TYPE_FLG,
313 (void **)&decompress, 0, "decompress");
314 num_options++;
315 #endif
316
296 if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&filename, OPTION_ARG_TYPE_STR, "file name")) 317 if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&filename, OPTION_ARG_TYPE_STR, "file name"))
297 { 318 {
298 return; 319 return;
299 } 320 }
300 #ifdef CYGPKG_REDBOOT_NETWORKING 321 #ifdef CYGPKG_REDBOOT_NETWORKING
338 printf("File name missing\n"); 359 printf("File name missing\n");
339 printf("usage: load %s\n", usage); 360 printf("usage: load %s\n", usage);
340 return; 361 return;
341 } 362 }
342 if (base_addr_set && 363 if (base_addr_set &&
343 ((base < (unsigned long)ram_start) || 364 ((base < (unsigned long)user_ram_start) ||
344 (base > (unsigned long)ram_end))) { 365 (base > (unsigned long)user_ram_end))) {
345 printf("Specified address (%p) is not in RAM.\n", (void*)base); 366 printf("Specified address (%p) is not in RAM.\n", (void*)base);
346 return; 367 return;
347 } 368 }
348 #ifdef CYGPKG_REDBOOT_NETWORKING 369 #ifdef CYGPKG_REDBOOT_NETWORKING
349 if (mode == MODE_TFTP) { 370 if (mode == MODE_TFTP) {
376 redboot_getc_rewind(); // Restore header to stream 397 redboot_getc_rewind(); // Restore header to stream
377 if (raw) { 398 if (raw) {
378 if (!base_addr_set) { 399 if (!base_addr_set) {
379 printf("Raw load requires a memory address\n"); 400 printf("Raw load requires a memory address\n");
380 } else { 401 } else {
381 unsigned char *mp = (unsigned char *)base; 402 #ifdef CYGPKG_COMPRESS_ZLIB
382 while ((res = redboot_getc()) >= 0) { 403 if (decompress) {
383 *mp++ = res; 404 _pipe_t* p = &load_pipe;
405 p->out_buf = (unsigned char*) base;
406 p->out_size = 0;
407 p->in_buf = _buffer;
408
409 err = (*_dc_init)(p);
410
411 while (0 == err) {
412 p->in_avail = 0;
413 for (i = 0; i < CYGNUM_REDBOOT_LOAD_ZLIB_BUFFER; i++) {
414 res = redboot_getc();
415 if (res < 0) break;
416 p->in_buf[p->in_avail++] = res;
417 }
418 if (0 == p->in_avail) break;
419
420 err = (*_dc_inflate)(p);
421 }
422
423 // Free used resources, do final translation of
424 // error value.
425 err = (*_dc_close)(p, err);
426
427 if (0 != err && p->msg)
428 printf("zlib: %s\n", p->msg);
429
430 end = (unsigned long) base + p->out_size;
431 } else // dangling block
432 #endif
433 {
434 unsigned char *mp = (unsigned char *)base;
435 while ((res = redboot_getc()) >= 0) {
436 *mp++ = res;
437 }
438 err = 0;
439 end = (unsigned long) mp;
384 } 440 }
385 printf("Raw file loaded %p-%p\n", (void *)base, (void *)mp); 441 if (0 == err)
442 printf("Raw file loaded %p-%p\n", (void *)base, (void *)end);
386 } 443 }
387 } else { 444 } else {
388 // Treat data as some sort of executable image 445 // Treat data as some sort of executable image
389 if (strncmp(&type[1], "ELF", 3) == 0) { 446 if (strncmp(&type[1], "ELF", 3) == 0) {
390 load_elf_image(redboot_getc); 447 end = load_elf_image(redboot_getc);
391 } else if ((type[0] == 'S') && 448 } else if ((type[0] == 'S') &&
392 ((type[1] >= '0') && (type[1] <= '9'))) { 449 ((type[1] >= '0') && (type[1] <= '9'))) {
393 load_srec_image(redboot_getc, base); 450 end = load_srec_image(redboot_getc, base);
394 } else { 451 } else {
395 printf("Unrecognized image type: %lx\n", *(unsigned long *)type); 452 printf("Unrecognized image type: %lx\n", *(unsigned long *)type);
396 } 453 }
397 } 454 }
398 } 455 }