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 + -
显示快捷键?