/* * makehex.c - Generate hex boot image file * * Copyright (C) 1998-2003 Gero Kuhlmann * * 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 #include #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); }