Compare commits

..

2 Commits

Author SHA1 Message Date
Ani Sinha 6721056ff4
Merge 360aced7de into c946b13575 2024-11-23 06:28:52 +00:00
Ani Sinha 360aced7de uki: introduce support for a .efifwauto section
UKIs can be used to bundle firmware blobs that can be measured and
used on a confidential computing environment. There can be more than one
firmware blob bundle, each one for a specific platform. Also firmware images
can themselves be containers like IGVM files that can in turn bundle the
actual firmware blob.

Add support to introduce a .efifwauto section in UKI that can be used for
firmware blobs/images. There can be multiple such sections and each section
can contain a single firmware image.

The matching .hwids entry for a specific platform can be used to select the
most appropriate firmware blob. Subsequent patches will add full support
for this selection mechanism.

ukify tool has been also changed to support addition of a firmware image
in UKI. For example:

ukify.py build \
        --stub ./build/src/boot/efi/linuxx64.efi.stub \
        --linux bzImage \
        --cmdline='blah blah debug' \
        --firmware ~/OVMF.fd \
        --output=root/efi/boot/bootx64.efi

Co-authored-by: harald.hoyer@gmail.com
2024-11-23 11:36:38 +05:30
4 changed files with 44 additions and 34 deletions

View File

@ -75,9 +75,6 @@
<listitem><para>An optional <literal>.ucode</literal> section with an initrd containing microcode, to
be handed to the kernel before any other initrd. This initrd must not be compressed.</para></listitem>
<listitem><para>An optional <literal>.fmw</literal> section with the firmware image.
</para></listitem>
<listitem><para>An optional <literal>.splash</literal> section with an image (in the Windows
<filename>.BMP</filename> format) to show on screen before invoking the kernel.</para></listitem>
@ -94,6 +91,15 @@
the same matching procedure. If a match is found, that <literal>.dtbauto</literal> section will be
loaded and will override <varname>.dtb</varname> if present.</para></listitem>
<listitem><para>Zero or more <literal>.efifwauto</literal> sections for the firmware image. It works
in many ways similar to <varname>.dtbauto</varname> sections. <filename>systemd-stub</filename>
will always use the first matching one. The match is performed by first selecting the most appropriate
entry in the <varname>.hwids</varname> section based on the hardware IDs supplied by SMBIOS (see below).
If a suitable entry is found, the <varname>compatible</varname> string from that entry will be used to
perform the matching procedure for firmware blobs in <varname>.efifwauto</varname> section. The first
matching firmware will be loaded.
</para></listitem>
<listitem><para>Zero or more <literal>.hwids</literal> sections with hardware IDs of the machines to
match DeviceTrees. <filename>systemd-stub</filename> will use the SMBIOS data to calculate hardware IDs
of the machine (as per <ulink

View File

@ -23,6 +23,6 @@ const char* const unified_sections[_UNIFIED_SECTION_MAX + 1] = {
[UNIFIED_SECTION_PROFILE] = ".profile",
[UNIFIED_SECTION_DTBAUTO] = ".dtbauto",
[UNIFIED_SECTION_HWIDS] = ".hwids",
[UNIFIED_SECTION_FIRMWARE] = ".fmw",
[UNIFIED_SECTION_FIRMWARE] = ".efifwauto",
NULL,
};

View File

@ -104,7 +104,7 @@ static int help(int argc, char *argv[], void *userdata) {
" --linux=PATH Path to Linux kernel image file %7$s .linux\n"
" --osrel=PATH Path to os-release file %7$s .osrel\n"
" --cmdline=PATH Path to file with kernel command line %7$s .cmdline\n"
" --firmware=PATH Path to firmware image file %7$s .fmw\n"
" --firmware=PATH Path to firmware image file %7$s .efifwauto\n"
" --initrd=PATH Path to initrd image file %7$s .initrd\n"
" --ucode=PATH Path to microcode image file %7$s .ucode\n"
" --splash=PATH Path to splash bitmap file %7$s .splash\n"

View File

@ -242,7 +242,7 @@ class UkifyConfig:
efi_arch: str
hwids: Path
initrd: list[Path]
firmware: Path
firmware: list[Path]
join_profiles: list[Path]
json: Union[Literal['pretty'], Literal['short'], Literal['off']]
linux: Optional[Path]
@ -363,22 +363,22 @@ class Uname:
DEFAULT_SECTIONS_TO_SHOW = {
'.linux': 'binary',
'.initrd': 'binary',
'.fmw': 'binary',
'.ucode': 'binary',
'.splash': 'binary',
'.dtb': 'binary',
'.dtbauto': 'binary',
'.hwids': 'binary',
'.cmdline': 'text',
'.osrel': 'text',
'.uname': 'text',
'.pcrpkey': 'text',
'.pcrsig': 'text',
'.sbat': 'text',
'.sbom': 'binary',
'.profile': 'text',
'.linux': 'binary',
'.initrd': 'binary',
'.ucode': 'binary',
'.splash': 'binary',
'.dtb': 'binary',
'.dtbauto': 'binary',
'.hwids': 'binary',
'.efifwauto': 'binary',
'.cmdline': 'text',
'.osrel': 'text',
'.uname': 'text',
'.pcrpkey': 'text',
'.pcrsig': 'text',
'.sbat': 'text',
'.sbom': 'binary',
'.profile': 'text',
} # fmt: skip
@ -1206,17 +1206,17 @@ def make_uki(opts: UkifyConfig) -> None:
sections = [
# name, content, measure?
('.osrel', opts.os_release, True),
('.cmdline', opts.cmdline, True),
('.dtb', opts.devicetree, True),
('.osrel', opts.os_release, True),
('.cmdline', opts.cmdline, True),
('.dtb', opts.devicetree, True),
*(('.dtbauto', dtb, True) for dtb in opts.devicetree_auto),
('.hwids', hwids, True),
('.uname', opts.uname, True),
('.splash', opts.splash, True),
('.pcrpkey', pcrpkey, True),
('.initrd', initrd, True),
('.fmw', opts.firmware, True),
('.ucode', opts.microcode, True),
('.hwids', hwids, True),
('.uname', opts.uname, True),
('.splash', opts.splash, True),
('.pcrpkey', pcrpkey, True),
('.initrd', initrd, True),
*(('.efifwauto', fw, True) for fw in opts.firmware),
('.ucode', opts.microcode, True),
] # fmt: skip
# If we're building a PE profile binary, the ".profile" section has to be the first one.
@ -1272,7 +1272,7 @@ def make_uki(opts: UkifyConfig) -> None:
'.osrel',
'.cmdline',
'.initrd',
'.fmw',
'.efifwauto',
'.ucode',
'.splash',
'.dtb',
@ -1735,9 +1735,13 @@ CONFIG_ITEMS = [
),
ConfigItem(
'--firmware',
metavar='PATH',
type=Path,
help='firmware file [.fmw section]',
action='append',
default=[],
help='firmware file [.efifwauto section]',
config_key='UKI/Firmware',
config_push=ConfigItem.config_list_prepend,
),
ConfigItem(
'--microcode',