/* $NetBSD: genprom.c,v 1.8 2007/12/26 10:19:41 dogcow Exp $ */ /* * mainly from netbsd:sys/arch/i386/netboot/genprom.c */ /* * Read a binary image of a bios extension, generate the * appropriate block count and checksum and write them * into the rom image (replacing 2nd and 5th bytes) * The binary image should be sized before being filtered * through this routine. */ #include #include #include #define PROM_SIZE 0x10000 /* max */ static char *progname; static void bail(const char *); int main(int, char **); static void bail(const char *msg) { (void)fprintf(stderr, "%s: %s\n", progname, msg); exit(1); } int main(int argc, char **argv) { char w[PROM_SIZE]; int i, sum; int romsize; unsigned short ck16; if ((progname = strrchr(argv[0], '/')) != NULL) progname++; else progname = argv[0]; if (argc > 1) { if (sscanf(argv[1], "%d", &romsize) != 1) bail("bad arg"); } else { bail("arg: romsize / bytes"); } (void)memset(w, 0x0, PROM_SIZE); i = fread(w, 1, PROM_SIZE, stdin); (void)fprintf(stderr, "bios extension size: %d (0x%x), read %d bytes\n", romsize, romsize, i); if (i > romsize) bail("read longer than expected"); w[2] = romsize / 512; /* BIOS extension size */ i = w[0x18] + (w[0x19] << 8); /* if this is a PCI ROM, this is the * offset to the "PCI data structure" */ if ((i < romsize - 0x18) && (w[i] == 'P') && (w[i + 1] == 'C') && (w[i + 2] == 'I') && (w[i + 3] == 'R')) { fprintf(stderr, "PCI Data Structure found\n"); w[i + 0x10] = romsize / 512; /* BIOS extension size again */ } for (sum = 0, i = 0; i < romsize; i++) sum += w[i]; w[5] = -sum; /* left free for checksum adjustment */ /* calculate CRC as used by PROM programmers */ for (ck16 = 0, i = 0; i < romsize; i++) ck16 += (unsigned char) w[i]; (void)fprintf(stderr, "ROM CRC: 0x%04x\n", ck16); (void)fwrite(w, 1, romsize, stdout); return (0); }