These docs are under active development.
On this page
reference 4 min read

mkuki

mkuki builds a UEFI unified kernel image (UKI): it takes a PE/COFF EFI stub and appends the kernel, the initramfs, and the kernel command line to it as named PE sections, producing a single EFI binary that UEFI firmware boots directly. Where mkirf produces the initramfs image, mkuki is the step that wraps that image — together with a kernel and a command line — into one bootable artifact. The two are the two halves of Peios' Dynamic Boot system.

mkuki --kernel PATH --initramfs PATH (--cmdline TEXT | --cmdline-file PATH) --out PATH
      [--stub PATH] [--watch] [--debounce SECS]
mkuki --stub-info

The UKI section layout

A UKI is an ordinary PE/COFF EFI executable — the stub — with three extra sections appended, which the stub reads at boot to find its payloads:

Section Content Source
.cmdline The kernel command line, NUL-terminated. --cmdline or --cmdline-file
.linux The kernel image. --kernel
.initrd The initramfs cpio image. --initramfs

mkuki appends them in exactly that order. Each new section is marked as initialised, read-only data. The tool works at the PE level directly: it parses the stub's DOS/PE headers and section table, computes correctly-aligned virtual addresses and file offsets for the new sections, appends their data, updates the section count and the SizeOfImage/SizeOfHeaders fields, and — if the stub's header has no spare room for three more section entries — grows the header region and relocates the existing sections' file pointers to make space. A stub that is not a valid MZ/PE image, or whose optional header is malformed, is rejected.

The command line

The command line is taken either literally from --cmdline or read from the file named by --cmdline-file (exactly one is required). Either way, mkuki trims trailing newlines and carriage returns and appends a single NUL terminator. A command line containing an embedded NUL byte is rejected.

The stub

--stub names the EFI stub to append to. With no --stub, mkuki uses a stub bundled into the binary (the systemd EFI stub). mkuki --stub-info prints that bundled stub's provenance and exits, so you can see exactly what the default is without building anything.

Output and atomicity

mkuki creates any missing parent directories of --out, writes the assembled image to a sibling temp file, and renames it into place, so an interrupted or failed build never leaves a half-written UKI behind. On success it prints the output path and byte size to stderr. Each of the three payloads must be non-empty; an empty .cmdline, .linux, or .initrd fails the build.

ℹ Note
mkuki does not sign the image. Producing the unified binary and signing it for Secure Boot are separate steps; mkuki has no signing options. Because a UKI bundles the kernel, initramfs, and command line into one PE image, that image is what a later Secure Boot milestone signs and the firmware verifies as a whole — but the signing itself is out of mkuki's scope.

Watch mode

With --watch, mkuki stays resident: it builds once up front, then rebuilds the UKI whenever an input changes — so the boot image tracks a new kernel, a freshly-repacked initramfs (mkirf's half of Dynamic Boot), or an edited command-line file with no manual step. Like mkirf's watch mode, it is a foreground loop that runs until killed; supervising it is a service manager's job, and a rebuild that fails (for example, a kernel caught mid-copy) is logged rather than fatal, so fixing the input recovers on the next change.

The watched inputs are --kernel, --initramfs, and — only if it is a --cmdline-file, since a literal --cmdline is static — the command-line file. mkuki watches each input's parent directory (non-recursively), not the file itself: this survives the atomic temp-and-rename writes that mkirf and mkuki both perform (which appear as a directory event a stale single-file watch would miss) and catches a versioned kernel being swapped in /boot. Because the watch is non-recursive, a write to an --out path nested deeper under a watched directory does not retrigger it — but an --out sitting directly in a watched input directory would, so mkuki refuses that invocation. The --debounce window (default 5 seconds) is the settle time before a rebuild.

Options

Option Effect
--kernel PATH The kernel image; becomes the .linux section. Required (except with --stub-info).
--initramfs PATH The initramfs cpio; becomes the .initrd section. Required (except with --stub-info).
--cmdline TEXT The kernel command line, given literally; becomes the .cmdline section. Mutually exclusive with --cmdline-file.
--cmdline-file PATH Read the kernel command line from PATH instead. Mutually exclusive with --cmdline.
--out PATH The output UKI path. Required (except with --stub-info).
--stub PATH The PE/COFF EFI stub to append sections to. Defaults to the bundled systemd stub.
--stub-info Print the bundled stub's provenance and exit.
--watch Stay resident and rebuild the UKI whenever --kernel, --initramfs, or --cmdline-file changes. Runs until killed.
--debounce SECS With --watch, the settle time before a rebuild. Default 5.

Exactly one of --cmdline or --cmdline-file must be given: supplying both, or neither, is a usage error.

Exit status

Code Meaning
0 The UKI was built (or --stub-info, --help, or --version was printed).
1 A build or watch failure — a missing or unreadable input, an invalid stub, an empty payload, or an I/O error.
2 A usage error — a bad or missing option, or an invalid --cmdline/--cmdline-file combination.

See also

  • mkirf — builds the .initrd payload mkuki wraps.
  • The initramfs stage — what the bundled initramfs does once firmware boots the UKI.