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

📄 cmd_load.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif  /* CFG_CMD_LOADS */#if (CONFIG_COMMANDS & CFG_CMD_LOADB)  /* loadb command (load binary) included */#define XON_CHAR        17#define XOFF_CHAR       19#define START_CHAR      0x01#define ETX_CHAR    0x03#define END_CHAR        0x0D#define SPACE           0x20#define K_ESCAPE        0x23#define SEND_TYPE       'S'#define DATA_TYPE       'D'#define ACK_TYPE        'Y'#define NACK_TYPE       'N'#define BREAK_TYPE      'B'#define tochar(x) ((char) (((x) + SPACE) & 0xff))#define untochar(x) ((int) (((x) - SPACE) & 0xff))extern int os_data_count;extern int os_data_header[8];static void set_kerm_bin_mode(unsigned long *);static int k_recv(void);static ulong load_serial_bin (ulong offset);char his_eol;        /* character he needs at end of packet */int  his_pad_count;  /* number of pad chars he needs */char his_pad_char;   /* pad chars he needs */char his_quote;      /* quote chars he'll use */int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){    ulong offset = 0;    ulong addr;    int load_baudrate, current_baudrate;    int rcode = 0;    char *s;    /* pre-set offset from CFG_LOAD_ADDR */    offset = CFG_LOAD_ADDR;    /* pre-set offset from $loadaddr */    if ((s = getenv("loadaddr")) != NULL) {        offset = simple_strtoul(s, NULL, 16);    }    load_baudrate = current_baudrate = gd->baudrate;    if (argc >= 2) {        offset = simple_strtoul(argv[1], NULL, 16);    }    if (argc == 3) {        load_baudrate = (int)simple_strtoul(argv[2], NULL, 10);        /* default to current baudrate */        if (load_baudrate == 0)            load_baudrate = current_baudrate;    }    if (load_baudrate != current_baudrate) {        printf ("## Switch baudrate to %d bps and press ENTER ...\n",            load_baudrate);        udelay(50000);        gd->baudrate = load_baudrate;        serial_setbrg ();        udelay(50000);        for (;;) {            if (getc() == '\r')                break;        }    }    /* support xmodem, www.arm9.net */    if (strcmp(argv[0],"loadx")==0) {        printf ("## Ready for binary (xmodem) download "            "to 0x%08lX at %d bps...\n",            offset,            load_baudrate);        addr = load_serial_xmodem (offset);    } else if (strcmp(argv[0],"loady")==0) {        printf ("## Ready for binary (ymodem) download "            "to 0x%08lX at %d bps...\n",            offset,            load_baudrate);        addr = load_serial_ymodem (offset);    } else {        printf ("## Ready for binary (kermit) download "            "to 0x%08lX at %d bps...\n",            offset,            load_baudrate);        addr = load_serial_bin (offset);        if (addr == ~0) {            load_addr = 0;            printf ("## Binary (kermit) download aborted\n");            rcode = 1;        } else {            printf ("## Start Addr      = 0x%08lX\n", addr);            load_addr = addr;        }    }    if (load_baudrate != current_baudrate) {        printf ("## Switch baudrate to %d bps and press ESC ...\n",            current_baudrate);        udelay (50000);        gd->baudrate = current_baudrate;        serial_setbrg ();        udelay (50000);        for (;;) {            if (getc() == 0x1B) /* ESC */                break;        }    }#ifdef CONFIG_AUTOSCRIPT    if (load_addr) {        char *s;        if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {            printf("Running autoscript at addr 0x%08lX ...\n", load_addr);            rcode = autoscript (load_addr);        }    }#endif    return rcode;}static ulong load_serial_bin (ulong offset){    int size, i;    char buf[32];    set_kerm_bin_mode ((ulong *) offset);    size = k_recv ();    /*     * Gather any trailing characters (for instance, the ^D which     * is sent by 'cu' after sending a file), and give the     * box some time (100 * 1 ms)     */    for (i=0; i<100; ++i) {        if (tstc()) {            (void) getc();        }        udelay(1000);    }    flush_cache (offset, size);    printf("## Total Size      = 0x%08x = %d Bytes\n", size, size);    sprintf(buf, "%X", size);    setenv("filesize", buf);    return offset;}void send_pad (void){    int count = his_pad_count;    while (count-- > 0)        putc (his_pad_char);}/* converts escaped kermit char to binary char */char ktrans (char in){    if ((in & 0x60) == 0x40) {        return (char) (in & ~0x40);    } else if ((in & 0x7f) == 0x3f) {        return (char) (in | 0x40);    } else        return in;}int chk1 (char *buffer){    int total = 0;    while (*buffer) {        total += *buffer++;    }    return (int) ((total + ((total >> 6) & 0x03)) & 0x3f);}void s1_sendpacket (char *packet){    send_pad ();    while (*packet) {        putc (*packet++);    }}static char a_b[24];void send_ack (int n){    a_b[0] = START_CHAR;    a_b[1] = tochar (3);    a_b[2] = tochar (n);    a_b[3] = ACK_TYPE;    a_b[4] = '\0';    a_b[4] = tochar (chk1 (&a_b[1]));    a_b[5] = his_eol;    a_b[6] = '\0';    s1_sendpacket (a_b);}void send_nack (int n){    a_b[0] = START_CHAR;    a_b[1] = tochar (3);    a_b[2] = tochar (n);    a_b[3] = NACK_TYPE;    a_b[4] = '\0';    a_b[4] = tochar (chk1 (&a_b[1]));    a_b[5] = his_eol;    a_b[6] = '\0';    s1_sendpacket (a_b);}/* os_data_* takes an OS Open image and puts it into memory, and   puts the boot header in an array named os_data_header   if image is binary, no header is stored in os_data_header.*/void (*os_data_init) (void);void (*os_data_char) (char new_char);static int os_data_state, os_data_state_saved;int os_data_count;static int os_data_count_saved;static char *os_data_addr, *os_data_addr_saved;static char *bin_start_address;int os_data_header[8];static void bin_data_init (void){    os_data_state = 0;    os_data_count = 0;    os_data_addr = bin_start_address;}static void os_data_save (void){    os_data_state_saved = os_data_state;    os_data_count_saved = os_data_count;    os_data_addr_saved = os_data_addr;}static void os_data_restore (void){    os_data_state = os_data_state_saved;    os_data_count = os_data_count_saved;    os_data_addr = os_data_addr_saved;}static void bin_data_char (char new_char){    switch (os_data_state) {    case 0:                 /* data */        *os_data_addr++ = new_char;        --os_data_count;        break;    }}static void set_kerm_bin_mode (unsigned long *addr){    bin_start_address = (char *) addr;    os_data_init = bin_data_init;    os_data_char = bin_data_char;}/* k_data_* simply handles the kermit escape translations */static int k_data_escape, k_data_escape_saved;void k_data_init (void){    k_data_escape = 0;    os_data_init ();}void k_data_save (void){    k_data_escape_saved = k_data_escape;    os_data_save ();}void k_data_restore (void){    k_data_escape = k_data_escape_saved;    os_data_restore ();}void k_data_char (char new_char){    if (k_data_escape) {        /* last char was escape - translate this character */        os_data_char (ktrans (new_char));        k_data_escape = 0;    } else {        if (new_char == his_quote) {            /* this char is escape - remember */            k_data_escape = 1;        } else {            /* otherwise send this char as-is */            os_data_char (new_char);        }    }}#define SEND_DATA_SIZE  20char send_parms[SEND_DATA_SIZE];char *send_ptr;/* handle_send_packet interprits the protocol info and builds and   sends an appropriate ack for what we can do */void handle_send_packet (int n){    int length = 3;    int bytes;    /* initialize some protocol parameters */    his_eol = END_CHAR;     /* default end of line character */    his_pad_count = 0;    his_pad_char = '\0';    his_quote = K_ESCAPE;    /* ignore last character if it filled the buffer */    if (send_ptr == &send_parms[SEND_DATA_SIZE - 1])        --send_ptr;    bytes = send_ptr - send_parms;  /* how many bytes we'll process */    do {        if (bytes-- <= 0)            break;        /* handle MAXL - max length */        /* ignore what he says - most I'll take (here) is 94 */        a_b[++length] = tochar (94);        if (bytes-- <= 0)            break;        /* handle TIME - time you should wait for my packets */        /* ignore what he says - don't wait for my ack longer than 1 second */        a_b[++length] = tochar (1);        if (bytes-- <= 0)            break;        /* handle NPAD - number of pad chars I need */        /* remember what he says - I need none */        his_pad_count = untochar (send_parms[2]);        a_b[++length] = tochar (0);        if (bytes-- <= 0)            break;        /* handle PADC - pad chars I need */        /* remember what he says - I need none */        his_pad_char = ktrans (send_parms[3]);        a_b[++length] = 0x40;   /* He should ignore this */        if (bytes-- <= 0)            break;        /* handle EOL - end of line he needs */        /* remember what he says - I need CR */        his_eol = untochar (send_parms[4]);        a_b[++length] = tochar (END_CHAR);        if (bytes-- <= 0)            break;        /* handle QCTL - quote control char he'll use */        /* remember what he says - I'll use '#' */        his_quote = send_parms[5];        a_b[++length] = '#';        if (bytes-- <= 0)            break;        /* handle QBIN - 8-th bit prefixing */        /* ignore what he says - I refuse */        a_b[++length] = 'N';        if (bytes-- <= 0)            break;        /* handle CHKT - the clock check type */        /* ignore what he says - I do type 1 (for now) */        a_b[++length] = '1';        if (bytes-- <= 0)            break;        /* handle REPT - the repeat prefix */        /* ignore what he says - I refuse (for now) */        a_b[++length] = 'N';        if (bytes-- <= 0)            break;        /* handle CAPAS - the capabilities mask */        /* ignore what he says - I only do long packets - I don't do windows */        a_b[++length] = tochar (2); /* only long packets */        a_b[++length] = tochar (0); /* no windows */        a_b[++length] = tochar (94);    /* large packet msb */        a_b[++length] = tochar (94);    /* large packet lsb */    } while (0);    a_b[0] = START_CHAR;    a_b[1] = tochar (length);    a_b[2] = tochar (n);    a_b[3] = ACK_TYPE;    a_b[++length] = '\0';    a_b[length] = tochar (chk1 (&a_b[1]));    a_b[++length] = his_eol;    a_b[++length] = '\0';    s1_sendpacket (a_b);}/* k_recv receives a OS Open image file over kermit line */

⌨️ 快捷键说明

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