[romprefix] Report a pessimistic runtime size estimate

PCI3.0 allows us to report a "runtime size" which can be smaller than
the actual ROM size.  On systems that support PMM our runtime size
will be small (~2.5kB), which helps to conserve the limited option ROM
space.  However, there is no guarantee that the PMM allocation will
succeed, and so we need to report the worst-case runtime size in the
PCI header.

Move the "shrunk ROM size" field from the PCI header to a new "iPXE
ROM header", allowing it to be accessed by ROM-manipulation utilities
such as disrom.pl.

Reported-by: Anton D. Kachalov <mouse@yandex-team.ru>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2012-07-23 17:41:38 +01:00
parent ee3636370d
commit 5de45cd3da
4 changed files with 111 additions and 6 deletions
+76 -1
View File
@@ -172,9 +172,10 @@ use constant ROM_SIGNATURE => 0xaa55;
use constant PCI_SIGNATURE => 'PCIR';
use constant PCI_LAST_IMAGE => 0x80;
use constant PNP_SIGNATURE => '$PnP';
use constant IPXE_SIGNATURE => 'iPXE';
our @EXPORT_OK = qw ( ROM_SIGNATURE PCI_SIGNATURE PCI_LAST_IMAGE
PNP_SIGNATURE );
PNP_SIGNATURE IPXE_SIGNATURE );
our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
use constant JMP_SHORT => 0xeb;
@@ -232,6 +233,7 @@ sub new {
init => { offset => 0x03, length => 0x03,
pack => \&pack_init, unpack => \&unpack_init },
checksum => { offset => 0x06, length => 0x01, pack => "C" },
ipxe_header => { offset => 0x10, length => 0x02, pack => "S" },
bofm_header => { offset => 0x14, length => 0x02, pack => "S" },
undi_header => { offset => 0x16, length => 0x02, pack => "S" },
pci_header => { offset => 0x18, length => 0x02, pack => "S" },
@@ -390,6 +392,25 @@ sub pnp_header {
=pod
=item C<< ipxe_header () >>
Return a C<Option::ROM::iPXE> object representing the ROM's iPXE
header, if present.
=cut
sub ipxe_header {
my $hash = shift;
my $self = tied(%$hash);
my $offset = $hash->{ipxe_header};
return undef unless $offset != 0;
return Option::ROM::iPXE->new ( $self->{data}, $offset );
}
=pod
=item C<< next_image () >>
Return a C<Option::ROM> object representing the next image within the
@@ -566,4 +587,58 @@ sub product {
return unpack ( "Z*", $raw );
}
##############################################################################
#
# Option::ROM::iPXE
#
##############################################################################
package Option::ROM::iPXE;
use strict;
use warnings;
use Carp;
use bytes;
sub new {
my $class = shift;
my $data = shift;
my $offset = shift;
my $hash = {};
tie %$hash, "Option::ROM::Fields", {
data => $data,
offset => $offset,
length => 0x06,
fields => {
signature => { offset => 0x00, length => 0x04, pack => "a4" },
struct_length => { offset => 0x04, length => 0x01, pack => "C" },
checksum => { offset => 0x05, length => 0x01, pack => "C" },
shrunk_length => { offset => 0x06, length => 0x01, pack => "C" },
build_id => { offset => 0x08, length => 0x04, pack => "L" },
},
};
bless $hash, $class;
# Retrieve true length of structure
my $self = tied ( %$hash );
$self->{length} = $hash->{struct_length};
return $hash;
}
sub checksum {
my $hash = shift;
my $self = tied(%$hash);
return $self->checksum();
}
sub fix_checksum {
my $hash = shift;
my $self = tied(%$hash);
$hash->{checksum} = ( ( $hash->{checksum} - $hash->checksum() ) & 0xff );
}
1;