swackham@violet.berkeley.edu (04/26/88)
I am trying to download some assembly code to a 68k single board computer. The monitor program on the computer can accept Motorola "S records". What is the format/structure of these records? I can create these on the host unix system once I know the requirements. Please E-mail responses to: swackham@violet.berkeley.edu Thanks!
michael@mcdchg.UUCP (Michael Bodine) (04/29/88)
swackham@violet.berkeley.edu.UUCP writes: > Motorola "S records". What is the format/structure of these records? > Please E-mail responses to: swackham@violet.berkeley.edu Altho you requested mailed responses, i've noticed requests for Srecord format a couple of times recently, so i'm posting this for general interest: Motorola S-records are intended to provide an ASCII-encoded hex format for binary records allowing the downloading of executable code or data into target systems or EPROM programs or communication of same across media prone to problems with binary transmissions. Most PROM blowers and M68K family debug tools understand the S-record format, which is as follows: Sxllaaaa[aa[aa]]dddd......ddcc where: Sx -- is the S-record format descriptor: S0 : header record, which is unused by almost any interpreter and which may contain standard ASCII data describing file contents S1 : a binary record with a 16-bit address S2 : a binary record with a 24-bit address S3 : a binary record with a 32-bit address S5 : a block record, contains the number of S1, S2 or S3 records in the following block, in the address field. dd data field is empty. Normally not used. S7 : termination record for a block of S3 records. Address field will optionally contain the start address for the completed program. S8 : termination record for S2 records. S9 : termination record for S1 records. Note that only one termination record is recquired at the end of the file to take the target out of load mode. S1, S2 and S3 records may be intermixed quite randomly, altho most vendors will typically choose the largest address in the file and make all S-records use that type of descriptor. ll -- the number of character pairs in the record inluding the descriptor and length, but not including the checksum aaaa[aa[aa]] -- the address into which the data is to be loaded, where the number of bits represented is 16 for S1, 24 for S2 and 32 for S3. dd -- a ASCII-coded hexadecimal pair representing one byte of binary data cc -- the low-order byte of the one's complement sum of all byte pairs in the record except the descriptor and the checksum, that is, the length, address and data fields are checksummed. An example: S1130000285F245F2212226A000424290008237C2A SXllaaaaddddddddddddddddddddddddddddddddcc A similar description of S-records is included with almost every firmware debugger manual available from Motorola. Enjoy! -- [ Michael Bodine, michael@mcdchg.UUCP Opinions expressed are mine and haven't ] [ been seen, commented on or in any way approved or even allowed by Motorola ] [ MicroComputer Division, Motorola General Systems Group or Motorola, Inc. ] [ No one else agrees with me; why should my employer? ]
kaul@icarus.eng.ohio-state.edu (Rich Kaul) (05/01/88)
In article <7439@mcdchg.UUCP> michael@mcdchg.UUCP (Michael Bodine) writes: >swackham@violet.berkeley.edu.UUCP writes: >> Motorola "S records". What is the format/structure of these records? >> Please E-mail responses to: swackham@violet.berkeley.edu >Altho you requested mailed responses, i've noticed requests for Srecord >format a couple of times recently, so i'm posting this for general >interest: > You might also want to know that there exists a public domain program called tohex that will convert Unix a.out files to Motorola S-records, Intex hex format or Textronix hex format. This program was written by Phil Harbison quite a while back and put out on the network (I dug it up in our archives from 1984). I sent a copy of this program to the guy who requested info on S-records. It certainly makes life easier. We have a guy here who uses it to program a robotic arm with a MC68020 controller. The controller fits into a MicroVax, so he compiles the programs for the arm on our Sun 3/260, converts the a.out, ftps to the MicroVax and downloads the records. The system works well. If anyone else is interested in the converter, drop me a line and I'll send it to you. -=- Rich Kaul kaul@icarus.eng.ohio-state.edu kaul@tut.cis.ohio-state.edu "You must realize that the computer has it in for you. The irrefutable proof of this is that the computer always does what you tell it to do."
kaul@icarus.eng.ohio-state.edu (Rich Kaul) (05/07/88)
Ok, after more than 30 requests, phone calls from people not able to get me via mail and mail forwarded from other machines, I'm giving up. Here's the source to the tohex program to convert Unix a.out to Motorola S-record or Intel Hex format. A word of warning. Read the manual page carefully. The magic number of the file is very important. It defaults to FMAGIC, but for those of you on Suns you will have to change this to ZMAGIC if you use the default executable type. See your documentation on your a.out type. In one of the more interesting turns of events, there is one person who told me he is using the GNU Assembler and this program on his 3b2 to generate MC68020 code. I know this runs under 4BSD and SunOS 3.2-3.4 I am told it will run under SysV but can't check and it ran under early releases of Xenix. Have fun, because you're on your own. -Rich #!/bin/sh echo 'Start of Tohex, part 01 of 01:' echo 'x - tohex.1' sed 's/^X//' > tohex.1 << '/' X.TH TOHEX 1L X.. Copyright 1984, 1987 by Phillip L. Harbison X.SH NAME Xtohex - convert UNIX a.out files to readable hex formats. X.SH SYNOPSIS X.bo Xtohex X{ -i | -s | -t } [-ln] [+n] file X.SH DESCRIPTION X.ad X.ul XTohex Xreads a file in UNIX a.out format and converts Xto one of several hex-ascii formats. XOutput is directed to the standard output. XThe X.ul X-s Xoption specifies Motorola S-record format. XThe X.ul X-i Xoption specifies Intel hex format. XThe X.ul X-t Xoption specifies Tektronix hex (tekhex) format. XA valid hex format and input filename Xmust be specified on the command line. X.LP XA record length may be specified using the X.ul X-ln Xoption, Xwhere n is the record length (decimal). XThe default record length is 32 byte-pairs. XThe maximum record length is 251 byte-pairs Xfor S-record format, Xand 255 byte-pairs for Intel-hex and Tekhex format. X.LP XTohex will derive the starting address offset Xfrom the header information in the a.out file. XA starting address offset may also Xbe provided using the X.ul X+n Xoption. XThe offset n (hexadecimal) will be used Xinstead of the value derived from the a.out header. XSpecifying an offset is usually unnecessary Xfor object files generated by the UNIX loader. X.SH EXAMPLES XThe first example shows the file X.ul Xnewprog Xbeing converted to Intel-hex records Xwith a starting address offset of A000 (hex) Xand written to X.ul Xnewprog.hex. XThe second example shows the file X.ul Xnewprog Xbeing converted to S-records Xwith a length of 64 byte-pairs, Xthe output being redirected to X.ul Xnewprog.hex. X.sp 1 X.nf X tohex -i +0A000 newprog > newprog.hex X tohex -s -l64 newprog > newprog.hex X.fi X.SH DIAGNOSTICS X.ul XTohex Xwill complain if it cannot find a valid format Xspecifier and input filename on the command line, Xif the record length exceeds the maximum record Xlength for the specified format, Xor if the input file is not stripped Xof symbol table information. XMessages should be self-explaining. X.SH NOTES XThe magic number is defined as FMAGIC in the Xa.out.h file on the author's system, Xand may not be correct for other systems. XPure executable a.out files are not supported, Xsince initialized data is assumed to follow Xdirectly after text. XThe S-record format supported is the S2/S8 record, Xproviding 24-bit addressing. XThe termination (S8) record will contain the starting address. XThe Intel-hex format only supports 16-bit addressing. X.SH FILES X/usr/include/a.out.h X.SH "SEE ALSO" Xa.out(5) X.SH AUTHOR XPhil Harbison / echo 'x - tohex.c' sed 's/^X//' > tohex.c << '/' X/* X * Tohex is a utility for converting UNIX a.out files into various X * readable hex formats suitable for downloading or inter-system X * file transfer. Motorola S-records, Tek-hex, and Intel Hex are X * currently supported. Other formats can be added easily by X * adding a formatter module and modifying getargs. Toshex, X * toihex, and totekhex are the current formatter modules. Tohex X * does not support System V COFF object files. X * X * (c) Copyright 1984, 1987 by Phillip L. Harbison X * X * Permission is granted to use, reproduce and distribute this pro- X * gram by any means, as long as no fee is charged, and provided X * this notice is always included in any copies. X * X * The author hereby dislaims any and all guarantees and X * warranties, both expressed and implied; and no fitness for any X * purpose whatsoever is claimed or implied. The author will not X * be responsible for any damages resulting from the use of this X * software. Tohex is provided as is, with no promise of support, X * but I will try to respond to polite bug reports or suggestions X * for improvements that are forwarded to me via any of the X * following means. X * X * Live: Phil Harbison X * Mail: 3409 Grassfort Drive, Huntsville, AL 35805-5421 X * UUCP: uunet!madhat!alvitar or alvitar@madhat.uu.net X * BELL: 205-881-4317, 205-535-2500 X * X */ X X#include <stdio.h> X#include <a.out.h> X X#define MAXSIZE 256 X#define NULL 0 X#define TRUE 1 X#define FALSE 0 X#define INTEL 'i' X#define LENGTH 'l' X#define MOT 's' X#define TEKHEX 't' X Xchar digits[]="0123456789ABCDEF"; /* for use in output conversion */ Xchar record[MAXSIZE+1]; /* where we put binary input data */ Xint (*hexout)(); /* pointer to conversion function */ Xint offset; /* starting address */ Xint oflag; /* starting address specified as arg */ Xint recsize; /* maximum data bytes/output record */ Xint chksum; /* output record checksum */ Xint toshex(), toihex(), totekhex(); /* conversion functions */ Xstruct bhdr header; /* where we put the a.out header */ XFILE *infile; /* input file descriptor */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int addr, maxaddr, count; X X /* process the command line arguments */ X if ( !getargs(argc, argv) ) { X usage(); X exit(1); X } X X /* read the a.out file header */ X if ( !fread(&header, sizeof (struct bhdr), 1, infile) ) { X fprintf(stderr,"tohex: unable to read file header\n"); X } X if ( header.fmagic != FMAGIC ) { X fprintf(stderr,"tohex: not an a.out file\n"); X exit(1); X } X if ( header.rtsize || header.rdsize ) { X fprintf(stderr, "tohex: input file not stripped\n"); X exit(1); X } X X /* print interesting trivia about the file */ X fprintf(stderr, "entry point: %08X\n", header.entry); X fprintf(stderr, "text size: %06X (%d)\n", header.tsize, header.tsize); X fprintf(stderr, "data size: %06X (%d)\n", header.dsize, header.dsize); X X /* X * if no starting address was specified use the entry X * point specified in the header. This is usually X * appropriate for a.out files. X */ X if ( !oflag ) X offset = header.entry; X X /* calculate size of input */ X maxaddr = header.tsize + header.dsize; X X /* loop until out of input */ X for ( addr= 0; addr <= maxaddr; ) { X /* X * try to read count bytes from infile into record X * where count is the lesser of recsize or the number X * of bytes remaining in the object image. X */ X count = ((addr + recsize) <= maxaddr) ? X recsize : (maxaddr - addr); X count = fread(record,1,count,infile); X /* are we at EOF ? */ X if ( !count ) { X break; X } X /* X * convert record from binary to hex format. hexout X * points to the specified conversion function. X */ X (*hexout)(count, addr, record); X addr += count; X } X /* X * force the termination record by X * requesting a zero-length packet. X */ X (*hexout)(0,0,record); X fclose(infile); X} X X/* X * getargs processes the command line arguments. It expects X * to see hex output type an input filename, and (optionally) X * a starting address offset in any order. X */ Xgetargs(argc, argv) Xint argc; Xchar *argv[]; X{ X int index, state, maxsize, tmp; X X state = TRUE; X oflag = FALSE; X hexout = NULL; X infile = (FILE *) NULL; X X /* default record size is 32 */ X recsize = 32; X X /* process each argument */ X for ( index= 1; index < argc; index++ ) { X /* see if its a flag */ X if ( *argv[index] == '-' ) { X /* must be a hex output type */ X switch ( *(argv[index] + 1) ) { X case MOT : X /* motorola S-records */ X hexout = toshex; X maxsize = 251; X break; X case INTEL : X hexout = toihex; X maxsize = 255; X break; X case TEKHEX : X hexout = totekhex; X maxsize = 255; X break; X case LENGTH : X if ( sscanf(argv[index]+2, "%d", &tmp) == 1 ) { X recsize = tmp; X } X else { X badarg(argv[index]); X state = FALSE; X } X break; X default : X badarg(argv[index]); X state = FALSE; X } X } X /* is it an offset? */ X else if ( *argv[index] == '+' ) { X /* yes, must be hexadecimal */ X if ( sscanf(argv[index]+1, "%x", &offset) == 1 ) { X oflag = TRUE; X } X else { X badarg(argv[index]); X state = FALSE; X } X } X /* else it must be a filename */ X else if ( (infile = fopen(argv[index], "r")) == NULL) { X fprintf(stderr, "unable to open %s\n", argv[index]); X } X } X /* was a format specified? */ X if ( hexout ) { X /* does recsize exceed maxsize? */ X if ( recsize > maxsize ) { X fprintf(stderr,"tohex: record size too large\n"); X state = FALSE; X } X } X else { X fprintf(stderr,"tohex: format not specified\n"); X state = FALSE; X } X /* do we have an input file? */ X if ( !infile ) { X fprintf(stderr,"tohex: no input file\n"); X state = FALSE; X } X return ( state ); X} X X/* X * toshex performs the binary to Motorola S-record con- X * version function. The argument "dptr" points to a X * string of bytes to be converted. "count" specifies X * the size of the string, while "addr" specifies the X * starting address for this block of output. Only S2 X * and S8 records are supported (24-bit addresses). X */ Xtoshex(count, addr, dptr) Xint count, addr; Xchar *dptr; X{ X /* adjust address for starting offset */ X addr += offset; X /* and mask off all but 24 bits */ X addr &= 0xFFFFFF; X /* no more bytes ? */ X if ( !count ) { X /* build a termination (S8) record */ X sheader('8',0,offset); X } X else { X /* build a data (S2) record */ X sheader('2',count,addr); X /* output data */ X for ( ; count-- ; ) { X hexpair(*dptr++); X } X } X /* output chksum, Motorola uses 1s complement */ X hexpair(~chksum); X putchar('\n'); X} X X/* X * sheader: called by toshex to generate the header X * of an s-record. Type is either 2 or 8. X */ Xsheader(type,count,addr) Xchar type; Xint count, addr; X{ X putchar('S'); X putchar(type); X chksum = 0; X X /* output record length */ X hexpair(count + 4); X X /* output address */ X hexpair(addr >> 16); X hexpair(addr >> 8); X hexpair(addr); X} X X/* X * toihex performs the binary to Intel-hex conversion X * function. The argument "dptr" points to a string of X * bytes to be converted. "count" specifies the size X * of the string, while "addr" specifies the starting X * address for this block of output. X */ Xtoihex(count, addr, dptr) Xint count, addr; Xchar *dptr; X{ X /* no more data? */ X if ( !count ) { X /* output termination packet */ X printf(":0000000000\n"); X } X else { X /* Start of header character */ X putchar(':'); X /* record length */ X chksum= 0; X hexpair(count); X /* address */ X hexpair(addr >> 8); X hexpair(addr); X /* record type, always 0 */ X hexpair(0); X /* data */ X for ( ; count--; ) { X hexpair(*dptr++); X } X /* checksum, intel uses 2s complement */ X hexpair(-chksum); X putchar('\n'); X } X} X X/* X * totekhex performs the binary to Tek-hex conversion X * function. The argument "dptr" points to a string of X * bytes to be converted. "count" specifies the size X * of the string, while "addr" specifies the starting X * address for this block of output. X */ Xtotekhex(count, addr, dptr) Xint count, addr; Xchar *dptr; X{ X int index; X X /* no more data? */ X if ( !count ) { X /* output termination packet */ X printf("/00000000\n"); X } X else { X chksum = 0; X /* Start of header character */ X putchar('/'); X /* address */ X tekpair(addr >> 8); X tekpair(addr); X tekpair(count); X /* header checksum */ X tekpair(chksum); X chksum = 0; X /* data */ X for ( ; count-- ; ) { X tekpair(*dptr++); X } X /* data checksum */ X tekpair(chksum); X putchar('\n'); X } X} X X/* X * hexpair outputs the two character hex-ascii equivalent X * of the least significant eight bits of its argument. X * It also performs chksum accumulation. This is a common X * support routine for the toshex and toihex functions. X */ Xhexpair(arg) Xint arg; X{ X putchar(digits[(arg >> 4) & 0x0F]); X putchar(digits[arg & 0x0F]); X chksum += arg; X} X X/* X * tekpair: called by totekhex to convert a byte to a X * hex-ascii pair. Tekhex computes the checksum using X * nibbles rather than bytes. X */ Xtekpair(arg) Xint arg; X{ X int lsn, msn; X X msn = (arg >> 4) & 0x0F; X lsn = arg & 0x0F; X putchar(digits[msn]); X putchar(digits[lsn]); X chksum = chksum + lsn + msn; X} X X/* X * usage prints the usage message, a standard part X * of most error messages. X */ Xusage() X{ X fprintf(stderr, X "usage: tohex -{s,i} [-l<length>] [+<offset>] filename\n"); X} X X/* X * badarg prints the rejected argument pointed X * to by str, prepended by an error message. X */ Xbadarg(str) X char *str; X{ X fprintf(stderr,"tohex: invalid argument %s\n", str); X} / echo 'x - makefile' sed 's/^X//' > makefile << '/' XSHELL= /bin/sh XBIN= /usr/lbin XCC= /usr/ghs/compiler/gcc X Xinstall: tohex X install -f $(BIN) tohex X Xtohex: tohex.o X $(CC) -o tohex tohex.o X Xclean: X rm -f tohex.o tohex / echo 'Part 01 of Tohex complete.' exit -=- Rich Kaul kaul@icarus.eng.ohio-state.edu kaul@tut.cis.ohio-state.edu "You must realize that the computer has it in for you. The irrefutable proof of this is that the computer always does what you tell it to do."
alvitar@madhat.UUCP (Phil Harbison) (05/13/88)
In article <178@accelerator.eng.ohio-state.edu> Rich Kaul writes: > > I know this runs under 4BSD and SunOS 3.2-3.4 I am told it will run > under SysV but can't check and it ran under early releases of Xenix. > Tohex runs under versions of SysV that do not use COFF for their binary files. I've thought about doing a COFF version of tohex, but never got around to it. My system is a 68K box running Unisoft Uniplus 5.0 which uses the old a.out format. -- Live: Phil Harbison USPS: 3409 Grassfort Drive, Huntsville, AL 35805-5421 UUCP: {clyde,uunet}!madhat!alvitar PSTN: 205-881-4317 205-830-4310x210