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

📄 cmd_load.c.l

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 L
📖 第 1 页 / 共 3 页
字号:
406 #endif  /* CFG_CMD_LOADS */407 408 409 #if (CONFIG_COMMANDS & CFG_CMD_LOADB)  /* loadb command (load binary) included */410 411 #define XON_CHAR        17412 #define XOFF_CHAR       19413 #define START_CHAR      0x01414 #define ETX_CHAR    0x03415 #define END_CHAR        0x0D416 #define SPACE           0x20417 #define K_ESCAPE        0x23418 #define SEND_TYPE       'S'419 #define DATA_TYPE       'D'420 #define ACK_TYPE        'Y'421 #define NACK_TYPE       'N'422 #define BREAK_TYPE      'B'423 #define tochar(x) ((char) (((x) + SPACE) & 0xff))424 #define untochar(x) ((int) (((x) - SPACE) & 0xff))425 426 extern int os_data_count;427 extern int os_data_header[8];428 429 static void set_kerm_bin_mode(unsigned long *);430 static int k_recv(void);431 static ulong load_serial_bin (ulong offset);432 433 434 char his_eol;        /* character he needs at end of packet */435 int  his_pad_count;  /* number of pad chars he needs */436 char his_pad_char;   /* pad chars he needs */437 char his_quote;      /* quote chars he'll use */438 439 int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])440 {441     ulong offset = 0;442     ulong addr;443     int load_baudrate, current_baudrate;444     int rcode = 0;445     char *s;446 447     /* pre-set offset from CFG_LOAD_ADDR */448     offset = CFG_LOAD_ADDR;449 450     /* pre-set offset from $loadaddr */451     if ((s = getenv("loadaddr")) != NULL) {452         offset = simple_strtoul(s, NULL, 16);453     }454 455     load_baudrate = current_baudrate = gd->baudrate;456 457     if (argc >= 2) {458         offset = simple_strtoul(argv[1], NULL, 16);459     }460     if (argc == 3) {461         load_baudrate = (int)simple_strtoul(argv[2], NULL, 10);462 463         /* default to current baudrate */464         if (load_baudrate == 0)465             load_baudrate = current_baudrate;466     }467 468     if (load_baudrate != current_baudrate) {469         printf ("## Switch baudrate to %d bps and press ENTER ...\n",470             load_baudrate);471         udelay(50000);472         gd->baudrate = load_baudrate;473         serial_setbrg ();474         udelay(50000);475         for (;;) {476             if (getc() == '\r')477                 break;478         }479     }480 481     /* support xmodem, www.arm9.net */482     if (strcmp(argv[0],"loadx")==0) {483         printf ("## Ready for binary (xmodem) download "484             "to 0x%08lX at %d bps...\n",485             offset,486             load_baudrate);487 488         addr = load_serial_xmodem (offset);489 490     } else if (strcmp(argv[0],"loady")==0) {491         printf ("## Ready for binary (ymodem) download "492             "to 0x%08lX at %d bps...\n",493             offset,494             load_baudrate);495 496         addr = load_serial_ymodem (offset);497 498     } else {499 500         printf ("## Ready for binary (kermit) download "501             "to 0x%08lX at %d bps...\n",502             offset,503             load_baudrate);504         addr = load_serial_bin (offset);505 506         if (addr == ~0) {507             load_addr = 0;508             printf ("## Binary (kermit) download aborted\n");509             rcode = 1;510         } else {511             printf ("## Start Addr      = 0x%08lX\n", addr);512             load_addr = addr;513         }514     }515     if (load_baudrate != current_baudrate) {516         printf ("## Switch baudrate to %d bps and press ESC ...\n",517             current_baudrate);518         udelay (50000);519         gd->baudrate = current_baudrate;520         serial_setbrg ();521         udelay (50000);522         for (;;) {523             if (getc() == 0x1B) /* ESC */524                 break;525         }526     }527 528 #ifdef CONFIG_AUTOSCRIPT529     if (load_addr) {530         char *s;531 532         if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {533             printf("Running autoscript at addr 0x%08lX ...\n", load_addr);534             rcode = autoscript (load_addr);535         }536     }537 #endif538     return rcode;539 }540 541 542 static ulong load_serial_bin (ulong offset)543 {544     int size, i;545     char buf[32];546 547     set_kerm_bin_mode ((ulong *) offset);548     size = k_recv ();549 550     /*551      * Gather any trailing characters (for instance, the ^D which552      * is sent by 'cu' after sending a file), and give the553      * box some time (100 * 1 ms)554      */555     for (i=0; i<100; ++i) {556         if (tstc()) {557             (void) getc();558         }559         udelay(1000);560     }561 562     flush_cache (offset, size);563 564     printf("## Total Size      = 0x%08x = %d Bytes\n", size, size);565     sprintf(buf, "%X", size);566     setenv("filesize", buf);567 568     return offset;569 }570 571 void send_pad (void)572 {573     int count = his_pad_count;574 575     while (count-- > 0)576         putc (his_pad_char);577 }578 579 /* converts escaped kermit char to binary char */580 char ktrans (char in)581 {582     if ((in & 0x60) == 0x40) {583         return (char) (in & ~0x40);584     } else if ((in & 0x7f) == 0x3f) {585         return (char) (in | 0x40);586     } else587         return in;588 }589 590 int chk1 (char *buffer)591 {592     int total = 0;593 594     while (*buffer) {595         total += *buffer++;596     }597     return (int) ((total + ((total >> 6) & 0x03)) & 0x3f);598 }599 600 void s1_sendpacket (char *packet)601 {602     send_pad ();603     while (*packet) {604         putc (*packet++);605     }606 }607 608 static char a_b[24];609 void send_ack (int n)610 {611     a_b[0] = START_CHAR;612     a_b[1] = tochar (3);613     a_b[2] = tochar (n);614     a_b[3] = ACK_TYPE;615     a_b[4] = '\0';616     a_b[4] = tochar (chk1 (&a_b[1]));617     a_b[5] = his_eol;618     a_b[6] = '\0';619     s1_sendpacket (a_b);620 }621 622 void send_nack (int n)623 {624     a_b[0] = START_CHAR;625     a_b[1] = tochar (3);626     a_b[2] = tochar (n);627     a_b[3] = NACK_TYPE;628     a_b[4] = '\0';629     a_b[4] = tochar (chk1 (&a_b[1]));630     a_b[5] = his_eol;631     a_b[6] = '\0';632     s1_sendpacket (a_b);633 }634 635 636 /* os_data_* takes an OS Open image and puts it into memory, and637    puts the boot header in an array named os_data_header638 639    if image is binary, no header is stored in os_data_header.640 */641 void (*os_data_init) (void);642 void (*os_data_char) (char new_char);643 static int os_data_state, os_data_state_saved;644 int os_data_count;645 static int os_data_count_saved;646 static char *os_data_addr, *os_data_addr_saved;647 static char *bin_start_address;648 int os_data_header[8];649 static void bin_data_init (void)650 {651     os_data_state = 0;652     os_data_count = 0;653     os_data_addr = bin_start_address;654 }655 static void os_data_save (void)656 {657     os_data_state_saved = os_data_state;658     os_data_count_saved = os_data_count;659     os_data_addr_saved = os_data_addr;660 }661 static void os_data_restore (void)662 {663     os_data_state = os_data_state_saved;664     os_data_count = os_data_count_saved;665     os_data_addr = os_data_addr_saved;666 }667 static void bin_data_char (char new_char)668 {669     switch (os_data_state) {670     case 0:                 /* data */671         *os_data_addr++ = new_char;672         --os_data_count;673         break;674     }675 }676 static void set_kerm_bin_mode (unsigned long *addr)677 {678     bin_start_address = (char *) addr;679     os_data_init = bin_data_init;680     os_data_char = bin_data_char;681 }682 683 684 /* k_data_* simply handles the kermit escape translations */685 static int k_data_escape, k_data_escape_saved;686 void k_data_init (void)687 {688     k_data_escape = 0;689     os_data_init ();690 }691 void k_data_save (void)692 {693     k_data_escape_saved = k_data_escape;694     os_data_save ();695 }696 void k_data_restore (void)697 {698     k_data_escape = k_data_escape_saved;699     os_data_restore ();700 }701 void k_data_char (char new_char)702 {703     if (k_data_escape) {704         /* last char was escape - translate this character */705         os_data_char (ktrans (new_char));706         k_data_escape = 0;707     } else {708         if (new_char == his_quote) {709             /* this char is escape - remember */710             k_data_escape = 1;711         } else {712             /* otherwise send this char as-is */713             os_data_char (new_char);714         }715     }716 }717 718 #define SEND_DATA_SIZE  20719 char send_parms[SEND_DATA_SIZE];720 char *send_ptr;721 722 /* handle_send_packet interprits the protocol info and builds and723    sends an appropriate ack for what we can do */724 void handle_send_packet (int n)725 {726     int length = 3;727     int bytes;728 729     /* initialize some protocol parameters */730     his_eol = END_CHAR;     /* default end of line character */731     his_pad_count = 0;732     his_pad_char = '\0';733     his_quote = K_ESCAPE;734 735     /* ignore last character if it filled the buffer */736     if (send_ptr == &send_parms[SEND_DATA_SIZE - 1])737         --send_ptr;738     bytes = send_ptr - send_parms;  /* how many bytes we'll process */739     do {740         if (bytes-- <= 0)741             break;742         /* handle MAXL - max length */743         /* ignore what he says - most I'll take (here) is 94 */744         a_b[++length] = tochar (94);745         if (bytes-- <= 0)746             break;747         /* handle TIME - time you should wait for my packets */748         /* ignore what he says - don't wait for my ack longer than 1 second */749         a_b[++length] = tochar (1);750         if (bytes-- <= 0)751             break;752         /* handle NPAD - number of pad chars I need */753         /* remember what he says - I need none */754         his_pad_count = untochar (send_parms[2]);755         a_b[++length] = tochar (0);756         if (bytes-- <= 0)757             break;758         /* handle PADC - pad chars I need */759         /* remember what he says - I need none */760         his_pad_char = ktrans (send_parms[3]);761         a_b[++length] = 0x40;   /* He should ignore this */762         if (bytes-- <= 0)763             break;764         /* handle EOL - end of line he needs */765         /* remember what he says - I need CR */766         his_eol = untochar (send_parms[4]);767         a_b[++length] = tochar (END_CHAR);768         if (bytes-- <= 0)769             break;770         /* handle QCTL - quote control char he'll use */771         /* remember what he says - I'll use '#' */772         his_quote = send_parms[5];773         a_b[++length] = '#';774         if (bytes-- <= 0)775             break;776         /* handle QBIN - 8-th bit prefixing */777         /* ignore what he says - I refuse */778         a_b[++length] = 'N';779         if (bytes-- <= 0)780             break;781         /* handle CHKT - the clock check type */782         /* ignore what he says - I do type 1 (for now) */783         a_b[++length] = '1';784         if (bytes-- <= 0)785             break;786         /* handle REPT - the repeat prefix */787         /* ignore what he says - I refuse (for now) */788         a_b[++length] = 'N';789         if (bytes-- <= 0)790             break;791         /* handle CAPAS - the capabilities mask */792         /* ignore what he says - I only do long packets - I don't do windows */793         a_b[++length] = tochar (2); /* only long packets */794         a_b[++length] = tochar (0); /* no windows */795         a_b[++length] = tochar (94);    /* large packet msb */796         a_b[++length] = tochar (94);    /* large packet lsb */797     } while (0);798 799     a_b[0] = START_CHAR;800     a_b[1] = tochar (length);801     a_b[2] = tochar (n);802     a_b[3] = ACK_TYPE;803     a_b[++length] = '\0';804     a_b[length] = tochar (chk1 (&a_b[1]));805     a_b[++length] = his_eol;806     a_b[++length] = '\0';807     s1_sendpacket (a_b);808 }809 810 /* k_recv receives a OS Open image file over kermit line */

⌨️ 快捷键说明

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