1 /* $NetBSD: genprom.c,v 1.7 2007/12/25 18:33:33 perry Exp $ */
4 * mainly from netbsd:sys/arch/i386/netboot/genprom.c
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.
19 #define PROM_SIZE 0x10000 /* max */
21 static char *progname
;
23 static void bail(const char *);
24 int main(int, char **);
29 (void)fprintf(stderr
, "%s: %s\n", progname
, msg
);
34 main(int argc
, char **argv
)
41 if ((progname
= strrchr(argv
[0], '/')) != NULL
)
47 if (sscanf(argv
[1], "%d", &romsize
) != 1)
50 bail("arg: romsize / bytes");
53 (void)memset(w
, 0x0, PROM_SIZE
);
54 i
= fread(w
, 1, PROM_SIZE
, stdin
);
56 (void)fprintf(stderr
, "bios extension size: %d (0x%x), read %d bytes\n",
60 bail("read longer than expected");
62 w
[2] = romsize
/ 512; /* BIOS extension size */
64 i
= w
[0x18] + (w
[0x19] << 8); /* if this is a PCI ROM, this is the
65 * offset to the "PCI data structure" */
66 if ((i
< romsize
- 0x18) && (w
[i
] == 'P') && (w
[i
+ 1] == 'C')
67 && (w
[i
+ 2] == 'I') && (w
[i
+ 3] == 'R')) {
68 fprintf(stderr
, "PCI Data Structure found\n");
69 w
[i
+ 0x10] = romsize
/ 512; /* BIOS extension size again */
71 for (sum
= 0, i
= 0; i
< romsize
; i
++)
74 w
[5] = -sum
; /* left free for checksum adjustment */
76 /* calculate CRC as used by PROM programmers */
77 for (ck16
= 0, i
= 0; i
< romsize
; i
++)
78 ck16
+= (unsigned char) w
[i
];
79 (void)fprintf(stderr
, "ROM CRC: 0x%04x\n", ck16
);
81 (void)fwrite(w
, 1, romsize
, stdout
);