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

📄 genfrec.c

📁 mips架构的bootloader,99左右的版本 但源代码现在没人更新了
💻 C
字号:
/************************************************************* * File: tools/genfrec.c * Purpose: Generate fast-format records from a MIPS COFF file * Author: Phil Bunce (pjb@carmel.com) * Revision History: *	970313	Added -e option */#include <stdio.h>#include "mipscoff.h"/* * This program is intended for downloading program binaries to * a specially equipped prom monitor. It uses base 64 encoding, where * three bytes are sent as four characters. There are two record types, * those starting with '/' and those that do not. The records that start * with a '/' are used to perform special operations, all other records * contain 24 bits of data. The function send12 is used to send special * operations, whereas the function send24 is used to send data. * To further improve download performance, contiguous records of zero * are sent as a special record that includes a count value. The bss * section is cleared using these special records. */#define DEBUG 0#define BLKSIZE 500#define swap(x,y)	((y==2)?byte_swap(x,y):word_swap(x,y))/* special 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 */unsigned long addr;int blksz;int chksum;/* define the other 2 chars needed for base 64 */char exta = ',';char extb = '.';char *usage[] = {	"usage: genfrec [-ptdbcs] file",	"\tgenerate fast-format records suitable for downloading to PMON.",	"\t-p\tprom mode, start addresses at zero",	"\t-t\tomit text section",	"\t-b\tinclude bss section",	"\t-d\tdebug mode",	"\t-D\tdriver",	"\t-c\tdon't send checksum record",	"\t-s\tinclude symbols",	"\t-e\tgenerate symbols exclusively",	0};int filecount = 0;int prom = 0;int omit_text = 0;int inc_bss = 0;int cflag = 1;int debug = 0;int driver = 0;int sflag = 0;int eflag = 0;unsigned long entry;int leflag;/*** MIPS magic numbers:**	fread(&fhdr,sizeof(fhdr),1,fp)**	fhdr.f_magic		HOST		TARGET**	   0540			 BE		  BE**	   061001		 BE		  LE	(swap req'd)**	   0542			 LE		  LE**	   060001		 LE		  BE	(swap req'd)**	   0543			 BE		  BE    (mips2)**	   063001		 BE		  LE    (mips2, swap req'd)*//**************************************************************  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] == 'p') prom = 1;			else if (argv[i][j] == 't') omit_text = 1;			else if (argv[i][j] == 'b') inc_bss = 1;			else if (argv[i][j] == 'c') cflag = 0;			else if (argv[i][j] == 'd') debug = 1;			else if (argv[i][j] == 'e') eflag = 1;			else if (argv[i][j] == 'D') driver = 1;			else if (argv[i][j] == 's') sflag = 1;			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 */ filecount++;	}if (driver) send12("/D",0);if (cflag) send12(CLRSUM,0);if (filecount == 0) dofile(stdin,"stdin");else {	for (i=1;i<argc;i++) { /* do the files */		if (argv[i][0] != '-') { /* must be a filename */			fp = fopen(argv[i],"r");			if (! fp) {				fprintf(stderr,"can't open %s\n",argv[i]);				exit(-1);				}			dofile(fp,argv[i]);			fclose(fp);			}		}	}txeof(entry);exit(0);}/**************************************************************  dofile(ifp,fname)*/dofile(ifp,fname)FILE *ifp;char *fname;{struct aouthdr ohdr;unsigned long offset;struct filehdr fhdr;fread(&fhdr,sizeof(fhdr),1,ifp);if (fhdr.f_magic == 060001 || fhdr.f_magic == 061001 || fhdr.f_magic == 063001) 	{ /* reverse endian */	leflag = 1;	swap(&fhdr.f_magic,sizeof(fhdr.f_magic));	swap(&fhdr.f_nscns,sizeof(fhdr.f_nscns));	swap(&fhdr.f_opthdr,sizeof(fhdr.f_opthdr));	swap(&fhdr.f_symptr,sizeof(fhdr.f_symptr));	}else leflag = 0;if (debug) printf("magic=0%o nscns=%d ohdrsz=%d\n",	fhdr.f_magic,fhdr.f_nscns,fhdr.f_opthdr);if (fhdr.f_magic != 0540 && fhdr.f_magic != 0542 && 	fhdr.f_magic != 0543 && fhdr.f_magic != 0546) {	fprintf(stderr,"genfrec: 0%o Bad magic number\n",fhdr.f_magic);	exit(1);	}fread(&ohdr,sizeof(ohdr),1,ifp);if (leflag) {	swap(&ohdr.entry,sizeof(ohdr.entry));	swap(&ohdr.tsize,sizeof(ohdr.tsize));	swap(&ohdr.text_start,sizeof(ohdr.text_start));	swap(&ohdr.dsize,sizeof(ohdr.dsize));	swap(&ohdr.data_start,sizeof(ohdr.data_start));	swap(&ohdr.bsize,sizeof(ohdr.bsize));	swap(&ohdr.bss_start,sizeof(ohdr.bss_start));	}if (debug) printf("entry=%lx tsize=%lx tbase=%lx dsize=%lx dbase=%lx\n",	ohdr.entry,ohdr.tsize,ohdr.text_start,ohdr.dsize,ohdr.data_start);offset = ((fhdr.f_nscns*sizeof(struct scnhdr))+sizeof(fhdr)+	sizeof(ohdr)+15)&~15;if (sflag || eflag) do_syms(ifp,&fhdr);if (eflag) return;if (omit_text) fseek(ifp,offset+ohdr.tsize,0);else {	txaddr(ohdr.text_start);	fseek(ifp,offset,0);	dosect(ifp,ohdr.tsize);	}if (!prom) txaddr(ohdr.data_start);dosect(ifp,ohdr.dsize);if (inc_bss) clrbss(ohdr.bss_start,ohdr.bsize);if (!entry) entry = ohdr.entry;}/**************************************************************  dosect(infile,scnsize)*/dosect(infile,scnsize)FILE *infile;long scnsize;{int i,n,zcnt,reccnt;unsigned char buf[3];long cnt,bdat;zcnt = 0;reccnt = 0;for (cnt=0;cnt+3<=scnsize;cnt+=3) {	fread(buf,sizeof(buf[0]),3,infile); /* read 3 data bytes */	/* convert to single word */	bdat = buf[0]; bdat = (bdat<<8)+buf[1]; bdat = (bdat<<8)+buf[2];	if (bdat == 0) { /* compress if the data is zero */		zcnt++;		if (zcnt < 4096) continue;		zcnt--;		}	if (DEBUG) printf("%06lx ",cnt);	if (zcnt > 0) { /* send a special record for zeros */		send12(ZEROS,zcnt);		if (DEBUG) printf(" %03x\n",zcnt);		reccnt++;		zcnt = 0;		}	send24(bdat); /* send the data */	reccnt++;	if (DEBUG) printf(" %06lx\n",bdat);	}if (zcnt > 0) { /* make sure we didn't end with zeros outstanding */	send12(ZEROS,zcnt);	if (DEBUG) printf(" %03x\n",zcnt);	zcnt = 0;	}if (DEBUG) printf("cnt=%06lx scnsize=%06lx\n",cnt,scnsize);for (i=0;i<scnsize-cnt;i++) { /* if sect size not divisable by 3 */	fread(buf,sizeof(buf[0]),1,infile);	send12(BYTE,buf[0]); /* send individual byte */	if (DEBUG) printf(" %02x\n",buf[0]);	}if (DEBUG) printf("\n");}/**************************************************************  send12(type,val)*/send12(type,val)char *type;int val;{char adat[4];val &= 0xfff;chksum += val;adat[0] = type[0];adat[1] = type[1];adat[2] = b2a(val>>6);adat[3] = b2a(val);send(adat,4);}/**************************************************************  send24(val)*/send24(val)unsigned long val;{char adat[4];int i;val &= 0xffffff;chksum += val>>12;chksum += val&0xfff;for (i=3;i>=0;i--) {	adat[i] = b2a(val);	val>>=6;	}send(adat,4);}/**************************************************************  send(p,n)*/send(p,n)char *p;int n;{if (blksz+n >= BLKSIZE) {	putc('\n',stdout);	blksz = 0;	}fwrite(p,sizeof(p[0]),n,stdout);blksz += n;}/**************************************************************  txchksum()*/txchksum(){send12(CHKSUM,chksum);chksum = 0;}/**************************************************************  txeof(addr)*/txeof(addr)unsigned long addr;{if (cflag) txchksum(chksum);txaddr(addr);send12(END,0);putc('\n',stdout);}/**************************************************************  txaddr(addr)*/txaddr(addr)unsigned long addr;{if (blksz+8 >= BLKSIZE) {	putc('\n',stdout);	blksz = 0;	}send12(ADDR,addr>>24);send24(addr);if (DEBUG) printf(" %08lx ",addr);}/**************************************************************  clrbss(addr,size)*/clrbss(addr,size)long addr,size;{int i,rem;txaddr(addr);if (DEBUG) printf("%08lx ",size);rem = size % 3;size /= 3;while (size>4095) {	send12(ZEROS,4095);	size -= 4095;	}send12(ZEROS,size);for (i=0;i<rem;i++) send12(BYTE,0);}/**************************************************************  a2b(c)*	not used in this program*/a2b(c)int c;{/* translate base64 (tx form) to binaryA-Z	0..25a-z	26..510-9	52..61exta	62extb	63*/if (c >= 'A' && c <= 'Z') return(c-'A');if (c >= 'a' && c <= 'z') return(c-'a'+26);if (c >= '0' && c <= '9') return(c-'0'+52);if (c == exta) return(62);if (c == extb) return(63);printf("a2a: Bad input value\n");return(0);}/**************************************************************  b2a(c)*/b2a(c)int c;{/* translate binary to base64 (tx form) 0..25		A-Z26..51		a-z52..61		0-96263*/c &= 0x3f;if (c <= 25)  return('A'+c);if (c <= 51) return('a'+c-26);if (c <= 61) return('0'+c-52); if (c == 62) return(exta);if (c == 63) return(extb);printf("b2a: bad input value\n");return(0);}/**************************************************************  word_swap(vp)*/word_swap(vp)unsigned long *vp;{unsigned short v1,v2;v1 = (*vp)>>16;byte_swap(&v1);v2 = (*vp)&0xffff;byte_swap(&v2);*vp = (((unsigned long)v2)<<16)+v1;}/**************************************************************  byte_swap(vp)*/byte_swap(vp)unsigned short *vp;{*vp = ((*vp)<<8)+((*vp)>>8);}/**************************************************************  do_syms(fp,fhdr)*/do_syms(fp,fhdr)FILE *fp;struct filehdr *fhdr;{int i,size,len;EXTR sym;HDRR symh;char buf[100];long p;blksz = 0;fseek(fp,fhdr->f_symptr,0);fread(&symh,sizeof(HDRR),1,fp);if (leflag) {	swap(&symh.cbExtOffset,sizeof(symh.cbExtOffset));	swap(&symh.cbSsExtOffset,sizeof(symh.cbSsExtOffset));	swap(&symh.iextMax,sizeof(symh.iextMax));	}if (debug) {	printf("HDRR offset=%08lx size=0x%02x\n",fhdr->f_symptr,sizeof(HDRR));	printf("cbSsExtOffset=%08lx iextMax=%d cbExtOffset=%08lx\n",		symh.cbSsExtOffset,symh.iextMax,symh.cbExtOffset);	printf("EXTR size=0x%02x\n",sizeof(EXTR));	printf("%5s %10s %10s %10s %2s %5s %10s\n",			"#","adr","iss", "value","st","sc","index");	}p = symh.cbExtOffset;for (i=0;i<=symh.iextMax;i++) { 	fseek(fp,p,0);	if (fread(&sym,sizeof(EXTR),1,fp) != 1) break;	if (leflag) {		swap(&sym.asym.iss,sizeof(sym.asym.iss));		swap(&sym.asym.value,sizeof(sym.asym.value));		}	p = ftell(fp);	fseek(fp,sym.asym.iss+symh.cbSsExtOffset,0);	getsym(buf,fp);	if (debug) {		printf("[%3d] ",i);		printf("0x%08lx ",sym.asym.iss);		printf("0x%08lx ",sym.asym.value);		printf("sym=%s\n",buf);		}	txaddr(sym.asym.value);	strcat(buf,",");	for (;;) {		len = strlen(buf)+2;		if ((len&3) == 0) break;		strcat(buf,"X");		}	if (blksz+len >= BLKSIZE) {		putc('\n',stdout);		blksz = 0;		}	printf("/S%s",buf);	blksz += len;	}putc('\n',stdout);}/**************************************************************  getsym(p,fp)*/getsym(p,fp)char *p;FILE *fp;{int c;for (;;) {	c = getc(fp);	if (c == EOF) break;	if (c == 0) break;	*p++ = c;	}*p = 0;}

⌨️ 快捷键说明

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