1 /* $NetBSD: genprom.c,v 1.4 2002/07/20 08:36:18 grant Exp $ */ 2 3 /* 4 * mainly from netbsd:sys/arch/i386/netboot/genprom.c 5 */ 6 7 /* 8 * Read a binary image of a bios extension, generate the 9 * appropriate block count and checksum and write them 10 * into the rom image (replacing 2nd and 5th bytes) 11 * The binary image should be sized before being filtered 12 * through this routine. 13 */ 14 15 #include <stdio.h> 16 #include <err.h> 17 #include <string.h> 18 19 #define PROM_SIZE 0x10000 /* max */ 20 21 int 22 main(argc, argv) 23 int argc; 24 char **argv; 25 { 26 char w[PROM_SIZE]; 27 int i, sum; 28 int romsize; 29 unsigned short ck16; 30 31 if (argc > 1) { 32 if (sscanf(argv[1], "%d", &romsize) != 1) { 33 errx(1, "bad arg"); 34 } 35 } else { 36 errx(1, "arg: romsize / bytes"); 37 } 38 39 memset(w, 0x0, PROM_SIZE); 40 i = fread(w, 1, PROM_SIZE, stdin); 41 42 fprintf(stderr, "bios extension size: %d (0x%x), read %d bytes\n", 43 romsize, romsize, i); 44 45 if (i > romsize) 46 errx(1, "read longer than expected"); 47 48 w[2] = romsize / 512; /* BIOS extension size */ 49 50 i = w[0x18] + (w[0x19] << 8); /* if this is a PCI ROM, this is the 51 * offset to the "PCI data structure" */ 52 if ((i < romsize - 0x18) && (w[i] == 'P') && (w[i + 1] == 'C') 53 && (w[i + 2] == 'I') && (w[i + 3] == 'R')) { 54 fprintf(stderr, "PCI Data Structure found\n"); 55 w[i + 0x10] = romsize / 512; /* BIOS extension size again */ 56 } 57 for (sum = 0, i = 0; i < romsize; i++) { 58 sum += w[i]; 59 } 60 w[5] = -sum; /* left free for checksum adjustment */ 61 62 /* calculate CRC as used by PROM programmers */ 63 for (ck16 = 0, i = 0; i < romsize; i++) 64 ck16 += (unsigned char) w[i]; 65 fprintf(stderr, "ROM CRC: 0x%04x\n", ck16); 66 67 fwrite(w, 1, romsize, stdout); 68 return (0); 69 } 70