Skip to content

Commit

Permalink
[util] Add support for EFI ROM images
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
pe-bo authored and mcb30 committed Jan 21, 2019
1 parent 3f4c179 commit de4565c
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
66 changes: 65 additions & 1 deletion src/util/Option/ROM.pm
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
13 changes: 13 additions & 0 deletions src/util/disrom.pl
Expand Up @@ -51,6 +51,19 @@
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";
Expand Down

0 comments on commit de4565c

Please sign in to comment.