mirror of
https://github.com/linuxboot/linuxboot
synced 2024-11-22 08:09:41 +00:00
100 lines
2.4 KiB
Perl
Executable File
100 lines
2.4 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
# Create a UEFI "Firmware File" (FFS) with optional features.
|
|
use warnings;
|
|
use strict;
|
|
use FindBin;
|
|
use lib "$FindBin::Bin/../lib";
|
|
use Getopt::Long;
|
|
use Digest::SHA 'sha1';
|
|
use EFI;
|
|
|
|
my $usage = <<"";
|
|
Usage:
|
|
$0 -o output.ffs [options] file.efi [...]
|
|
Options:
|
|
-o | --output output.ffs Output file (default is stdout)
|
|
-n | --name FileName Name to include in UI Section
|
|
-t | --type Type FREEFORM|DRIVER|SMM|DXE_CORE|SMM_CORE|PEIM
|
|
-v | --version 1.0 Version section
|
|
-g | --guid GUID This file GUID (default is hash of Name)
|
|
-d | --depex 'guid guid..' Optional dependencies (all ANDed, or TRUE)
|
|
-z | --compress Enable LZMA compression
|
|
|
|
my $output = '-';
|
|
my $name;
|
|
my $type = 'FREEFORM';
|
|
my $version;
|
|
my $guid;
|
|
my $depex;
|
|
my $compress;
|
|
|
|
|
|
GetOptions(
|
|
"o|output=s" => \$output,
|
|
"n|name=s" => \$name,
|
|
"t|type=s" => \$type,
|
|
"v|version=s" => \$version,
|
|
"g|guid=s" => \$guid,
|
|
"d|depex=s" => \$depex,
|
|
"z|compress+" => \$compress,
|
|
) or die $usage;
|
|
|
|
die "$type: unknown file type\n"
|
|
unless exists $EFI::file_types{$type};
|
|
|
|
my @sections;
|
|
|
|
# Read entire files at a time and append a new section
|
|
# for each file read. Some special types have their own
|
|
# section type; otherwise we're adding a PE32
|
|
# The file goes first so that it will be aligned correctly
|
|
# on the 4 KB page inside the FV.
|
|
local $/ = undef;
|
|
while(<>)
|
|
{
|
|
push @sections, EFI::section($EFI::section_type_map{$type} || 'PE32', $_);
|
|
}
|
|
|
|
# Put the optional parts after the input data
|
|
push @sections, EFI::section(USER_INTERFACE => EFI::ucs16($name))
|
|
if $name;
|
|
|
|
push @sections, EFI::section(VERSION => EFI::ucs16(chr(0x00) . $version))
|
|
if $version;
|
|
|
|
push @sections, EFI::depex($type, split /\s+/, $depex)
|
|
if $depex;
|
|
|
|
|
|
# If we're compressing, compress the data and wrap it with a GUIDed header
|
|
# replacing all of the existing sections.
|
|
@sections = ( EFI::compress(@sections) )
|
|
if $compress;
|
|
|
|
# If no GUID was provided, make one from the name
|
|
# if there is no name from the data
|
|
if ($guid)
|
|
{
|
|
$guid = EFI::guid($guid);
|
|
}
|
|
elsif ($name)
|
|
{
|
|
# Generate a deterministic GUID based on the UI name
|
|
$guid = substr(sha1($name), 0, 16);
|
|
}
|
|
|
|
# Create the FFS header for the sections
|
|
my $ffs = EFI::ffs($type, $guid, @sections);
|
|
|
|
|
|
if ($output eq '-')
|
|
{
|
|
print $ffs;
|
|
} else {
|
|
open OUTPUT, ">", $output
|
|
or die "$output: Unable to open: $!\n";
|
|
|
|
print OUTPUT $ffs;
|
|
close OUTPUT;
|
|
}
|