linuxboot/bin/create-fv

118 lines
2.7 KiB
Perl
Executable File

#!/usr/bin/perl
# Create a UEFI "Firmware Volume" (FV) from "Firmware FileS" (FFS).
#
# Typical usage is to create a FFS for each file that will be included,
# then to wrap them in a (compressed) FV.
#
# for file in *.efi; do
# ./bin/create-ffs -o $file.ffs -t DRIVER $file
# done
# ./bin/create-ffs -o raw.ffs -t FREEFORM raw.bin
# ./bin/create-fv -o firmware.fv *.ffs
use warnings;
use strict;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Getopt::Long;
use Digest::SHA 'sha1';
use EFI;
my $usage = <<"END";
Usage:
$0 -o output.fv [options] file.ffs [...]
Options:
-h | -? | --help This help
-o | --output output.ffs Output file (default is stdout)
-s | --size BYTES Final size in bytes (default is 4 MB)
-v | --verbose Increase verbosity
-z | --compress BYTES Create an internal LZMA compresed FV
For compressed firmware volumes, the --size is the final size of the
output and --compress size is the internal volume. So to create a 4MB
volume with a 8MB internal use --size 0x4000000 --compress 0x800000
Sizes are limited to less than 16 MB until FFSv3 support is added.
END
# if invoked with no options, we should probably print some help
die $usage unless @ARGV;
my $output = '-';
my $size = 4 * 1024 * 1024;
my $verbose = 0;
my $compress_size;
GetOptions(
"h|?|help" => sub { print $usage; exit 0 },
"o|output=s" => \$output,
"s|size=o" => \$size,
"z|compress=o" => \$compress_size,
"v|verbose+" => \$verbose,
) or die $usage;
#my $guid = EFI::guid($guid_str)
# or die "$guid_str: Unable to parse GUID\n";
# Read entire files at a time and append a new file
# for each input read.
local $/ = undef;
my @ffs;
my $length_sum = 0;
while(<>)
{
push @ffs, $_;
$length_sum += length $_;
warn sprintf "%s: 0x%x bytes\n",
$ARGV,
length $_,
if $verbose > 1;
}
warn sprintf "%s: 0x%08x out of %08x bytes in FV%s\n",
$output,
$length_sum,
$compress_size || $size,
$compress_size ? " (uncompressed)" : "",
if $verbose > 0;
my $fv = EFI::fv($compress_size || $size, @ffs)
or die "$output: Unable to create FV\n";
if ($compress_size)
{
my $sec_lz = EFI::compress(EFI::section(FIRMWARE_VOLUME_IMAGE => $fv));
my $ffs_lz = EFI::ffs(FIRMWARE_VOLUME_IMAGE => '', $sec_lz);
warn sprintf "%s: 0x%08x out of %08x bytes in FV (compressed)\n",
$output,
length($ffs_lz),
$size,
if $verbose > 0;
my $outer_fv = EFI::fv($size, $ffs_lz)
or die sprintf "%s: Unable to append 0x%08x compressed bytes\n",
$output,
length($ffs_lz),
;
$fv = $outer_fv;
}
if ($output eq '-')
{
print $fv;
} else {
open OUTPUT, ">", $output
or die "$output: Unable to open: $!\n";
print OUTPUT $fv;
close OUTPUT;
}
__END__