/*
* makehex.c - Generate hex boot image file
*
* Copyright (C) 1998-2003 Gero Kuhlmann <gero@gkminix.han.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: makehex.c,v 1.4 2003/01/25 23:29:42 gkminix Exp $
*/
#include <common.h>
#include <nblib.h>
#include "makerom.h"
/* Size of one hex record */
#define IHEX_RECSIZE 16
#define MHEX_RECSIZE 16
#define THEX_RECSIZE 16
/*
* Read one byte from temporary rom image file
*/
static int readbyte(romimage)
int romimage;
{
static __u8 buf[BLKSIZE];
static int buflen = 0;
static int bufofs = 0;
if (bufofs >= buflen) {
if ((buflen = nbread(buf, BLKSIZE, romimage)) == 0)
return(EOF);
bufofs = 0;
}
return(buf[bufofs++]);
}
/*
* Return a nibble in ASCII hex
*/
static char hex(c)
int c;
{
if((c &= 0x000f) < 10)
c += '0';
else
c += 'A' - 10;
return(c);
}
/*
* Convert bootrom image to Intel hex format
*/
static void makeihex(romimage, outfile)
int romimage;
FILE *outfile;
{
char *line, buffer[128];
int address = 0;
int c = 1;
int sum, i;
/* Process the boot rom image */
fprintf(outfile, "# netboot bootrom image (Intel hex)\n");
fprintf(outfile, "# created with %s, %s\n", progname, VERSION);
fprintf(outfile, ":020000020000FC\n");
while (c != EOF) {
sum = 0;
line = buffer;
for (i = 0; i < IHEX_RECSIZE && (c = readbyte(romimage)) != EOF; i++) {
*line++ = hex(c >> 4);
*line++ = hex(c);
sum += c; /* checksum each character */
}
*line = '\0';
if (i) {
sum += (address >> 8) & 0xff; /* checksum high address byte */
sum += address & 0xff; /* checksum low address byte */
sum += i; /* checksum record byte count */
fprintf(outfile, ":%02X%04X00%s%02X\n", i,
(address & 0xffff), buffer, ((0 - sum) & 0xff));
}
address += i;
}
fprintf(outfile, ":00000001FF\n"); /* end record */
}
/*
* Convert bootrom image to Motorola hex format
*/
static void makemhex(romimage, outfile)
int romimage;
FILE *outfile;
{
char *line, buffer[128];
int address = 0;
int c = 1;
int sum, i;
/* Process the boot rom image */
fprintf(outfile, "# netboot bootrom image (Motorola hex)\n");
fprintf(outfile, "# created with %s, %s\n", progname, VERSION);
while (c != EOF) {
sum = 0;
line = buffer;
for (i = 0; i < MHEX_RECSIZE && (c = readbyte(romimage)) != EOF; i++) {
*line++ = hex(c >> 4);
*line++ = hex(c);
sum += c; /* checksum each character */
}
*line = '\0';
if (i) {
sum += (address >> 8) & 0xff; /* checksum high address byte */
sum += address & 0xff; /* checksum low address byte */
sum += i + 3; /* checksum record byte count */
fprintf(outfile, "S1%02X%04X%s%02X\n", i + 3,
(address & 0xffff), buffer, ((0 - sum) & 0xff));
}
address += i;
}
fprintf(outfile, "S9030000FD\n"); /* end record */
}
/*
* Convert bootrom image to Tektronix hex format
*/
static void makethex(romimage, outfile)
int romimage;
FILE *outfile;
{
char *line, buffer[128];
int address = 0;
int c = 1;
int psum, dsum, i;
/* Process the boot rom image */
fprintf(outfile, "# netboot bootrom image (Tektronix hex)\n");
fprintf(outfile, "# created with %s, %s\n", progname, VERSION);
while (c != EOF) {
psum = dsum = 0;
line = buffer;
for (i = 0; i < THEX_RECSIZE && (c = readbyte(romimage)) != EOF; i++) {
*line++ = hex(c >> 4);
*line++ = hex(c);
dsum += (c & 0x0f) + ((c >> 4) & 0x0f);
}
*line = '\0';
if (i) {
psum += (i & 0x0f) + ((i >> 4) & 0x0f);
psum += (address & 0x0f) + ((address >> 4) & 0x0f);
psum += ((address >> 8) & 0x0f) + ((address >> 12) & 0x0f);
fprintf(outfile, "/%04X%02X%02X%s%02X\n", (address & 0xffff), i,
(psum & 0xff), buffer, (dsum & 0xff));
}
address += i;
}
fprintf(outfile, "/00000000\n"); /* end record */
}
/*
* Make hex output file
*/
void makehex(fname, tempfile, outtype)
char *fname;
int tempfile;
int outtype;
{
FILE *outfile;
/* Open the output file */
if ((outfile = fopen(fname, "w")) == NULL) {
prnerr1("unable to create %s", fname);
exit(EXIT_CREATE);
}
/* Generate the appropriate hex output */
assert(outtype == OUT_IHEX || outtype == OUT_MHEX || outtype == OUT_THEX);
switch (outtype) {
case OUT_IHEX:
makeihex(tempfile, outfile);
break;
case OUT_MHEX:
makemhex(tempfile, outfile);
break;
case OUT_THEX:
makethex(tempfile, outfile);
break;
}
/* Close output file */
fclose(outfile);
}
syntax highlighted by Code2HTML, v. 0.9.1