Skip to content

Commit

Permalink
[romprefix] Report a pessimistic runtime size estimate
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mcb30 committed Jul 23, 2012
1 parent ee36363 commit 5de45cd
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 6 deletions.
28 changes: 23 additions & 5 deletions src/arch/i386/prefix/romprefix.S
Expand Up @@ -63,6 +63,8 @@ romheader_size: .byte 0 /* Size in 512-byte blocks */
jmp init /* Initialisation vector */
checksum:
.byte 0
.org 0x10
.word ipxeheader
.org 0x16
.word undiheader
.org 0x18
Expand All @@ -78,9 +80,6 @@ checksum:
.long 0
.previous

build_id:
.long _build_id /* Randomly-generated build ID */

pciheader:
.ascii "PCIR" /* Signature */
.word pci_vendor_id /* Vendor identification */
Expand All @@ -106,7 +105,7 @@ pciheader_runtime_length:
.long pciheader_image_length
.long 512
.long 0
.ascii "ADHW"
.ascii ZINFO_TYPE_ADxW
.long pciheader_runtime_length
.long 512
.long 0
Expand Down Expand Up @@ -175,6 +174,25 @@ undiheader:
.equ undiheader_len, . - undiheader
.size undiheader, . - undiheader

ipxeheader:
.ascii "iPXE" /* Signature */
.byte ipxeheader_len /* Length of structure */
.byte 0 /* Checksum */
shrunk_rom_size:
.byte 0 /* Shrunk size (in 512-byte blocks) */
.byte 0 /* Reserved */
build_id:
.long _build_id /* Randomly-generated build ID */
.equ ipxeheader_len, . - ipxeheader
.size ipxeheader, . - ipxeheader

.section ".zinfo.fixup", "a", @progbits /* Compressor fixups */
.ascii "ADHB"
.long shrunk_rom_size
.long 512
.long 0
.previous

/* Initialisation (called once during POST)
*
* Determine whether or not this is a PnP system via a signature
Expand Down Expand Up @@ -354,7 +372,7 @@ pmm_scan:
addr32 rep movsl /* PMM presence implies flat real mode */
popw %es
/* Shrink ROM */
movw pciheader_runtime_length, %ax
movb shrunk_rom_size, %al
movb %al, romheader_size
1: /* Allocate decompression PMM block. Round up the size to the
* nearest 128kB and use the size within the PMM handle; this
Expand Down
77 changes: 76 additions & 1 deletion src/util/Option/ROM.pm
Expand Up @@ -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;
Expand Down Expand Up @@ -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" },
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
11 changes: 11 additions & 0 deletions src/util/disrom.pl
Expand Up @@ -85,4 +85,15 @@
printf "\n";
}

my $ipxe = $rom->ipxe_header();
if ( $ipxe ) {
printf "iPXE header:\n\n";
printf " %-16s 0x%02x (%s0x%02x)\n", "Checksum:", $ipxe->{checksum},
( ( $ipxe->checksum == 0 ) ? "" : "INCORRECT: " ), $ipxe->checksum;
printf " %-16s 0x%02x (%d)\n", "Shrunk length:",
$ipxe->{shrunk_length}, ( $ipxe->{shrunk_length} * 512 );
printf " %-16s 0x%08x\n", "Build ID:", $ipxe->{build_id};
printf "\n";
}

} while ( $rom = $rom->next_image );
1 change: 1 addition & 0 deletions src/util/fixrom.pl
Expand Up @@ -32,6 +32,7 @@
my $image = $rom;
while ( $image ) {
$image->pnp_header->fix_checksum() if $image->pnp_header;
$image->ipxe_header->fix_checksum() if $image->ipxe_header;
$image->fix_checksum();
$image = $image->next_image();
}
Expand Down

0 comments on commit 5de45cd

Please sign in to comment.