load.c
来自「mips架构的bootloader,99左右的版本 但源代码现在没人更新了」· C语言 代码 · 共 304 行
C
304 行
/************************************************************* * File: pmon/load.c * Purpose: * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970303 Moved def of blksz and blkinx here * 970303 Removed unused static globals. * 970325 Added 'line'. * 970325 Added better eol stuff * 970514 Added \0 to eol list - needed for ethernet * 980113 Added (char *) casts for av[] * 980405 Added -m option * 980918 Removed old MSIM ifdefs. */#include <termio.h>#include <pmon.h>Optdesc load_opts[] = { {"[-vbeasti][-baud][offset][-c cmdstr]","load memory from hostport"}, {"-c cmdstr","send cmdstr to host"}, {"-s","don't clear symbols"}, {"-b","don't clear breakpoints"}, {"-e","don't clear exception handlers"}, {"-a","don't add offset to symbols"}, {"-t","load at top of memory"}, {"-i","ignore checksum errors"},#ifdef ETHERNET {"-B","binary transfer mode"}, {"-v","verbose mode"},#endif {"-<num>","set baud rate"}, {"-m","don't load memory - symbols only"}, {0}};char *dlerrs[] = {0,"bad char","bad length","bad type", "bad chksum", "out of symbol space"};#ifdef CROSSVIEW#ifdef NOPROTO#define _(x) ()#else#define _(x) x#endif#define REC_END 2#define REC_DATA 3#define REC_ERROR 4typedef unsigned long ADDR;#if 0 /* 970303 */static int fdbg;static char *dbgport = "tty1";#endif#endifUlong start_address;Ulong nextaddr;Ulong wordbuf;Ulong tbase;int chksum;int tot;int blksz;int blkinx;#define ether_bcopy() (* ether_bcopy_ptr)()Func *ether_bcopy_ptr;/************************************************************** load(ac,av)*/load(ac,av)int ac;Uchar *av[];{struct termio tbuf;char *hostport,*cmdstr;int fd,dlecho,dlproto,dltype,count,n;int len,err,i,j,s,flags;Ulong offset;Uchar recbuf[MAXREC],*baudrate;int errs[6],line;baudrate = 0;offset = 0;count = 0;cmdstr = 0;flags = 0;for (i=0;i<6;i++) errs[i] = 0;hostport = getMonEnv("hostport");vflag = 0;for (i=1;i<ac;i++) { if (av[i][0] == '-') { for (j=1;av[i][j];j++) { if (av[i][j] == 's') flags |= DL_SFLAG; else if (av[i][j] == 'b') flags |= DL_bFLAG; else if (av[i][j] == 'B') flags |= DL_BFLAG; else if (av[i][j] == 'e') flags |= DL_EFLAG; else if (av[i][j] == 'a') flags |= DL_AFLAG; else if (av[i][j] == 'v') vflag = 1; else if (av[i][j] == 't') { flags |= DL_TFLAG; Gpr[7] = 0; } else if (av[i][j] == 'i') flags |= DL_IFLAG; else if (av[i][j] == 'c') { i++; if (i >= ac) { printf("bad arg count\n"); return; } cmdstr = (char *)av[i]; break; } else if (isdigit(av[i][j])) { baudrate = &av[i][j]; break; } else printf("%c: unrecognized option\n",av[i][j]); } } else { if (av[i][0] == 't') hostport = (char *)av[i]; else if (count == 0) { if (!get_rsa(&offset,av[i])) return(1); count++; } else printf("%s: unrecognized argument\n",av[i]); } }if (!(flags&DL_SFLAG)) clrsyms();if (!(flags&DL_bFLAG)) clrbpt(-1);if (!(flags&DL_EFLAG)) clrhndlrs();#ifdef CROSSVIEWif (strequ(av[0],"lo")) hostport = "tty0";#endiffd = open(hostport,0,0);if (fd == -1) { printf("can't open %s\n",hostport); return; }dltype = -1; /* dltype is set by 1st char of 1st record */printf("Downloading from %s, ^C to abort\n",hostport);ioctl(fd,TCGETA,&tbuf);tbuf.c_iflag &= ~IXOFF;ioctl(fd,TCSETAF,&tbuf);if (baudrate) { if ((n=getbaudrate(fd,baudrate)) == 0) { printf("%s: unsupported baud rate\n",baudrate); return; } tbuf.c_cflag &= ~CBAUD; tbuf.c_cflag |= n; ioctl(fd,TCSETAF,&tbuf); }dlecho = matchenv("dlecho");if (dlecho == OFF || dlecho == LFEED) { tbuf.c_lflag &= ~ECHO; ioctl(fd,TCSETAF,&tbuf); }dlproto = matchenv("dlproto");if (cmdstr) { write(fd,cmdstr,strlen(cmdstr)); write(fd,"\r",1); }#ifdef ETHERNETif (flags&DL_BFLAG) { ether_bcopy(); return; /* never exits via this return. Uses ^C's longjmp */ }#endifchksum = 0;err = tot = 0;#ifdef CROSSVIEWif (strequ(av[0],"lo")) { dltype = 2; tbuf.c_iflag &= ~(ISTRIP|ICRNL); tbuf.c_cc[2] = 0xff; /* turn off bs processing */ ioctl(fd,TCSETAF,&tbuf); dlink_init_admin(); }#endifline = 0;for (;;) {#ifdef CROSSVIEW if (dltype == 2) { s = getBinRec(fd,recbuf,&nextaddr, &len); /* ** the last record in the download sequence ** contains the start address */ start_address = nextaddr; if (s == REC_DATA) memwrite(recbuf,len); if (s == REC_ERROR) { /* dlink_terminate( fd ); */ s = -3; } } else {#endif blksz = read(fd,recbuf,MAXREC-1); line++;#if 0 /* original */ if (blksz) blksz--; /* remove line termination char */#else /* 970325 delete all line termination characters */ while (blksz && (recbuf[blksz-1] == '\n' || recbuf[blksz-1] == '\r' || recbuf[blksz-1] == 0 || recbuf[blksz-1] == 003)) blksz--;#endif recbuf[blksz] = 0; /* null terminate the line */ if (strempty(recbuf)) continue; if (dlproto == XONXOFF) writec(fd,CNTRL('s')); if (strempty(recbuf)) { if (dlproto == XONXOFF) writec(fd,CNTRL('q')); else if (dlproto == ETXACK) writec(fd,CNTRL('f')); if (dlecho == LFEED) writec(fd,'\n'); continue; /* skip blank lines */ }#ifdef CROSSVIEW }#endif blkinx = 0; if (dltype == -1) { if (recbuf[0] == '/') dltype = 1; else if (recbuf[0] == 'S') dltype = 0; else { printf("bad record type\n"); dltype = ETXACK; err++; break; } } if (dltype == 1) s = fload(recbuf,offset,&len,&flags); else if (dltype == 0) s = sload(recbuf,offset,&len,&flags); /* return: -1..-N = err, 0 = end, 1 = ok */ if (s < 0) { printf("error %d on line %d\n",s,line); err++; errs[0-s]++; } else tot += len;#ifdef CROSSVIEW if ( dltype == 2 ) { if ( s == REC_END ) break; } else#endif { if (s == 0) break; if (s < 0 && dlproto == ETXACK) break; } if (dltype != 2) { if (dlproto == XONXOFF) writec(fd,CNTRL('q')); else if (dlproto == ETXACK) writec(fd,CNTRL('f')); } if (dlecho == LFEED) writec(fd,'\n'); }if ( dltype != 2 ) { if (dlproto == XONXOFF) writec(fd,CNTRL('q')); else if (dlproto == ETXACK) { if (err > 0) writec(fd,CNTRL('u')); else writec(fd,CNTRL('f')); } }if (dlecho == LFEED) writec(fd,'\n');if (fd > STDERR) close(fd);flush_cache(ICACHE);if (err) { printf("\n%d errors\n",err); for (i=1;i<6;i++) if (errs[i]) printf(" %3d %s\n",errs[i],dlerrs[i]); }else { if ( dltype == 2 ) printf("!540!pc=%08x\n", start_address ); else { printf("Entry address is %08x\n",getPc()); printf("\ntotal = 0x%x bytes\n",tot); } }writec(fd,CNTRL('q'));}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?