⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 load.c

📁 基于ecos的redboot
💻 C
📖 第 1 页 / 共 2 页
字号:

void
redboot_getc_rewind(void)
{
    getc_info.bufp = getc_info.buf;
    getc_info.avail = getc_info.len;
}

#define MODE_TFTP   0
#define MODE_XMODEM xyzModem_xmodem  // 1
#define MODE_YMODEM xyzModem_ymodem  // 2
#define MODE_ZMODEM xyzModem_zmodem  // 3
#define MODE_DISK   4

void 
do_load(int argc, char *argv[])
{
    int res, num_options;
    int i, err, mode;
    bool verbose, raw;
    bool base_addr_set, mode_str_set;
    char *mode_str;
#ifdef CYGPKG_REDBOOT_NETWORKING
    struct sockaddr_in host;
    bool hostname_set;
    char *hostname;
#endif
#ifdef CYGPKG_COMPRESS_ZLIB
    bool decompress;
#endif
    unsigned long base = 0;
    unsigned long end = 0;
    char type[4];
    char *filename = 0;
    struct option_info opts[6];

#ifdef CYGPKG_REDBOOT_NETWORKING
    memset((char *)&host, 0, sizeof(host));
    host.sin_len = sizeof(host);
    host.sin_family = AF_INET;
    host.sin_addr = my_bootp_info.bp_siaddr;
    host.sin_port = 0;
#endif
#ifdef CYGPKG_REDBOOT_NETWORKING
    mode = MODE_TFTP;
#else
    mode = MODE_YMODEM;
#endif

    init_opts(&opts[0], 'v', false, OPTION_ARG_TYPE_FLG, 
              (void **)&verbose, 0, "verbose");
    init_opts(&opts[1], 'r', false, OPTION_ARG_TYPE_FLG, 
              (void **)&raw, 0, "load raw data");
    init_opts(&opts[2], 'b', true, OPTION_ARG_TYPE_NUM, 
              (void **)&base, (bool *)&base_addr_set, "load address");
    init_opts(&opts[3], 'm', true, OPTION_ARG_TYPE_STR, 
              (void **)&mode_str, (bool *)&mode_str_set, "download mode (TFTP, xyzMODEM, or disk)");
    num_options = 4;
#ifdef CYGPKG_REDBOOT_NETWORKING
    init_opts(&opts[4], 'h', true, OPTION_ARG_TYPE_STR, 
              (void **)&hostname, (bool *)&hostname_set, "host name (IP address)");
    num_options++;
#endif
#ifdef CYGPKG_COMPRESS_ZLIB
    init_opts(&opts[5], 'd', false, OPTION_ARG_TYPE_FLG, 
              (void **)&decompress, 0, "decompress");
    num_options++;
#endif

    if (!scan_opts(argc, argv, 1, opts, num_options, (void *)&filename, OPTION_ARG_TYPE_STR, "file name"))
    {
        return;
    }
#ifdef CYGPKG_REDBOOT_NETWORKING
    if (hostname_set) {
        if (!inet_aton(hostname, (in_addr_t *)&host)) {
            printf("Invalid IP address: %s\n", hostname);
            return;
        }
    }
#endif
    if (mode_str_set) {
        if (strncmpci(&mode_str[1], "modem", strlen(&mode_str[1])) == 0) {
            switch (tolower(mode_str[0])) {
            case 'x':
                mode = MODE_XMODEM;
                break;
            case 'y':
                mode = MODE_YMODEM;
                break;
            case 'z':
                mode = MODE_ZMODEM;
                break;
            default:
                printf("Invalid 'mode': %s\n", mode_str);
                return;
            }
            // When using a serial download type, override verbose
            // setting: spinner interferes with the protocol.
            verbose = false;
#ifdef CYGPKG_REDBOOT_DISK
	} else if (strcmpci(mode_str, "disk") == 0) {
            mode = MODE_DISK;
#endif
#ifdef CYGPKG_REDBOOT_NETWORKING
        } else if (strcmpci(mode_str, "tftp") == 0) {
            mode = MODE_TFTP;
            if (!have_net) {
                printf("TFTP mode requires a working network\n");
                return;
            }
#endif
        } else {
            printf("Invalid 'mode': %s\n", mode_str);
            return;
        }
    }
#if defined(CYGPKG_REDBOOT_NETWORKING) || defined(CYGPKG_REDBOOT_DISK)
    if ((mode == MODE_TFTP || mode == MODE_DISK) && !filename) {
        printf("File name missing\n");
        printf("usage: load %s\n", usage);
        return;
    }
#endif
#ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS
    if (base_addr_set &&
        ((base < (unsigned long)user_ram_start) ||
         (base > (unsigned long)user_ram_end))) {
        if (!verify_action("Specified address (%p) is not believed to be in RAM", (void*)base))
            return;
    }
#endif
    if (raw && !base_addr_set) {
        printf("Raw load requires a memory address\n");
        return;
    }
#ifdef CYGPKG_REDBOOT_NETWORKING
    if (mode == MODE_TFTP) {
        res = tftp_stream_open(filename, &host, TFTP_OCTET, &err);    
        if (res < 0) {
            printf("Can't load '%s': %s\n", filename, tftp_error(err));
            return;
        }
        redboot_getc_init(tftp_stream_read, verbose);
    }
#endif
#ifdef CYGPKG_REDBOOT_DISK
    else if (mode == MODE_DISK) {
        res = disk_stream_open(filename, &err);
        if (res < 0) {
            printf("Can't load '%s': %s\n", filename, disk_error(err));
            return;
        }
        redboot_getc_init(disk_stream_read, verbose);
    }
#endif
    else {
        res = xyzModem_stream_open(filename, mode, &err);
        if (res < 0) {
            printf("Can't load '%s': %s\n", filename, xyzModem_error(err));
            return;
        }
        // Suppress verbosity when using xyz modem download
        redboot_getc_init(xyzModem_stream_read, 0 && verbose);
    }
    if (raw) {
#ifdef CYGPKG_COMPRESS_ZLIB
        if (decompress) {
            _pipe_t load_pipe;
            _pipe_t* p = &load_pipe;
            unsigned char _buffer[CYGNUM_REDBOOT_LOAD_ZLIB_BUFFER];

            p->out_buf = (unsigned char*) base;
            p->out_size = 0;
            p->in_buf = _buffer;
                
            err = (*_dc_init)(p);

            while (0 == err) {
                p->in_avail = 0;
                for (i = 0; i < CYGNUM_REDBOOT_LOAD_ZLIB_BUFFER; i++) {
                    res = redboot_getc();
                    if (res < 0) break;
                    p->in_buf[p->in_avail++] = res;
                }
                if (0 == p->in_avail) break;

                err = (*_dc_inflate)(p);
            }

            // Free used resources, do final translation of
            // error value.
            err = (*_dc_close)(p, err);

            if (0 != err && p->msg) {
                printf("decompression error: %s\n", p->msg);
            }

            end = (unsigned long) base + p->out_size;
        } else // dangling block
#endif
        {
            unsigned char *mp = (unsigned char *)base;
            while ((res = redboot_getc()) >= 0) {
                *mp++ = res;
            }
            err = 0;
            end = (unsigned long) mp;
        }
        if (0 == err)
            printf("Raw file loaded %p-%p\n", (void *)base, (void *)end);
    } else {
        // Read initial header - to determine file [image] type
        for (i = 0;  i < sizeof(type);  i++) {
            if ((res = redboot_getc()) < 0) {
                err = getc_info.err;
                break;
            } 
            type[i] = res;
        }
        if (res >= 0) {
            redboot_getc_rewind();  // Restore header to stream
            // Treat data as some sort of executable image
            if (strncmp(&type[1], "ELF", 3) == 0) {
                end = load_elf_image(redboot_getc);
            } else if ((type[0] == 'S') &&
                       ((type[1] >= '0') && (type[1] <= '9'))) {
                end = load_srec_image(redboot_getc, base);
            } else {
                printf("Unrecognized image type: 0x%lx\n", *(unsigned long *)type);
            }
        }
    }

    switch (mode) {
#ifdef CYGPKG_REDBOOT_DISK
      case MODE_DISK:
        disk_stream_close(&err);
	break;
#endif
#ifdef CYGPKG_REDBOOT_NETWORKING
      case MODE_TFTP:
        tftp_stream_close(&err);
	break;
#endif
      default:
        xyzModem_stream_close(&err);
	break;
    }
    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -