2016-12-01 18:57:35 +00:00
|
|
|
#!/usr/bin/perl
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
|
|
|
|
undef $/;
|
|
|
|
my $rom = <>;
|
|
|
|
my $base = 0xFFFFFFFF - length($rom) + 1;
|
|
|
|
printf "ROM len: %08x\n", length($rom);
|
|
|
|
printf "ROM base: %08x\n", $base;
|
|
|
|
|
|
|
|
sub uint32
|
|
|
|
{
|
|
|
|
my $offset = shift;
|
|
|
|
return unpack("V", substr($rom, $offset - $base, 4));
|
|
|
|
}
|
|
|
|
|
|
|
|
sub uint64
|
|
|
|
{
|
|
|
|
my $offset = shift;
|
|
|
|
return unpack("Q", substr($rom, $offset - $base, 8));
|
|
|
|
}
|
|
|
|
|
|
|
|
# Assume the ROM is mapped to the top of 4GB
|
|
|
|
my $fit_ptr = uint32(0xFFFFFFC0);
|
|
|
|
my $fit_offset = $fit_ptr - $base;
|
|
|
|
|
|
|
|
printf "FIT pointer: %08x (offset %08x)\n", $fit_ptr, $fit_offset;
|
|
|
|
|
2018-02-06 23:01:19 +00:00
|
|
|
die "FIT pointer out of range?\n" if $fit_offset < 0;
|
2016-12-01 18:57:35 +00:00
|
|
|
|
|
|
|
my $fit = substr($rom, $fit_ptr - $base, 8);
|
|
|
|
printf "Signature: '%s'\n", $fit;
|
|
|
|
die "Bad signature?\n" unless $fit eq '_FIT_ ';
|
|
|
|
|
|
|
|
my $entries = uint32($fit_ptr + 0x8);
|
|
|
|
|
|
|
|
my %entry_types = (
|
|
|
|
0x00 => "Header",
|
|
|
|
0x01 => "Microcode",
|
|
|
|
0x02 => "Startup ACM",
|
|
|
|
0x07 => "BIOS Startup Module",
|
|
|
|
0x08 => "TPM Policy",
|
|
|
|
0x09 => "BIOS Policy",
|
|
|
|
0x0A => "TXT Policy",
|
|
|
|
0x0B => "Key Manifest",
|
|
|
|
0x0C => "Boot Policy Manifest",
|
|
|
|
0x10 => "CSE Secure Boot",
|
|
|
|
0x2D => "TXTSX Policy",
|
|
|
|
0x2F => "JMP Debug Policy",
|
|
|
|
0x7F => "SKIP",
|
|
|
|
);
|
|
|
|
|
|
|
|
for my $i (1..$entries-1)
|
|
|
|
{
|
|
|
|
my ($address, $len, $ver, $type, $csum) = unpack(
|
|
|
|
"QVSCC", substr($rom, $fit_ptr - $base + $i*0x10, 0x10));
|
|
|
|
|
|
|
|
printf "%d: address %08x @ %08x: ver %04x type %s (0x%02x)\n",
|
|
|
|
$i,
|
|
|
|
$address,
|
|
|
|
$len,
|
|
|
|
$ver,
|
|
|
|
$entry_types{$type} || "Unknown",
|
|
|
|
$type,
|
|
|
|
;
|
|
|
|
}
|