Unified kernel image

A unified kernel image (UKI) is a single executable which can be booted directly from UEFI firmware, or automatically sourced by boot-loaders with little or no configuration.

Although Arch supported kernels themselves can be loaded by UEFI firmware, a unified image allows to incorporate all or a subset of the following:

The resulting executable, and therefore all these elements can then be easily signed for use with Secure Boot.

Note: In the entire article esp denotes the mountpoint of the EFI system partition.

Preparing a unified kernel image

mkinitpcio

One can test the feature by running as an example

# mkdir -p esp/EFI/Linux
# mkinitcpio -p linux -- --uki esp/EFI/Linux/test-systemd.efi

This would produce a kernel image for the linux preset.

Kernel command line

First, create /etc/kernel/cmdline with your kernel parameters, taking care to remove entries pointing at microcode and initramfs, e.g.

/etc/kernel/cmdline
rw quiet bgrt_disable
Tip: The bgrt_disable parameter tells Linux to not display the OEM logo after loading the ACPI tables.

.preset file

Next modify /etc/mkinitcpio.d/linux.preset, or the preset that you are using, as follows, with the appropriate mount point of the EFI system partition :

  • If your system requires Microcode, add ALL_microcode=(/boot/*-ucode.img),
  • Add a PRESET_uki= parameter for each item in PRESETS=,
  • Optionally, comment out PRESET_image= to avoid building redundant initramfs-*.img,
  • Optionally, append a parameter to each line for which you want to add a splash image.

Here is a working example for the kernel and the Arch splash screen.

/etc/mkinitcpio.d/linux.preset
# mkinitcpio preset file for the 'linux' package

ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
ALL_microcode=(/boot/*-ucode.img)

PRESETS=('default' 'fallback')

#default_image="/boot/initramfs-linux.img"
default_uki="''esp''/EFI/Linux/archlinux-linux.efi"
default_options="--splash /usr/share/systemd/bootctl/splash-arch.bmp"

#fallback_image="/boot/initramfs-linux-fallback.img"
fallback_uki="''esp''/EFI/Linux/archlinux-linux-fallback.efi"
fallback_options="-S autodetect"
Tip:
  • If all you want to do is boot from the unified kernel images, you can mount the ESP to /efi and only those need to reside on the ESP partition.
  • You can append --cmdline /etc/kernel/fallback_cmdline to fallback_options to use different a different cmdline than above for the fallback image (e.g. without quiet)

Finally, regenerate the initramfs.

kernel-install

You can use systemd's script to automatically install kernels in the UKI format to the esp both for custom kernels and also by switching pacman hooks from mkinitpcio to kernel-install. Kernel-install has its own hook system that those packages which care about doing something during kernel installation can use. (i.e.: ships with both pacman hooks and kernel-install hooks as well)

Set the kernel-install layout to 'uki'

Set the kernel-install layout to 'uki'. e.g.:

# echo "layout=uki" >> /etc/kernel/install.conf

Mask direct kernel installation pacman hooks

# echo "" > /etc/pacman.d/hooks/60-mkinitcpio-remove.hook
# echo "" > /etc/pacman.d/hooks/90-mkinitcpio-install.hook
# echo "" > /etc/pacman.d/hooks/zz-sbctl.hook

Create a pacman hook for kernel-install

Create a pacman hook for kernel-install. You can use .

Reinstall kernels

Remove and reinstall the kernel packages that you use.

dracut

See dracut#Unified kernel image and dracut#Generate a new initramfs on kernel upgrade.

sbctl

Install the package. Store the kernel command line in /etc/kernel/cmdline. Use the command with the parameter to create a bundle and have it be regenerated by a Pacman hook at appropriate times:

# sbctl bundle --save esp/archlinux.efi

To create more EFI binaries for other kernels and initramfs images, repeat the above command with parameters and , see . The EFI binaries can be regenerated at any time with .

Manually

Put the kernel command line you want to use in a file, and create the bundle file using objcopy(1).

For microcode, first concatenate the microcode file and your initrd, as follows:

$ cat esp/cpu_manufacturer-ucode.img esp/initramfs-linux.img > /tmp/combined_initrd.img

When building the unified kernel image, pass in /tmp/combined_initrd.img as the initrd. This file can be removed afterwards.

The offsets are simply calculated so no sections overlap, as recommended in .

After creating the image, copy it to the EFI system partition:

# cp linux.efi esp/EFI/Linux/

Booting

systemd-boot

systemd-boot searches in for unified kernel images, and there is no further configuration needed. See

rEFInd

rEFInd will autodetect unified kernel images on your EFI system partition, and is capable of loading them. They can also be manually specified in , by default located at:

If the image is at the root of the ESP, rEFInd only requires its name, as follows: . Recall that no kernel parameters from will be passed when booting this way.

Directly from UEFI

efibootmgr can be used to create a UEFI boot entry for the .efi file:

# efibootmgr --create --disk /dev/sdX --part partition_number --label "label" --loader 'EFI\Linux\file.efi' --unicode

See for an explanation of the options.

gollark: Technically only PD, but whatever.
gollark: I use PID control in a bunch of flight control code for Minecraft. It works quite well.
gollark: I mean, you'd have to program it to or train it on those, but it isn't impossible.
gollark: Good, because neural networks are excellent at that.
gollark: But right now, at least, it isn't very capable of generally intelligent stuff, which is probably for the best.

See also

This article is issued from Archlinux. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.