Browse Source

[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>
tags/v1.20.1
Petr Borsodi 5 years ago
parent
commit
de4565cbe7
2 changed files with 78 additions and 1 deletions
  1. 65
    1
      src/util/Option/ROM.pm
  2. 13
    0
      src/util/disrom.pl

+ 65
- 1
src/util/Option/ROM.pm View File

@@ -176,9 +176,10 @@ use constant PCI_LAST_IMAGE => 0x80;
176 176
 use constant PNP_SIGNATURE => '$PnP';
177 177
 use constant UNDI_SIGNATURE => 'UNDI';
178 178
 use constant IPXE_SIGNATURE => 'iPXE';
179
+use constant EFI_SIGNATURE => 0x00000ef1;
179 180
 
180 181
 our @EXPORT_OK = qw ( ROM_SIGNATURE PCI_SIGNATURE PCI_LAST_IMAGE
181
-		      PNP_SIGNATURE UNDI_SIGNATURE IPXE_SIGNATURE );
182
+		      PNP_SIGNATURE UNDI_SIGNATURE IPXE_SIGNATURE EFI_SIGNATURE );
182 183
 our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
183 184
 
184 185
 use constant JMP_SHORT => 0xeb;
@@ -458,6 +459,25 @@ sub ipxe_header {
458 459
 
459 460
 =pod
460 461
 
462
+=item C<< efi_header () >>
463
+
464
+Return a C<Option::ROM::EFI> object representing the ROM's EFI header,
465
+if present.
466
+
467
+=cut
468
+
469
+sub efi_header {
470
+  my $hash = shift;
471
+  my $self = tied(%$hash);
472
+
473
+  my $pci = $hash->pci_header ();
474
+  return undef unless defined $pci;
475
+
476
+  return Option::ROM::EFI->new ( $self, $pci );
477
+}
478
+
479
+=pod
480
+
461 481
 =item C<< next_image () >>
462 482
 
463 483
 Return a C<Option::ROM> object representing the next image within the
@@ -813,4 +833,48 @@ sub fix_checksum {
813 833
   $hash->{checksum} = ( ( $hash->{checksum} - $hash->checksum() ) & 0xff );
814 834
 }
815 835
 
836
+##############################################################################
837
+#
838
+# Option::ROM::EFI
839
+#
840
+##############################################################################
841
+
842
+package Option::ROM::EFI;
843
+
844
+use strict;
845
+use warnings;
846
+use Carp;
847
+use bytes;
848
+
849
+sub new {
850
+  my $class = shift;
851
+  my $rom = shift;
852
+  my $pci = shift;
853
+
854
+  my $hash = {};
855
+  tie %$hash, "Option::ROM::Fields", {
856
+    rom => $rom,
857
+    data => $rom->{data},
858
+    offset => 0x00,
859
+    length => 0x18,
860
+    fields => {
861
+      signature =>		{ offset => 0x00, length => 0x02, pack => "S" },
862
+      init_size =>		{ offset => 0x02, length => 0x02, pack => "S" },
863
+      efi_signature =>		{ offset => 0x04, length => 0x04, pack => "L" },
864
+      efi_subsystem =>		{ offset => 0x08, length => 0x02, pack => "S" },
865
+      efi_machine_type =>	{ offset => 0x0a, length => 0x02, pack => "S" },
866
+      compression_type =>	{ offset => 0x0c, length => 0x02, pack => "S" },
867
+      efi_image_offset =>	{ offset => 0x16, length => 0x02, pack => "S" },
868
+    },
869
+  };
870
+  bless $hash, $class;
871
+
872
+  my $self = tied ( %$hash );
873
+
874
+  return undef unless ( $hash->{efi_signature} == Option::ROM::EFI_SIGNATURE &&
875
+			$pci->{code_type} == 0x03 );
876
+
877
+  return $hash;
878
+}
879
+
816 880
 1;

+ 13
- 0
src/util/disrom.pl View File

@@ -51,6 +51,19 @@ do {
51 51
   printf "  %-16s 0x%04x\n", "PnP header:", $rom->{pnp_header} if ( exists $rom->{pnp_header} );
52 52
   printf "\n";
53 53
 
54
+  my $efi = $rom->efi_header();
55
+  if ( $efi ) {
56
+    printf "EFI header:\n\n";
57
+    printf "  %-16s 0x%04x (%d)\n", "Init size:",
58
+	   $efi->{init_size}, ( $efi->{init_size} * 512 );
59
+    printf "  %-16s 0x%08x\n", "EFI Signature:", $efi->{efi_signature};
60
+    printf "  %-16s 0x%04x\n", "EFI Subsystem:", $efi->{efi_subsystem};
61
+    printf "  %-16s 0x%04x\n", "EFI Machine type:", $efi->{efi_machine_type};
62
+    printf "  %-16s 0x%04x\n", "Compression type:", $efi->{compression_type};
63
+    printf "  %-16s 0x%04x\n", "EFI Image offset:", $efi->{efi_image_offset};
64
+    printf "\n";
65
+  }
66
+
54 67
   my $pci = $rom->pci_header();
55 68
   if ( $pci ) {
56 69
     printf "PCI header:\n\n";

Loading…
Cancel
Save