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

📄 bsoload.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: mon/bsoload.c * Purpose: file loader for bso's tools * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970303	Cleaned up unused globals and functions */#include <termio.h>#include <mon.h>#define NOPROTO#ifdef NOPROTO#define	_(x)	()#else#define _(x) 	x#endif#define	REC_END		2#define	REC_DATA	3#define	REC_ERROR	4typedef unsigned long ADDR;void              dlink_init_admin _(( void ));static int               dlink_getcp _(( int ));static int               dlink_getc _(( int ));int               getBinRecord _(( int, char *, ADDR *, int * ));/* static void              dlink_terminate _(( int )); *//**************************************************************  loader for BSO's binary download format***	pkt ::= <len><msg><chksum>*	msg ::= <type><address><recordlength><databytes>*	*	Note that a pkt can contain part of a msg. ie. a msg can start*	in one pkt and continue in the next.**	type:  bits 2:0 number of address bytes minus 1 !!*		    4:3 compression type ( 0 = none )*		    6:5 zeros*		    7   set if termination record with initial pc**	len: total unescaped bytes in <msg>** 	recordlength: length is <databytes>**	checksum: a one byte ones complement sum of all unescaped record bytes,*		  except the record length and the checksum itself** Since the protocol is the start/stop protocol and the communication supports* a user interrupt character also when downloading these characters have to be * escaped when they appear in the data stream:**	Esc ( 0x1b )    -->  0x1b 0x1c *	Intr ( 0x03)    -->  0x1b 0x1d*	Crtl-S ( 0x13 ) -->  0x1b 0x1f*	Crtl-Q ( 0x11 ) -->  0x1b 0x1e** Any byte in the download record may have to be escaped, even the one in* the record length or the checksum.**/enum	e_status{	OK,	ERROR};#define	ESC_DLE		0x1c#define	ESC_INTR	0x1d#define	ESC_XON		0x1e#define	ESC_XOFF	0x1f#define	ASCII_DLE	0x1b#define	ASCII_INTR	0x03#define	ASCII_XON	0x11#define	ASCII_XOFF	0x13#define	ASCII_ACK	0x06#define	ASCII_NAK	0x15#define	MAX_SRECLEN	250	/* 255 when including 4 address bytes and 1 checksum byte */#define	MAX_DATALEN	(MAX_SRECLEN + 10)#define	MAX_LINELEN	(2 * MAX_DATALEN)static char    		recordLine [MAX_LINELEN];/* ========================================================================= * *  Binary record support                                                    * * ========================================================================= */#define	DLINK_BUFSIZE	255static char	*dlink_buffer	= recordLine;	/* note its size and usage ! */static char	*dlink_rp;static int	dlink_bytes_left;static int	dlink_sum;static int	dlink_ack_yet;	/* send ack before receiving next packet */static int	lbfn = 0;static int	bcnt = 0;static char	lwbuf[256];static int	dlink_stopped;extern Ulong 	nextaddr; static char *dlerrs[] = {0,"bad char","bad length","bad type",		 "bad chksum", "out of symbol space"};/**************************************************************  do_lo(ac,av)*/do_lo(ac,av)int ac;char *av[];{struct termio tbuf;int i,fd,err,s,len;int errs[6];Ulong start_address;char ch;fd = STDIN;ioctl_xvwlo(fd);dlink_init_admin();printf("Downloading from tty0, ^C to abort\n");for (;;) {	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,0);	if (s == REC_ERROR) { /* dlink_terminate( fd ); */ s = -3; }        if (s < 0) {                err++;                errs[0-s]++;                }        else tot += len;	if ( s == REC_END ) break;	}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 printf("!540!pc=%08x\n", start_address ); writec(1,CNTRL('q'));dlink_stopped = 0;}/**************************************************************  low_read( fd, n )*/low_read( fd, n )int	fd,n;{	if ( n > 256 ) n = 256;	if (dlink_stopped) writec( 1, CNTRL('q'));	lbfn = read( fd, lwbuf, n );	writec( 1, CNTRL('s'));	dlink_stopped = 1;	bcnt = -1;}	/**************************************************************  static unsigned char*/static unsigned chario_getc( fd )int fd;{	char	c;	int	n;	scandevs();	if ( lbfn == 0 )	{		/*		** now block until something is received		*/		if (dlink_stopped) writec( 1, CNTRL( 'q' ) );		while ( (n = read( fd, &c, 1 ) ) == 0 ) { scandevs(); }		writec( 1, CNTRL( 's' ) );		dlink_stopped = 1;	}	else	{		lbfn--;		bcnt++;		c = lwbuf[bcnt];	}	return c;}/************************************************************* * Function    : sRecordAck * Arguments   : OK: valid record; ERROR: invalid record * Returns     : - * Globals     : - * Modifies    : - * Description : output ACK or NACK signal when configurated to do so */static void	sRecordAck( fd, stat )int	fd;int	stat;{	if ( stat == OK )	{		writec( 1, CNTRL( ASCII_ACK ) );	}	else	{		writec( 1, CNTRL( ASCII_NAK ) );	}}/************************************************************* * Function    : dlink_init_admin * Arguments   : - * Returns     : - * Globals     : - * Modifies    : - * Description : resets any dlink variables*/void	dlink_init_admin( ){	dlink_ack_yet		= 0;	dlink_rp		= dlink_buffer;	dlink_bytes_left	= 0;	dlink_sum		= 0;}/************************************************************* * Function    : dlink_getcp * Arguments   : - * Returns     : character read * Globals     : - * Modifies    : - * Description : read one char from the datalink, after processing escaping *               operates at lowest IO level */static int	dlink_getcp( fd )int	fd;{	int	c;	c	= io_getc( fd );		if ( c == ASCII_DLE )	{		switch ( c = io_getc( fd ) )		{		case ESC_DLE:			c	= ASCII_DLE;			break;		case ESC_XOFF:			c	= ASCII_XOFF;			break;		case ESC_XON:			c	= ASCII_XON;			break;		case ESC_INTR:			c = ASCII_INTR;			/*			 *   process interrupt			c	= comm_info.intr;			 */			break;		}	}	return c;}/************************************************************* * Function    : dlink_getc * Arguments   : - * Returns     : next character from buffered link * Globals     : - * Modifies    : - * Description : read a packet from the datalink stream if the current buffer *               is empty, and return the next unprocessed char *               Since retrying endlessly, no error status can be returned.*/static int	dlink_getc( fd )int	fd;{	unsigned char	c;	int		i;	char		*cp;retry:	if ( dlink_bytes_left )	{		--dlink_bytes_left;		c	= *(unsigned char *)dlink_rp;		++dlink_rp;		return c;	}	if ( dlink_ack_yet )	{		/* need to send ACK for previously processed packet yet */		/* (delay the ACK to halt the sender while processing) */		sRecordAck( fd, OK );		dlink_ack_yet	= 0;	}	do	{		/* read packet */		dlink_sum		= 0;		dlink_rp		= dlink_buffer;		dlink_bytes_left	= dlink_getcp( fd );	/* length */		low_read( fd, dlink_bytes_left );		for ( cp = dlink_buffer, i = dlink_bytes_left; i; --i, ++cp )		{			c		= dlink_getcp( fd );			dlink_sum	+= c;			*cp		= c;		}		/* checksum */		dlink_sum	+= dlink_getcp( fd );		/* only NAK is send now, ACK on next packet or termination */		if ( (dlink_sum & 0xff) != 0xff )		{			sRecordAck( fd, ERROR );		}	}	while ( (dlink_sum & 0xff) != 0xff );	/* till success or INTR */	dlink_ack_yet	= 1;	goto retry;		/* use tail recursion -> for empty records */}#if 0 /* 970303 *//**************************************************************  static void	dlink_terminate( fd )*/static void	dlink_terminate( fd )int	fd;{	if ( dlink_ack_yet )	{		/* need to send ACK for previously processed packet yet */		/* delay the ACK to halt the sender while processing */		sRecordAck( fd, OK );		dlink_ack_yet	= 0;	}}#endif/************************************************************* * Function    : getBinRec * Arguments   : buffer to place data, *               ptr to address var, ptr to length * Returns     : REC_END if termination record, REC_DATA if data, *               REC_ERROR if an illegal record is received. * Globals     : - * Modifies    : - * Description : receive one binary data record, and return it and its length*/getBinRec( fd, dataBuffer, recordAddress, nrOfBytes )	int	fd;	char	*dataBuffer;	ADDR	*recordAddress;	int	*nrOfBytes;{	ADDR	addr;	int	rec_type;	int	nr;	addr = 0L;	/*	 * Typebyte: bit7    = terminating record with initial PC	 *           bit6..5 = unused, zeros	 *           bit4..3 = compress type	 *           bit2..0 = address bytes	*/	rec_type	= dlink_getc( fd );	if ( rec_type & 0x78 )	/* don't accept compressed data */	{		return REC_ERROR;	}	/* read the address */	for ( nr = (rec_type & 0x07)+1; nr; --nr )	{		addr	= (addr << 8) | dlink_getc( fd );	}	nr	= dlink_getc( fd );	*nrOfBytes	= nr;	*recordAddress	= addr;	for ( ; nr; --nr )	{		*dataBuffer++	= dlink_getc( fd );		tot++;	}	if ( rec_type & 0x80 )	/* ignore the data in a termination record */	{		*nrOfBytes	= 0;		return REC_END;	}	return REC_DATA;}

⌨️ 快捷键说明

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