mirror of https://github.com/ipxe/ipxe.git
[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>pull/88/head
parent
3f4c179a14
commit
de4565cbe7
|
@ -176,9 +176,10 @@ use constant PCI_LAST_IMAGE => 0x80;
|
||||||
use constant PNP_SIGNATURE => '$PnP';
|
use constant PNP_SIGNATURE => '$PnP';
|
||||||
use constant UNDI_SIGNATURE => 'UNDI';
|
use constant UNDI_SIGNATURE => 'UNDI';
|
||||||
use constant IPXE_SIGNATURE => 'iPXE';
|
use constant IPXE_SIGNATURE => 'iPXE';
|
||||||
|
use constant EFI_SIGNATURE => 0x00000ef1;
|
||||||
|
|
||||||
our @EXPORT_OK = qw ( ROM_SIGNATURE PCI_SIGNATURE PCI_LAST_IMAGE
|
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 ] );
|
our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
|
||||||
|
|
||||||
use constant JMP_SHORT => 0xeb;
|
use constant JMP_SHORT => 0xeb;
|
||||||
|
@ -458,6 +459,25 @@ sub ipxe_header {
|
||||||
|
|
||||||
=pod
|
=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 () >>
|
=item C<< next_image () >>
|
||||||
|
|
||||||
Return a C<Option::ROM> object representing the next image within the
|
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 );
|
$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;
|
1;
|
||||||
|
|
|
@ -51,6 +51,19 @@ do {
|
||||||
printf " %-16s 0x%04x\n", "PnP header:", $rom->{pnp_header} if ( exists $rom->{pnp_header} );
|
printf " %-16s 0x%04x\n", "PnP header:", $rom->{pnp_header} if ( exists $rom->{pnp_header} );
|
||||||
printf "\n";
|
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();
|
my $pci = $rom->pci_header();
|
||||||
if ( $pci ) {
|
if ( $pci ) {
|
||||||
printf "PCI header:\n\n";
|
printf "PCI header:\n\n";
|
||||||
|
|
Loading…
Reference in New Issue