diff --git a/man/ukify.xml b/man/ukify.xml
index c3c0d3f2df..97c3f899c7 100644
--- a/man/ukify.xml
+++ b/man/ukify.xml
@@ -17,14 +17,14 @@
ukify
- Combine kernel and initrd into a signed Unified Kernel Image
+ Combine components into a signed Unified Kernel Image for UEFI systems/usr/lib/systemd/ukify
- LINUX
- INITRD
+ LINUX
+ INITRDOPTIONS
@@ -35,8 +35,8 @@
Note: this command is experimental for now. While it is intended to become a regular component of
systemd, it might still change in behaviour and interface.
- ukify is a tool that combines a kernel and an initrd with
- a UEFI boot stub to create a
+ ukify is a tool that combines components (e.g.: a kernel and an initrd with
+ a UEFI boot stub) to create a
Unified Kernel Image (UKI)
ā a PE binary that can be executed by the firmware to start the embedded linux kernel.
See systemd-stub7
@@ -53,6 +53,9 @@
and
below.
+ ukify can also be used to assemble a PE binary that is not executable but
+ contains auxiliary data, for example additional kernel command line entries.
+
If PCR signing keys are provided via the and
options, PCR values that will be seen after booting with the given
kernel, initrd, and other sections, will be calculated, signed, and embedded in the UKI.
@@ -78,10 +81,9 @@
Options
- Note that the LINUX positional argument is mandatory. The
- INITRD positional arguments are optional. If more than one is specified, they
- will all be combined into a single PE section. This is useful to for example prepend microcode before the
- actual initrd.
+ The LINUX and INITRD positional arguments are
+ optional. If more than one INITRD are specified, they will all be combined into
+ a single PE section. This is useful to for example prepend microcode before the actual initrd.The following options are understood:
@@ -296,6 +298,19 @@
key pcr-private-system-key.pem. The Linux binary and the resulting
combined image will be signed with the SecureBoot key sb.key.
+
+
+ Kernel command line auxiliary PE
+
+ ukify \
+ --secureboot-private-key=sb.key \
+ --secureboot-certificate=sb.cert \
+ --cmdline='debug' \
+ --output=debug.cmdline.efi
+
+
+ This creates a signed PE binary that contains an additional kernel command line parameter.
+
diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py
index 7e025b5ef4..1b58f05d4c 100755
--- a/src/ukify/test/test_ukify.py
+++ b/src/ukify/test/test_ukify.py
@@ -206,6 +206,27 @@ def test_sections(kernel_initrd, tmpdir):
for sect in 'text osrel cmdline linux initrd uname test'.split():
assert re.search(fr'^\s*\d+\s+.{sect}\s+0', dump, re.MULTILINE)
+def test_addon(kernel_initrd, tmpdir):
+ output = f'{tmpdir}/addon.efi'
+ opts = ukify.parse_args([
+ f'--output={output}',
+ '--cmdline=ARG1 ARG2 ARG3',
+ '--section=.test:CONTENTZ',
+ ])
+
+ try:
+ ukify.check_inputs(opts)
+ except OSError as e:
+ pytest.skip(str(e))
+
+ ukify.make_uki(opts)
+
+ # let's check that objdump likes the resulting file
+ dump = subprocess.check_output(['objdump', '-h', output], text=True)
+
+ for sect in 'text cmdline test'.split():
+ assert re.search(fr'^\s*\d+\s+.{sect}\s+0', dump, re.MULTILINE)
+
def unbase64(filename):
tmp = tempfile.NamedTemporaryFile()
diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py
index b319f2dc91..3fbeb2b215 100755
--- a/src/ukify/ukify.py
+++ b/src/ukify/ukify.py
@@ -551,7 +551,7 @@ def make_uki(opts):
sbsign_invocation += ['--engine', opts.signing_engine]
sign_kernel = opts.sign_kernel
- if sign_kernel is None and opts.sb_key:
+ if sign_kernel is None and opts.linux is not None and opts.sb_key:
# figure out if we should sign the kernel
sbverify_tool = find_tool('sbverify', opts=opts)
@@ -583,7 +583,7 @@ def make_uki(opts):
else:
linux = opts.linux
- if opts.uname is None:
+ if opts.uname is None and opts.linux is not None:
print('Kernel version not specified, starting autodetection š.')
opts.uname = Uname.scrape(opts.linux, opts=opts)
@@ -624,7 +624,8 @@ def make_uki(opts):
# UKI creation
- uki.add_section(Section.create('.linux', linux, measure=True))
+ if linux is not None:
+ uki.add_section(Section.create('.linux', linux, measure=True))
if opts.sb_key:
unsigned = tempfile.NamedTemporaryFile(prefix='uki')
@@ -657,7 +658,7 @@ def parse_args(args=None):
description='Build and sign Unified Kernel Images',
allow_abbrev=False,
usage='''\
-usage: ukify [optionsā¦] linux initrdā¦
+usage: ukify [optionsā¦] [linux [initrdā¦]]
ukify -h | --help
''')
@@ -666,6 +667,7 @@ usage: ukify [optionsā¦] linux initrdā¦
p.add_argument('linux',
type=pathlib.Path,
+ nargs="?",
help='vmlinuz file [.linux section]')
p.add_argument('initrd',
type=pathlib.Path,
@@ -769,7 +771,8 @@ usage: ukify [optionsā¦] linux initrdā¦
opts = p.parse_args(args)
- path_is_readable(opts.linux)
+ if opts.linux is not None:
+ path_is_readable(opts.linux)
for initrd in opts.initrd or ():
path_is_readable(initrd)
path_is_readable(opts.devicetree)
@@ -784,7 +787,7 @@ usage: ukify [optionsā¦] linux initrdā¦
if opts.os_release is not None and opts.os_release.startswith('@'):
opts.os_release = path_is_readable(opts.os_release[1:])
- elif opts.os_release is None:
+ elif opts.os_release is None and opts.linux is not None:
p = pathlib.Path('/etc/os-release')
if not p.exists():
p = path_is_readable('/usr/lib/os-release')
@@ -815,6 +818,8 @@ usage: ukify [optionsā¦] linux initrdā¦
raise ValueError('--phases= specifications must match --pcr-private-key=')
if opts.output is None:
+ if opts.linux is None:
+ raise ValueError('--output= must be specified when building a PE addon')
suffix = '.efi' if opts.sb_key else '.unsigned.efi'
opts.output = opts.linux.name + suffix