mirror of
https://github.com/linuxboot/linuxboot
synced 2024-11-21 15:50:58 +00:00
118 lines
2.7 KiB
Perl
Executable File
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__
|