8
use constant MAX_ROM_LEN => 1024*1024;
9
use constant PCI_OFF => 0x18;
10
use constant INDICATOR_OFF => 0x15;
7
use lib "$FindBin::Bin";
8
use Option::ROM qw ( :all );
13
10
my @romfiles = @ARGV
14
11
or die "Usage: $0 rom-file-1 rom-file-2 ... > multi-rom-file\n";
16
13
while ( my $romfile = shift @romfiles ) {
17
my $last = @romfiles ? 0 : 1;
19
open ROM, "<$romfile" or die "Could not open $romfile: $!\n";
20
my $len = read ( ROM, my $romdata, MAX_ROM_LEN )
21
or die "Could not read $romfile: $!\n";
24
die "$romfile is not a ROM file\n"
25
unless substr ( $romdata, 0, 2 ) eq "\x55\xAA";
27
( my $checklen ) = unpack ( 'C', substr ( $romdata, 2, 1 ) );
29
die "$romfile has incorrect length field $checklen (should be $len)\n"
30
unless $len == $checklen;
32
( my $pci ) = unpack ( 'v', substr ( $romdata, PCI_OFF, 2 ) );
33
die "Invalid PCI offset field in $romfile\n"
35
die "No PCIR signature in $romfile\n"
36
unless substr ( $romdata, $pci, 4 ) eq "PCIR";
39
unpack ( 'C', substr ( $romdata, $pci + INDICATOR_OFF, 1 ) );
40
my $msg = sprintf ( "$romfile: indicator was %02x, ", $indicator );
41
$indicator &= ! ( 1 << 7 );
42
$indicator |= ( $last << 7 );
43
$msg .= sprintf ( "now %02x\n", $indicator );
44
substr ( $romdata, $pci + INDICATOR_OFF, 1 ) = pack ( 'C', $indicator );
16
my $rom = new Option::ROM;
17
$rom->load ( $romfile );
19
# Tag final image as non-final in all except the final ROM
22
$image = $image->next_image() while $image->next_image();
23
$image->pci_header->{last_image} &= ~PCI_LAST_IMAGE;
24
$image->fix_checksum();
27
# Write ROM file to STDOUT