summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arch/i386/prefix/romprefix.S28
-rw-r--r--src/util/Option/ROM.pm77
-rwxr-xr-xsrc/util/disrom.pl11
-rwxr-xr-xsrc/util/fixrom.pl1
4 files changed, 111 insertions, 6 deletions
diff --git a/src/arch/i386/prefix/romprefix.S b/src/arch/i386/prefix/romprefix.S
index 2719a70a..2b4c20b8 100644
--- a/src/arch/i386/prefix/romprefix.S
+++ b/src/arch/i386/prefix/romprefix.S
@@ -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
@@ -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 */
@@ -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
@@ -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
@@ -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
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;
diff --git a/src/util/disrom.pl b/src/util/disrom.pl
index c133c26a..87138686 100755
--- a/src/util/disrom.pl
+++ b/src/util/disrom.pl
@@ -85,4 +85,15 @@ do {
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 );
diff --git a/src/util/fixrom.pl b/src/util/fixrom.pl
index c84e2cf2..8987b512 100755
--- a/src/util/fixrom.pl
+++ b/src/util/fixrom.pl
@@ -32,6 +32,7 @@ foreach my $romfile ( @romfiles ) {
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();
}