From 69fa49428088ccefd438a0e87b1111a727a8b702 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 15 Aug 2012 13:18:46 +0100 Subject: [util] Display UNDI ROM header in disrom.pl Requested-by: Daniel Wyatt Signed-off-by: Michael Brown --- src/util/Option/ROM.pm | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/util/disrom.pl | 16 ++++++++++ 2 files changed, 96 insertions(+) (limited to 'src/util') diff --git a/src/util/Option/ROM.pm b/src/util/Option/ROM.pm index bf704cad..fb37ce4b 100644 --- a/src/util/Option/ROM.pm +++ b/src/util/Option/ROM.pm @@ -396,6 +396,25 @@ sub pnp_header { =pod +=item C<< undi_header () >> + +Return a C object representing the ROM's UNDI header, +if present. + +=cut + +sub undi_header { + my $hash = shift; + my $self = tied(%$hash); + + my $offset = $hash->{undi_header}; + return undef unless $offset != 0; + + return Option::ROM::UNDI->new ( $self->{data}, $offset ); +} + +=pod + =item C<< ipxe_header () >> Return a C object representing the ROM's iPXE @@ -591,6 +610,67 @@ sub product { return unpack ( "Z*", $raw ); } +############################################################################## +# +# Option::ROM::UNDI +# +############################################################################## + +package Option::ROM::UNDI; + +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 => 0x16, + fields => { + signature => { offset => 0x00, length => 0x04, pack => "a4" }, + struct_length => { offset => 0x04, length => 0x01, pack => "C" }, + checksum => { offset => 0x05, length => 0x01, pack => "C" }, + struct_revision =>{ offset => 0x06, length => 0x01, pack => "C" }, + version_revision =>{ offset => 0x07, length => 0x01, pack => "C" }, + version_minor => { offset => 0x08, length => 0x01, pack => "C" }, + version_major => { offset => 0x09, length => 0x01, pack => "C" }, + loader_entry => { offset => 0x0a, length => 0x02, pack => "S" }, + stack_size => { offset => 0x0c, length => 0x02, pack => "S" }, + data_size => { offset => 0x0e, length => 0x02, pack => "S" }, + code_size => { offset => 0x10, length => 0x02, pack => "S" }, + bus_type => { offset => 0x12, length => 0x04, pack => "a4" }, + }, + }; + 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 ); +} + ############################################################################## # # Option::ROM::iPXE diff --git a/src/util/disrom.pl b/src/util/disrom.pl index 87138686..574957ac 100755 --- a/src/util/disrom.pl +++ b/src/util/disrom.pl @@ -85,6 +85,22 @@ do { printf "\n"; } + my $undi = $rom->undi_header(); + if ( $undi ) { + printf "UNDI header:\n\n"; + printf " %-16s %s\n", "Signature:", $undi->{signature}; + printf " %-16s 0x%02x (%s0x%02x)\n", "Checksum:", $undi->{checksum}, + ( ( $undi->checksum == 0 ) ? "" : "INCORRECT: " ), $undi->checksum; + printf " %-16s %d.%d.%d\n", "UNDI version:", $undi->{version_major}, + $undi->{version_minor}, $undi->{version_revision}; + printf " %-16s 0x%04x\n", "Loader entry:", $undi->{loader_entry}; + printf " %-16s 0x%04x\n", "Stack size:", $undi->{stack_size}; + printf " %-16s 0x%04x\n", "Data size:", $undi->{data_size}; + printf " %-16s 0x%04x\n", "Code size:", $undi->{code_size}; + printf " %-16s %s\n", "Bus type:", $undi->{bus_type}; + printf "\n"; + } + my $ipxe = $rom->ipxe_header(); if ( $ipxe ) { printf "iPXE header:\n\n"; -- cgit v1.2.3-55-g7522