diff --git a/src/util/catrom.pl b/src/util/catrom.pl index fe37e6b6..da99d7b9 100755 --- a/src/util/catrom.pl +++ b/src/util/catrom.pl @@ -3,46 +3,27 @@ use warnings; use strict; -use bytes; +use FindBin; +use lib "$FindBin::Bin"; +use Option::ROM qw ( :all ); -use constant MAX_ROM_LEN => 1024*1024; -use constant PCI_OFF => 0x18; -use constant INDICATOR_OFF => 0x15; - -my $total_len = 0; my @romfiles = @ARGV or die "Usage: $0 rom-file-1 rom-file-2 ... > multi-rom-file\n"; while ( my $romfile = shift @romfiles ) { - my $last = @romfiles ? 0 : 1; - open ROM, "<$romfile" or die "Could not open $romfile: $!\n"; - my $len = read ( ROM, my $romdata, MAX_ROM_LEN ) - or die "Could not read $romfile: $!\n"; - close ROM; + # Read ROM file + my $rom = new Option::ROM; + $rom->load ( $romfile ); - die "$romfile is not a ROM file\n" - unless substr ( $romdata, 0, 2 ) eq "\x55\xAA"; + # Tag final image as non-final in all except the final ROM + if ( @romfiles ) { + my $image = $rom; + $image = $image->next_image() while $image->next_image(); + $image->pci_header->{last_image} &= ~PCI_LAST_IMAGE; + $image->fix_checksum(); + } - ( my $checklen ) = unpack ( 'C', substr ( $romdata, 2, 1 ) ); - $checklen *= 512; - die "$romfile has incorrect length field $checklen (should be $len)\n" - unless $len == $checklen; - - ( my $pci ) = unpack ( 'v', substr ( $romdata, PCI_OFF, 2 ) ); - die "Invalid PCI offset field in $romfile\n" - if $pci >= $len; - die "No PCIR signature in $romfile\n" - unless substr ( $romdata, $pci, 4 ) eq "PCIR"; - - ( my $indicator ) = - unpack ( 'C', substr ( $romdata, $pci + INDICATOR_OFF, 1 ) ); - my $msg = sprintf ( "$romfile: indicator was %02x, ", $indicator ); - $indicator &= ! ( 1 << 7 ); - $indicator |= ( $last << 7 ); - $msg .= sprintf ( "now %02x\n", $indicator ); - substr ( $romdata, $pci + INDICATOR_OFF, 1 ) = pack ( 'C', $indicator ); - warn $msg; - - print $romdata; + # Write ROM file to STDOUT + $rom->save ( "-" ); }