linuxboot/bin/create-fv

118 lines
2.7 KiB
Plaintext
Raw Normal View History

2018-01-20 20:59:52 +00:00
#!/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
2018-01-20 20:59:52 +00:00
use warnings;
use strict;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Getopt::Long;
use Digest::SHA 'sha1';
use EFI;
2018-01-20 20:59:52 +00:00
my $usage = <<"END";
2018-01-20 20:59:52 +00:00
Usage:
$0 -o output.fv [options] file.ffs [...]
Options:
-h | -? | --help This help
2018-01-20 20:59:52 +00:00
-o | --output output.ffs Output file (default is stdout)
-s | --size BYTES Final size in bytes (default is 4 MB)
2018-01-21 12:40:03 +00:00
-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.
2018-01-20 20:59:52 +00:00
END
# if invoked with no options, we should probably print some help
die $usage unless @ARGV;
2018-01-20 20:59:52 +00:00
my $output = '-';
my $size = 4 * 1024 * 1024;
2018-01-21 12:40:03 +00:00
my $verbose = 0;
my $compress_size;
2018-01-20 20:59:52 +00:00
GetOptions(
"h|?|help" => sub { print $usage; exit 0 },
2018-01-20 20:59:52 +00:00
"o|output=s" => \$output,
2018-01-20 21:04:13 +00:00
"s|size=o" => \$size,
"z|compress=o" => \$compress_size,
"v|verbose+" => \$verbose,
2018-01-20 20:59:52 +00:00
) or die $usage;
#my $guid = EFI::guid($guid_str)
# or die "$guid_str: Unable to parse GUID\n";
2018-01-20 20:59:52 +00:00
# Read entire files at a time and append a new file
# for each input read.
local $/ = undef;
my @ffs;
my $length_sum = 0;
2018-01-20 20:59:52 +00:00
while(<>)
{
push @ffs, $_;
$length_sum += length $_;
2018-01-20 20:59:52 +00:00
warn sprintf "%s: 0x%x bytes\n",
$ARGV,
length $_,
2018-01-21 12:40:03 +00:00
if $verbose > 1;
2018-01-20 20:59:52 +00:00
}
2018-01-21 12:40:03 +00:00
warn sprintf "%s: 0x%08x out of %08x bytes in FV%s\n",
$output,
$length_sum,
$compress_size || $size,
2018-01-21 12:40:03 +00:00
$compress_size ? " (uncompressed)" : "",
if $verbose > 0;
my $fv = EFI::fv($compress_size || $size, @ffs)
or die "$output: Unable to create FV\n";
2018-01-20 20:59:52 +00:00
if ($compress_size)
{
my $sec_lz = EFI::compress(EFI::section(FIRMWARE_VOLUME_IMAGE => $fv));
my $ffs_lz = EFI::ffs(FIRMWARE_VOLUME_IMAGE => '', $sec_lz);
2018-01-21 12:40:03 +00:00
warn sprintf "%s: 0x%08x out of %08x bytes in FV (compressed)\n",
$output,
length($ffs_lz),
$size,
2018-01-21 12:40:03 +00:00
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;
2018-01-20 20:59:52 +00:00
}
2018-01-20 20:59:52 +00:00
if ($output eq '-')
{
print $fv;
2018-01-20 20:59:52 +00:00
} else {
open OUTPUT, ">", $output
or die "$output: Unable to open: $!\n";
print OUTPUT $fv;
2018-01-20 20:59:52 +00:00
close OUTPUT;
}
__END__