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

📄 rdsrec.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************* * File: tools/rdsrec.c * Purpose: S-record reader * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970327	Changed RMON to IMON in help. *	970818	Fixed prob caused by srecs that have odd# of bytes *	970823	Fixed prob w disasm mip16 code *	970927	Fixed prob w -A caused by 970823 *	970927	Added checksum to -A mode *	970930	Large change. Sort srecs into linked list before processing. *		This was necessary for bso. Also added bytefill. Necessary *		for Cygnus. *	970930	Removed the vertcut feature. *	971001	Fixed wrong addresses in -n *	971003	Fixed -C. Don't emit .byte. *	980309	Added -m option for generating .ocm files. *	981205	The -b option fails if address appears more than once. *	990115	Added -Bnn option to set length of srecord. */#include <stdio.h>#include <string.h>#include <ctype.h>#include <malloc.h>#ifdef MSDOS#include <fcntl.h>#include <io.h>#endiftypedef unsigned char Uchar;typedef unsigned long Ulong;#define DEBUG 0#define loop for (;;)#define RECSIZE 100#define strNcpy(x,y,z)	strncpy(x,y,z),x[z]=0#define LINESZ 100#define BLKSIZE 500#define ADDRSIZE  4	/* address size specified in bytes 				2 = S1recs, 				3 = S2recs, 				4 = S3 recs 				*//* special fast-format record types */#define ZEROS "/Z"		/* record contains a count of zeros,				   actually it's the number of 24-bit				   records that are all zero */#define BYTE "/B"		/* record contains a single byte */#define CHKSUM "/C"		/* checksum to date */#define CLRSUM "/K"		/* klear (sic) the checksum */#define ADDR "/A"		/* double length record containing a 32 bit				   address */#define END "/E"		/* end of download *//* define the other 2 chars needed for base 64 */char exta = ',';char extb = '.';typedef struct SymRec {	struct SymRec *next;	char *name;	unsigned long value;	} SymRec;typedef struct DataRec {	struct DataRec *next;	Ulong addr;	int len;	Uchar *data;	} DataRec;int filecount;char *filelist[10];int debug;int nodisasm;char prnbuf[100];SymRec *symchn;		/* symbols in reverse value order (highest 1st) */int fastmode;Ulong nextaddr;Ulong addr;int zcnt;int blksz;int chksum;int cflag = 1;int datasize = 32;int Dflag;int mflag;int gensrecs;unsigned long bdat;unsigned long bdat_cnt;char bytebuf[256];int bytecnt,vertnn;Ulong bytebufadr;DataRec *datachn;int bytefill;/* output file pointer and name */FILE *ofp;char *oname;char *usage[] = {	"usage: rdsrec [-bln] file [-o name]",	"Read a Motorola S-record file. By default it disassembles the file.",	"\t-A name\tgenerate assembly data declarations",	"\t-b\tsend binary image to stdout.",	"\t-Bnn\tnumber of databytes per record (for -s option)",	"\t-C name\tgenerate C data declarations",	"\t-D\tmark the output as a TDD for IMON",	"\t-f\tgenerate fast-format records",	"\t-l\tlittle endian, swap each word",	"\t-m\tgenerate ocm info file",	"\t-n\tno disassembly",	"\t-o name\tsend output to file",	"\t-s\tgenerate S-records",	"\t-Txxxxxxxx\tadd offset to record address",#if 0 /* 970930 feature removed */	"\t-vm.n\tvertical cut",#endif	0};int binary,little;Ulong Toffs;#if 0 /* feature removed 970930 */int vertm = 1;int vertn = 0;#endifchar *cname;char *aname;FILE *ifp;char linebuf[RECSIZE]; /* buffer the ascii data from the file */Uchar databuf[RECSIZE]; /* buffer the data bytes */int bufinx,buflen; /* indexes into the databuf[] */long disasm();char *strccat();int getbyte();/**************************************************************  main(argc,argv)*/main(argc,argv)int argc;char *argv[];{FILE *fp;int i,j;for (i=1;i<argc;i++) { /* first find all the options */	if (argv[i][0] == '-') { /* must be an option */		for (j=1;argv[i][j] != 0;j++) {			if (argv[i][j] == 'd') debug = 1;			else if (argv[i][j] == 'b') {				binary = 1;				bytefill = 1;				}			else if (argv[i][j] == 'B') {				sscanf(&argv[i][j],"B%d",&datasize);				break;				}			else if (argv[i][j] == 'T') {				sscanf(&argv[i][j],"T%lx",&Toffs);				break;				}			else if (argv[i][j] == 'l') little = 1;			else if (argv[i][j] == 'o') {				if (i+1 >= argc) {					printf("bad arg count\n");					exit(1);					}				oname = argv[++i];				break;				}			else if (argv[i][j] == 'A') {				if (i+1 >= argc) {					printf("bad arg count\n");					exit(1);					}				aname = argv[++i];				bytefill = 1;				break;				}			else if (argv[i][j] == 'C') {				if (i+1 >= argc) {					printf("bad arg count\n");					exit(1);					}				cname = argv[++i];				bytefill = 1;				break;				}			else if (argv[i][j] == 'n') nodisasm = 1;			else if (argv[i][j] == 'D') Dflag = 1;			else if (argv[i][j] == 'f') fastmode = 1;			else if (argv[i][j] == 's') gensrecs = 1;			else if (argv[i][j] == 'c') cflag = 0;			else if (argv[i][j] == 'm') mflag = 1;#if 0 /* feature removed 970930 */			else if (argv[i][j] == 'v') {				sscanf(&argv[i][j],"v%d.%d",&vertm,&vertn);				break;				}#endif			else {				fprintf(stderr,"%c: bad option\n",argv[i][j]);				for (j=0;usage[j];j++)					fprintf(stderr,"%s\n",usage[j]);				exit(-1);				}			}		}	else /* must be a file */ filelist[filecount++] = argv[i];	}#if 0 /* feature removed 970930 */if (vertn+1 > vertm) {	fprintf(stderr,"incompatible -vm.n options\n");	exit(1);	}#endifif (oname) {	ofp = fopen(oname,"w");	if (!ofp) {		fprintf(stderr,"can't open %s\n",oname);		exit(1);		}	}else ofp = stdout;#ifdef MSDOS/* MSDOS converts 0x0a to 0x0d0a, so... */if (binary) _setmode(fileno(ofp),_O_BINARY);#endifif (filecount == 0) dofile(stdin,"stdin");else {	for (i=0;i<filecount;i++) { /* do the files */		fp = fopen(filelist[i],"r");		if (! fp) { 			fprintf(stderr,"can't open %s\n",filelist[i]);			exit(-1);			}		dofile(fp,filelist[i]);		fclose(fp);		}	}exit(0);}/**************************************************************  dofile(fp,fname)* 	do a file*/dofile(fp,fname)FILE *fp;char *fname;{int len,x,totbytes;int i,mips16,v;Ulong val,na,csum,addr;mips16 = 0;ifp = fp;if (Dflag && fastmode) send12("/D",0);if (cflag && fastmode) send12(CLRSUM,0);if (cname) fprintf(ofp,"unsigned char %s[] = {\n",cname);if (aname) fprintf(ofp,"\t.data\n\t.globl %s\n%s:\n\t.byte ",aname,aname);totbytes = 0;csum = 0;for (i=0;;i++) {	v = getbyte(&addr);	if (v == EOF) break;	val <<= 8;	val |= v;	if (fastmode && addr != nextaddr) txaddr(addr);	else if (gensrecs) srecSend(addr,v);	else if (fastmode) fastSend(v);	else if (cname || aname) {		if (i>=12) {			if (aname) fprintf(ofp,"\n\t.byte ");			else fprintf(ofp,"\n\t"); /* 971003 */			i = 0;			}		if (i != 0) fprintf(ofp,",");		fprintf(ofp,"0x%02x",v);		totbytes++;		csum += v;		}	else if((i+1)%4 == 0) {		if (little) word_swap(&val);		if (binary) putw(&val,ofp);		else if (nodisasm) fprintf(ofp,"%08lx: %08lx\n",addr-3,val);		else {			setTiny(addr-3,&mips16);			if (mips16) {				na = disasm(prnbuf,addr-2, val);				fprintf(ofp,"%s\n",prnbuf);				if (na-(addr-2) == 2) i -= 2;				}			else {				disasm(prnbuf,addr-3, val);				if (mflag) col2only(prnbuf);				fprintf(ofp,"%s\n",prnbuf);				}			}		}	}if (fastmode) txeof(addr);if (gensrecs) do_erec(addr);if (cname) {	fprintf(ofp,"};\nint %s_size = %d;\n",cname,totbytes);	fprintf(ofp,"unsigned long %s_csum = 0x%08lx;\n",cname,csum);	}if (aname) {	fprintf(ofp,"\n\t.sdata\n\t.globl %s_size\n%s_size: .word %d\n",		aname,aname,totbytes);	fprintf(ofp,"\t.globl %s_csum\n%s_csum: .word 0x%08lx\n",		aname,aname,csum);	}}/**************************************************************  int getbyte(paddr)*	get the next data byte from the input file*/int getbyte(paddr)Ulong *paddr;{int x;int len;DataRec *p;if (!datachn) {	for (;;) {		if (!fgets(linebuf,RECSIZE,ifp)) break;		if (linebuf[strlen(linebuf)-1] == '\n') 			linebuf[strlen(linebuf)-1] = 0;		if (linebuf[strlen(linebuf)-1] == '\r') 			linebuf[strlen(linebuf)-1] = 0;		if (linebuf[0] != 'S') continue;		if (linebuf[1] >= '1' && linebuf[1] <= '3') {			if (x=datarec(linebuf,&addr,&len)) 				fprintf(stderr,"err %ld\n",x);			addDataRec(addr,databuf,len);			}		else if (linebuf[1] >= '7' && linebuf[1] <= '9') 			entrec(linebuf,&addr);		else if (linebuf[1] == '4') symrec(linebuf);		}	bufinx = 0;	nextaddr = datachn->addr+1;	*paddr = datachn->addr+Toffs;	return datachn->data[bufinx++];	}if (bufinx >= datachn->len) {	free(datachn->data);	p = datachn;	datachn = p->next;	free(p);	bufinx = 0;	if (datachn == 0) return(EOF);	*paddr = datachn->addr+Toffs;	}if (bytefill && datachn->addr > nextaddr) {	nextaddr++;	*paddr = nextaddr+Toffs;	return(0);	}*paddr = datachn->addr+bufinx+Toffs;nextaddr = datachn->addr+bufinx+1;return datachn->data[bufinx++];}/**************************************************************  addDataRec(addr,data,len)*/addDataRec(addr,data,len)Ulong addr;Uchar *data;int len;{DataRec *new,*p,*pr;new = (DataRec *)malloc(sizeof(DataRec));new->data = (Uchar *)malloc(len);memcpy(new->data,data,len);new->addr = addr;new->len = len;new->next = 0;/* empty chain */if (!datachn) {	datachn = new;	return;	}/* insert before first item? */if (datachn->addr > new->addr) {	new->next = datachn;	datachn = new;	return;	}/* one item on chain */if (datachn->next == 0) {	datachn->next = new;	return;	}		/* n items on chain */for (p=datachn->next,pr=datachn;p;p=p->next) {	if (p->addr > new->addr) break;	pr = p;	}new->next = pr->next;pr->next = new;return;}/**************************************************************  entrec(p)*	process an entry-point record*/entrec(p,paddr)char *p;Ulong *paddr;{int len,i,chksum;unsigned long addr,v;chksum = 0;if (!gethex(&len,&p[2],2)) return(-1);chksum += len;if (len*2 != strlen(p)-4) return(-2);i = 4; addr = 0;switch (p[1]) {	case '7' :		if (!gethex(&v,&p[i],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		i += 2;	case '8' :		if (!gethex(&v,&p[i],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		i += 2;	case '9' :		if (!gethex(&v,&p[i],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		if (!gethex(&v,&p[i+2],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		break;	default : return(-3);	}if (!fastmode && !aname) fprintf(stderr,"Entry point %08lx\n",addr);*paddr = addr;return(0);}/**************************************************************  datarec(p,paddr,plen)*	process a data record*/datarec(p,paddr,plen)char *p;Ulong *paddr;int *plen;{int len,i,chksum,cs;Ulong v,val;*plen = 0;chksum = 0;if (!gethex(&len,&p[2],2)) return(-1);chksum += len;if (len*2 != strlen(p)-4) return(-2);i = 4; addr = 0;switch (p[1]) {	case '3' :		if (!gethex(&v,&p[i],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		i += 2;	case '2' :		if (!gethex(&v,&p[i],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		i += 2;	case '1' :		if (!gethex(&v,&p[i],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		if (!gethex(&v,&p[i+2],2)) return(-1);		addr = (addr<<8)+v;		chksum += v;		break;	default  : return(-3);	}*paddr = addr;p = &p[i+4];len -= (i/2)+1;val = 0;for (i=0;i<len;i++,p+=2) {	if (!gethex(&v,p,2)) return(-1);	databuf[i] = v;	chksum += v;	}if (!gethex(&cs,p,2)) return(-1);if (cs != ((~chksum)&0xff)) return(-4);*plen = i;

⌨️ 快捷键说明

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