diff options
author | Michael Brown | 2012-07-23 18:41:38 +0200 |
---|---|---|
committer | Michael Brown | 2012-07-23 18:57:40 +0200 |
commit | 5de45cd3da2308a6db37fb7c0822c9fdadf00d96 (patch) | |
tree | e33ac06ab9d117ea86644d2362660e84b7727c2f /src/util/Option | |
parent | [contrib] Fix rom-o-matic git version number issues (diff) | |
download | ipxe-5de45cd3da2308a6db37fb7c0822c9fdadf00d96.tar.gz ipxe-5de45cd3da2308a6db37fb7c0822c9fdadf00d96.tar.xz ipxe-5de45cd3da2308a6db37fb7c0822c9fdadf00d96.zip |
[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>
Diffstat (limited to 'src/util/Option')
-rw-r--r-- | src/util/Option/ROM.pm | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/src/util/Option/ROM.pm b/src/util/Option/ROM.pm index fdc5e4ae..82d65426 100644 --- a/src/util/Option/ROM.pm +++ b/src/util/Option/ROM.pm @@ -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; |