summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Borsodi2019-01-16 17:37:58 +0100
committerMichael Brown2019-01-21 12:58:02 +0100
commitde4565cbe76ea9f7913a01f331be3ee901bb6e17 (patch)
tree3ea69ee18d11142e9f841281e350b6ab665368eb
parent[util] Improve processing of ROM images in Option::ROM (diff)
downloadipxe-de4565cbe76ea9f7913a01f331be3ee901bb6e17.tar.gz
ipxe-de4565cbe76ea9f7913a01f331be3ee901bb6e17.tar.xz
ipxe-de4565cbe76ea9f7913a01f331be3ee901bb6e17.zip
[util] Add support for EFI ROM images
The Option::ROM module recognizes and checks EFI header of image. The disrom.pl utility dumps this header if is present. Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/util/Option/ROM.pm66
-rwxr-xr-xsrc/util/disrom.pl13
2 files changed, 78 insertions, 1 deletions
diff --git a/src/util/Option/ROM.pm b/src/util/Option/ROM.pm
index 7bbd6986..51831adf 100644
--- a/src/util/Option/ROM.pm
+++ b/src/util/Option/ROM.pm
@@ -176,9 +176,10 @@ use constant PCI_LAST_IMAGE => 0x80;
use constant PNP_SIGNATURE => '$PnP';
use constant UNDI_SIGNATURE => 'UNDI';
use constant IPXE_SIGNATURE => 'iPXE';
+use constant EFI_SIGNATURE => 0x00000ef1;
our @EXPORT_OK = qw ( ROM_SIGNATURE PCI_SIGNATURE PCI_LAST_IMAGE
- PNP_SIGNATURE UNDI_SIGNATURE IPXE_SIGNATURE );
+ PNP_SIGNATURE UNDI_SIGNATURE IPXE_SIGNATURE EFI_SIGNATURE );
our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
use constant JMP_SHORT => 0xeb;
@@ -458,6 +459,25 @@ sub ipxe_header {
=pod
+=item C<< efi_header () >>
+
+Return a C<Option::ROM::EFI> object representing the ROM's EFI header,
+if present.
+
+=cut
+
+sub efi_header {
+ my $hash = shift;
+ my $self = tied(%$hash);
+
+ my $pci = $hash->pci_header ();
+ return undef unless defined $pci;
+
+ return Option::ROM::EFI->new ( $self, $pci );
+}
+
+=pod
+
=item C<< next_image () >>
Return a C<Option::ROM> object representing the next image within the
@@ -813,4 +833,48 @@ sub fix_checksum {
$hash->{checksum} = ( ( $hash->{checksum} - $hash->checksum() ) & 0xff );
}
+##############################################################################
+#
+# Option::ROM::EFI
+#
+##############################################################################
+
+package Option::ROM::EFI;
+
+use strict;
+use warnings;
+use Carp;
+use bytes;
+
+sub new {
+ my $class = shift;
+ my $rom = shift;
+ my $pci = shift;
+
+ my $hash = {};
+ tie %$hash, "Option::ROM::Fields", {
+ rom => $rom,
+ data => $rom->{data},
+ offset => 0x00,
+ length => 0x18,
+ fields => {
+ signature => { offset => 0x00, length => 0x02, pack => "S" },
+ init_size => { offset => 0x02, length => 0x02, pack => "S" },
+ efi_signature => { offset => 0x04, length => 0x04, pack => "L" },
+ efi_subsystem => { offset => 0x08, length => 0x02, pack => "S" },
+ efi_machine_type => { offset => 0x0a, length => 0x02, pack => "S" },
+ compression_type => { offset => 0x0c, length => 0x02, pack => "S" },
+ efi_image_offset => { offset => 0x16, length => 0x02, pack => "S" },
+ },
+ };
+ bless $hash, $class;
+
+ my $self = tied ( %$hash );
+
+ return undef unless ( $hash->{efi_signature} == Option::ROM::EFI_SIGNATURE &&
+ $pci->{code_type} == 0x03 );
+
+ return $hash;
+}
+
1;
diff --git a/src/util/disrom.pl b/src/util/disrom.pl
index 71eee590..6b2b3073 100755
--- a/src/util/disrom.pl
+++ b/src/util/disrom.pl
@@ -51,6 +51,19 @@ do {
printf " %-16s 0x%04x\n", "PnP header:", $rom->{pnp_header} if ( exists $rom->{pnp_header} );
printf "\n";
+ my $efi = $rom->efi_header();
+ if ( $efi ) {
+ printf "EFI header:\n\n";
+ printf " %-16s 0x%04x (%d)\n", "Init size:",
+ $efi->{init_size}, ( $efi->{init_size} * 512 );
+ printf " %-16s 0x%08x\n", "EFI Signature:", $efi->{efi_signature};
+ printf " %-16s 0x%04x\n", "EFI Subsystem:", $efi->{efi_subsystem};
+ printf " %-16s 0x%04x\n", "EFI Machine type:", $efi->{efi_machine_type};
+ printf " %-16s 0x%04x\n", "Compression type:", $efi->{compression_type};
+ printf " %-16s 0x%04x\n", "EFI Image offset:", $efi->{efi_image_offset};
+ printf "\n";
+ }
+
my $pci = $rom->pci_header();
if ( $pci ) {
printf "PCI header:\n\n";