BOOTCTL(1)

๐ŸŽ€ BOOTCTL โ€” the bootctl(1) glow-up ๐ŸŽ€

okay bestie, buckle up, because this one is the tool for bossing your EFI firmware around and it's lowkey iconic ๐Ÿ’…


โœจ NAME โœจ

bootctl โ€” control EFI firmware boot settings and manage boot loader. yes that's the whole job description and it ate ๐Ÿ’–


๐ŸŒธ SYNOPSIS ๐ŸŒธ

bootctl [OPTIONS...] {COMMAND}

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

So like, bootctl is your girl for all things boot. She can:

  • check the EFI firmware and boot loader status (vibe check ๐Ÿ‘€)
  • list and manage available boot loaders and boot loader entries
  • install, update, or remove the systemd-boot(7) boot loader on the current system

fr fr, that's the whole resume and she's overqualified ๐Ÿซถ


๐Ÿ‘‘ GENERIC EFI FIRMWARE/BOOT LOADER COMMANDS ๐Ÿ‘‘

These ones work on any EFI system, no matter which boot loader you're running. universal besties ๐ŸŒˆ

  • status โ€” shows brief info about the system firmware, the boot loader that was used to boot the system, the boot loaders currently available in the ESP, the boot loaders listed in the firmware's list of boot loaders, and the current default boot loader entry. And plot twist: if you don't specify any command at all, this is the implied default. Check the example below for what the output actually looks like. Added in version 239.
  • reboot-to-firmware [BOOL] โ€” query or set the "Reboot-Into-Firmware-Setup" flag of the EFI firmware. Takes a boolean argument which controls whether to show the firmware setup on next system reboot. If you omit the argument, it shows the current status of the flag โ€” or whether the flag is even supported. This controls the same flag as systemctl reboot --firmware-setup, but it's more low-level and lets you set the flag independently from actually requesting a reboot. Hint: use systemctl reboot --firmware-setup to reboot into firmware setup once. See systemctl(1) for details. Added in version 251.

๐Ÿ’– BOOT LOADER SPECIFICATION COMMANDS ๐Ÿ’–

These are for all boot loaders that implement the UAPI.1 Boot Loader Specification[1] โ€” like systemd-boot. the it-girls of the boot loader world ๐Ÿ’…

  • list โ€” shows all available boot loader entries implementing the UAPI.1 Boot Loader Specification[1], plus any other entries discovered or automatically generated by a boot loader implementing the Boot Loader Interface[2]. Want JSON? Ask nicely with --json=. See the example below for details of the output. Added in version 239.
  • unlink [ID] โ€” removes a boot loader entry including the files it refers to. Takes an optional boot loader entry ID string or a glob pattern as argument. Referenced files like the kernel, initrds, system extensions (sysexts), configuration extensions (confexts) or credential files are only removed if no other entry refers to them โ€” she's careful like that. If you don't give an ID argument, the --oldest option must be specified, in which case the boot loader entry with the lowest version gets removed. For robustness reasons, the currently booted menu entry is never removed, and neither is the last existing boot loader entry. periodt. Added in version 253.
  • link KERNEL โ€” creates one or more Type #1 boot loader entries pointing to the specified UKI. Takes the path to a Unified Kernel Image (UKI) as argument. The UKI gets copied into the ESP (or XBOOTLDR partition if present) below the configured entry token directory, and one or more Boot Loader Specification[1] Type #1 entries are generated referring to it โ€” one per UKI profile, if multiple profiles are embedded. iconic.

The title, version, commit number and initial try counter of the generated entries may be overridden with --entry-title=, --entry-version=, --entry-commit= and --tries-left=. Additional sidecar resources (system extension images, configuration extension images, credential files) to pass to the UKI at boot may be specified with --extra=.

If the ESP/XBOOTLDR doesn't have enough free space for the new boot loader entry and its referenced resources, the oldest existing boot loader entry matching the selected entry token gets removed โ€” along with any resources referenced by it that are no longer referenced by any other entry. This step repeats until the new boot loader entry fits. For robustness reasons, the currently booted boot loader entry is never removed, nor is the last existing boot loader entry. By default, the operation refuses to proceed if the resulting ESP/XBOOTLDR free space would drop below a safety threshold after automatic removal of older entries completes; use --keep-free= to adjust. Added in version 261.

  • link-auto โ€” like link, but instead of taking the kernel and sidecar resources as arguments, it discovers them automatically. the lazy-girl method, we love her ๐Ÿ’œ

These directories are searched, in decreasing order of priority:

  1. /etc/systemd/uki/
  2. /run/systemd/uki/
  3. /var/lib/systemd/uki/ (where systemd-sysupdate(8) stages downloaded resources)
  4. /usr/local/lib/systemd/uki/
  5. /usr/lib/systemd/uki/

In each directory the UKI is taken from kernel.efi, or โ€” if absent โ€” the newest version in the versioned directory kernel.efi.v/ (see systemd.v(7)); the UKI from the highest-priority directory that has one is used. Sidecar resources are picked up from the extras.d/ subdirectory of each, matching the suffixes .sysext.raw, .confext.raw and .cred, each either as a plain file or as a versioned .v/ directory; resources are combined across all directories, with the same resource in a higher-priority directory taking precedence. Any files specified with --extra= are linked in addition to the discovered ones.

This is what systemd-sysupdate(8) uses when it completes an update, so a freshly downloaded kernel and its sidecar resources are linked into place without specifying any paths. no cap, that's the whole point โœจ

Added in version 262.

  • cleanup โ€” removes files from the ESP and XBOOTLDR partitions that belong to the entry token but are not referenced in any boot loader entries. spring cleaning but make it boot loader ๐Ÿงน Added in version 253.

๐Ÿ’… BOOT LOADER INTERFACE COMMANDS ๐Ÿ’…

These work for all boot loaders that implement the UAPI.1 Boot Loader Specification[1] and the Boot Loader Interface[2] โ€” again, like systemd-boot. the full package, honestly ๐Ÿซถ

  • set-preferred ID, set-default ID, set-oneshot ID, set-sysfail ID โ€” sets the default boot loader entry. Takes a single boot loader entry ID string or a glob pattern as argument. Let's break down the sisterhood:
    • set-oneshot sets the default entry only for the next boot
    • set-default sets it persistently for all future boots
    • set-preferred is like set-default, but it's aware of boot assessment and will skip boot entries that have their tries-left counter set to zero. she's โœจthoughtfulโœจ
    • set-sysfail sets the boot loader entry to be used in case of a system failure

System failure (SysFail) boot entries can optionally modify the automatic selection order in the event of a failure, such as a boot firmware update failure with the failure status recorded in the EFI system table.

bootctl list can be used to list available boot loader entries and their IDs. ๐Ÿ‘ˆ reminder bestie

In addition, the boot loader entry ID may be specified as one of: @default, @oneshot or @current โ€” which correspond to the current default boot loader entry for all future boots, the current default boot loader entry for the next boot, and the currently booted boot loader entry. These special IDs are resolved to the current values of the EFI variables LoaderEntryDefault, LoaderEntrySysFail, LoaderEntryOneShot and LoaderEntrySelected โ€” see UAPI.1 Boot Loader Specification[1] for details. These special IDs are primarily useful as a quick way to persistently make the currently booted boot loader entry the default choice, or to upgrade the default boot loader entry for the next boot to the default boot loader entry for all future boots โ€” but they may be used for other operations too. versatile queen ๐Ÿ’…

If set to @saved the chosen entry will be saved as an EFI variable on every boot and automatically selected the next time the boot loader starts.

When an empty string ("") is specified as the ID, then the corresponding EFI variable will be unset. gone. deleted. ๐Ÿ’€

Hint: use systemctl reboot --boot-loader-entry=ID to reboot into a specific boot entry, and systemctl reboot --boot-loader-menu=timeout to reboot into the boot loader menu once. See systemctl(1) for details.

Added in version 240.

  • set-timeout TIMEOUT, set-timeout-oneshot TIMEOUT โ€” sets the boot loader menu timeout in seconds. The set-timeout-oneshot command sets the timeout only for the next boot. See systemd.time(7) for details about the syntax of time spans. โฐ

If this is set to menu-disabled or menu-hidden or 0, no menu is shown and the default entry will be booted immediately. Setting it to menu-force disables the timeout while always showing the menu. And when an empty string ("") is specified, the bootloader will revert to its default menu timeout. back to factory settings, we love a reset ๐ŸŒธ

Added in version 250.

โœจ SYSTEMD-BOOT COMMANDS โœจ

Okay bestie, these commands are strictly for the systemd-boot EFI boot loader and they do not play nice with any other boot loader. No crossovers, no collabs. ๐Ÿ’…


  • install โ€” Drops systemd-boot into the EFI system partition. A copy of systemd-boot gets stashed as the EFI default/fallback loader at ESP/EFI/BOOT/BOOT*.EFI. Then the boot loader gets yeeted to the top of the firmware's boot loader list. Main character placement, honestly. ๐Ÿ‘‘

Added in version 239.

  • update โ€” Updates every installed version of systemd-boot(7), but only if the version on hand is newer than the one already chillin' in the EFI system partition. That includes the EFI default/fallback loader at ESP/EFI/BOOT/BOOT*.EFI. If the boot loader is missing from the firmware's boot loader list, it gets added to the end of it. โœจ

Added in version 239.

  • remove โ€” Takes out all installed versions of systemd-boot from the EFI system partition and from the firmware's boot loader list. It's giving ghosting, but make it systemd. ๐Ÿ’€

Added in version 239.

  • is-installed โ€” Checks if systemd-boot is installed in the ESP. Heads up though: one single ESP can host multiple boot loaders, so this just checks whether systemd-boot is one (of possibly many) installed boot loaders โ€” it does not check whether it's the default, and it does not check whether it's registered in any EFI variables. Lowkey humble of it.

Added in version 243.

  • random-seed โ€” Generates a random seed and stores it in the EFI System Partition (ESP), for systemd-boot to use. If a random seed is already sitting in the ESP, it gets refreshed. It also generates a random 'system token' and stores it persistently as an EFI variable, but only if one hasn't been set before. If the boot loader finds the random seed in the ESP and the system token in the EFI variable, it derives a random seed to pass to the OS plus a new seed to store in the ESP, from the combination of both. The random seed handed to the OS gets credited to the kernel's entropy pool by the system manager during early boot, which lets userspace boot up with an entropy pool that's fully initialized very early on. Also peep systemd-boot-random-seed.service(8).

See Random Seeds[3] for further info.

Added in version 243.


๐Ÿง KERNEL IMAGE COMMANDS ๐Ÿง

  • kernel-identify KERNEL-IMAGE โ€” Takes a kernel image as its argument and checks what kind of kernel that image actually is. Returns one of "uki", "addon", "pe", and "unknown". Vibe check, but for kernels. ๐Ÿ”

Added in version 253.

  • kernel-inspect KERNEL-IMAGE โ€” Takes a kernel image as its argument and prints details about the image. Spills the tea on it, basically. ๐Ÿต

Added in version 253.


๐Ÿ’– OPTIONS ๐Ÿ’–

Here's everything bootctl understands, bestie. Read them all, they're all important, no skipping:

  • --esp-path= โ€” Path to the EFI System Partition (ESP). If you don't specify it, /efi/, /boot/, and /boot/efi/ get checked one after another. Recommendation: mount the ESP to /efi/ if you can. ๐ŸŽ€
  • --boot-path= โ€” Path to the Extended Boot Loader partition, as defined in the UAPI.1 Boot Loader Specification[1]. If you don't specify it, /boot/ gets checked. Recommendation: mount the Extended Boot Loader partition to /boot/ if you can.
  • --root=root โ€” Takes a directory path as its argument. All paths get prefixed with that alternate root path you gave, config search paths included.

Added in version 252.

  • --image=image โ€” Takes a path to a disk image file or block device node. If you give it one, all operations get applied to the file system inside that disk image. It's similar to --root=, except it operates on file systems stored in disk images or block devices. The disk image should either contain just a file system, or a set of file systems inside a GPT partition table, following the UAPI.2 Discoverable Partitions Specification[4]. Wanna know more about which disk images are supported? Check systemd-nspawn(1)'s switch with the same name.

Added in version 252.

  • --image-policy=policy โ€” Takes an image policy string as its argument, as per systemd.image-policy(7). That policy gets enforced when operating on the disk image you named with --image=, see above. If you don't specify one, it defaults to the "*" policy, meaning every recognized file system in the image gets used.
  • --install-source= โ€” When installing binaries with --root= or --image=, this selects where to source them from. Takes one of "auto" (the default), "image" or "host". With "auto", binaries get picked from the specified directory or image, and if they're not found there they get picked from the host. With "image" or "host", there is no fallback search โ€” if the binaries aren't in the selected source, that's it.

Added in version 252.

  • -p, --print-esp-path โ€” Modifies the behaviour of status. Only prints the path to the EFI System Partition (ESP) to standard output, then exits. Short and sweet. โœจ

Added in version 236.

  • -x, --print-boot-path โ€” Modifies the behaviour of status. Only prints the path to the Extended Boot Loader partition if it exists, otherwise the path to the ESP, to standard output, then exits. This one is super useful for figuring out where to put boot loader entries, because they'd preferably live in the Extended Boot Loader partition if it exists, and in the ESP otherwise.

Boot Loader Specification Type #1 entries should generally go in the directory "$(bootctl -x)/loader/entries/". Whether that directory exists can also be used as an indication that boot loader entry support is available on the system. Similarly, Boot Loader Specification Type #2 entries should go in the directory "$(bootctl -x)/EFI/Linux/".

Note that this option (just like the --print-esp-path option above) is available independently of which boot loader is in use, meaning it works even without systemd-boot being installed. ๐Ÿฆ‹

Added in version 242.

  • --print-loader-path โ€” Modifies the behaviour of status: it shows the absolute path to the boot loader EFI binary used for the current boot, if that info is available. Note that no attempt is made to verify whether the binary still exists. It might be gone, bestie, and this option will not tell you. ๐Ÿ’€

Added in version 257.

  • --print-stub-path โ€” Modifies the behaviour of status: it shows the absolute path to the UKI/stub EFI binary used for the current boot, if that info is available. Note that no attempt is made to verify whether the binary still exists.

Added in version 257.

  • -R, --print-root-device โ€” Prints the path to the block device node backing the root file system of the local OS. You get a path like /dev/nvme0n1p5. If the root file system is backed by dm-crypt/LUKS or dm-verity, the underlying block device is what comes back. If the root file system is backed by multiple block devices (like btrfs supports), the operation will fail. If you pass the switch twice (i.e. -RR) and the discovered block device is a partition device, the "whole" block device it belongs to gets determined and printed (e.g. /dev/nvme0n1). If the root file system is "tmpfs" (or a similar in-memory file system), the block device backing /usr/ gets returned, if applicable. And if the root file system is a network file system (e.g. NFS, CIFS), the operation will fail.

Added in version 254.

  • --print-efi-architecture โ€” Prints the EFI architecture string of the local firmware. This is handy for generically formatting filenames such as bootx64.efi that have the local firmware architecture in the name. ๐Ÿงš

Added in version 261.

  • --variables=yes|no|auto โ€” Controls whether to touch the firmware's boot loader list stored in EFI variables, plus other EFI variables. If you don't specify it, or set it to auto, EFI variables will not be modified when execution in a container runtime is detected. yes can be used to explicitly override that check.

Added in version 258.

  • --random-seed=yes|no โ€” By default, the install command initializes a random seed file in the ESP. When you're creating an image, you might wanna disable that so you don't end up with the same seed in every single instance. Not cute.

Added in version 257.

  • --graceful โ€” Ignores failure when the EFI System Partition can't be found, when EFI variables can't be written, or when a different or newer boot loader is already installed. Currently only applies to the is-installed, update, random-seed and install verbs. Since version v258, it's implicitly enabled when running inside a chroot.

Added in version 244.

  • -q, --quiet โ€” Suppresses printing of the results of various commands, and also the hints about the ESP being unavailable. Silence. ๐Ÿคซ

Added in version 251.

  • --make-entry-directory=yes|no โ€” Controls creation and deletion of the UAPI.1 Boot Loader Specification[1] Type #1 entry directory on the file system that holds resources such as kernel and initrd images, during install and remove respectively. The directory gets named after the entry token, as specified with the --entry-token= parameter described below, and it's placed immediately below the $BOOT root directory (i.e. beneath the file system returned by the --print-boot-path option, see above). Defaults to "no".

Added in version 251.

  • --entry-token= โ€” Controls how boot loader entries for this OS installation get named and identified. Accepted during install, and it takes one of "auto", "machine-id", "os-id", "os-image-id" or an arbitrary string prefixed by "literal:" as its argument.

If set to machine-id, the entries get named after the machine ID of the running system (e.g. "b0e793a9baf14b5fa13ecbe84ff637ac"). See machine-id(5) for the details about the machine ID concept and file.

If set to os-id, the entries get named after the OS ID of the running system, i.e. the ID= field of os-release(5) (e.g. "fedora"). Similarly, if set to os-image-id, the entries get named after the OS image ID of the running system, i.e. the IMAGE_ID= field of os-release (e.g. "vendorx-cashier-system").

If set to auto (the default), the /etc/kernel/entry-token file will be read if it exists, and the stored value used. Otherwise, if the local machine ID is initialized, it gets used. Otherwise, IMAGE_ID= from os-release gets used, if set. Otherwise, ID= from os-release gets used, if set.

Unless it's set to "machine-id" โ€” or when --make-entry-directory=yes is in the mix โ€” that selected token string gets written to a file at /etc/kernel/entry-token, so it's locked in for all the entries that come after. ๐Ÿ’พ That file is also read by kernel-install(8), so it knows under which name to generate boot loader entries for freshly installed kernels, and so it can figure out the entry names when it's time to remove the old ones.

Naming your entries with the machine ID is generally the move, but there are totally cases where the other identifiers hit better. Specifically: if the identification data that the machine ID entails shall not be stored on the (unencrypted) $BOOT partition, or if the ID shall be generated on first boot and is not known when the entries are prepared. And here's the tea โ€” using the machine ID has the benefit that multiple parallel installations of the same OS can coexist on the same medium, and they can update their boot loader entries independently. ๐Ÿ‘ฏ When you use another identifier instead (like the OS ID or the OS image ID), parallel installations of the same OS would try to use the same entry name. To support parallel installations, the installer must use a different entry token when adding a second installation.

Added in version 251.

  • --all-architectures โ€” installs binaries for all supported EFI architectures (and yes, this implies --variables=no). ๐Ÿ’…

Added in version 252.

  • --efi-boot-option-description= โ€” the description of the entry that gets added to the firmware's boot option list. Defaults to "Linux Boot Manager".

Using the default entry name "Linux Boot Manager" is generally preferable, because only one bootloader installed to a single ESP partition should be used to boot any number of OS installations found on the various disks installed in the system. Specifically, distributions should not use this flag to install a branded entry in the boot option list. That said โ€” in situations with multiple disks, each with their own ESP partition, it can be beneficial to make it easier to identify the bootloader being used in the firmware's boot option menu.

Added in version 252.

  • --efi-boot-option-description-with-device= โ€” takes a boolean, defaults to false. Controls whether to append disk model information to the firmware boot option item description (as configured with --efi-boot-option-description= above). This is a whole vibe when you're installing multiple operating systems on separate disks on the same system, because it makes sure the firmware boot options are discernible and gives a hint which disk is being booted into. โš ๏ธ Just note that this uses hardware model information, so it might not be too useful in case multiple disks of an identical model are used.

Added in version 260.

  • -n, --dry-run โ€” dry run for unlink and cleanup.

In dry run mode, the unlink and cleanup operations only print the files that would get deleted, without actually deleting them. The short option -n was added in version 262.

Added in version 253.

  • --oldest โ€” when used with unlink, selects the oldest installed boot loader entry matching the boot entry token for removal (rather than passing an explicit entry ID). So useful for pruning older installed boot loader entries. ๐ŸŒฑ Note that the currently booted entry is never removed, nor is the last remaining one.

Added in version 261.

  • --keep-free=BYTES โ€” when used with link, controls the minimum amount of free space (in bytes) that must remain on the target partition (ESP or XBOOTLDR) after the new entry has been materialized. The operation fails if installing the entry would drop the free space below this threshold. Accepts the usual size suffixes (K, M, G, ...). If empty, the built-in default is restored. If set to zero, no minimum amount of free space is kept.

Added in version 261.

  • --entry-title=TITLE โ€” when used with link, specifies the title of the generated boot loader entry (the "title" field of the Type #1 entry). If not specified, a title is derived from the UKI's embedded metadata.

Added in version 261.

  • --entry-version=VERSION โ€” when used with link, specifies the version string of the generated boot loader entry (the "version" field of the Type #1 entry). If not specified, the version is derived from the UKI's embedded metadata. The boot loader uses this to sort and select entries.

Added in version 261.

  • --entry-commit=NR โ€” when used with link, specifies the commit number for the generated boot loader entry.

Added in version 261.

  • --extra=PATH, -X PATH โ€” when used with link, registers an additional sidecar resource file that shall be passed to the UKI at boot. This may be a system extension image (*.sysext.raw), configuration extension image (*.confext.raw), or credential file (*.cred). The file is copied into the ESP/XBOOTLDR alongside the UKI and the boot loader will load and pass it to the kernel via initrd. This option may be used multiple times to register more than one extra resource. If passed an empty argument, all previously specified extras are cleared. ๐Ÿงน

Added in version 261.

  • --tries-left=NR โ€” when used with link, initializes the boot counting "tries-left" counter for the generated entry. If set, the resulting boot entry file is named according to the boot counting scheme described in the Automatic Boot Assessment[5] documentation, so that the boot loader decreases the counter on each attempted boot and eventually marks the entry as bad. If not specified, boot counting is not enabled for the generated entry. ๐Ÿ”ข

Added in version 261.

  • --secure-boot-auto-enroll=yes|no, --private-key=PATH/URI, --private-key-source=TYPE[:NAME], --certificate=PATH, --certificate-source=TYPE[:NAME] โ€” configure the ESP for secure boot auto-enrollment when invoking the install command. Takes a boolean argument. Disabled by default. Enabling this option will make bootctl populate the ESP with signed "PK", "KEK" and "db" signature databases, each containing the given certificate in "DER" format as their only entry. These secure boot signature databases will be picked up and enrolled by systemd-boot if secure boot is in setup mode and secure boot auto-enrollment is enabled. ๐Ÿ”

When specifying this option, a certificate and private key have to be provided as well using the --certificate= and --private-key= options. The --certificate= option takes a path to a PEM encoded X.509 certificate or a URI that's passed to the OpenSSL provider configured with --certificate-source which takes one of "file" or "provider", with the latter being followed by a specific provider identifier, separated with a colon, e.g. "provider:pkcs11". The --private-key= option can take a path or a URI that will be passed to the OpenSSL engine or provider, as specified by --private-key-source= as a "type:name" tuple, such as "engine:pkcs11". The specified OpenSSL signing engine or provider will be used to sign the EFI signature lists.

Added in version 257.

  • --no-pager โ€” do not pipe output into a pager. โœ‹
  • --json=MODE โ€” shows output formatted as JSON. Expects one of "short" (for the shortest possible output without any redundant whitespace or line breaks), "pretty" (for a pretty version of the same, with indentation and line breaks) or "off" (to turn off JSON output, the default). โœจ
  • -h, --help โ€” print a short help text and exit. ๐Ÿซถ
  • --version โ€” print a short version string and exit.

๐ŸŽ€ SIGNED .EFI FILES ๐ŸŽ€

bootctl install and update will look for a systemd-boot file ending with the ".efi.signed" suffix first, and copy that instead of the normal ".efi" file. This is the hook that lets distributions or end-users provide signed images for UEFI SecureBoot. ๐Ÿ”


๐Ÿ’– EXIT STATUS ๐Ÿ’–

On success, 0 is returned, a non-zero failure code otherwise. bootctl --print-root-device returns exit status 80 in case the root file system is not backed by single block device, and other non-zero exit statuses on other errors. ๐Ÿ“Ÿ


๐ŸŒˆ ENVIRONMENT ๐ŸŒˆ

  • If $SYSTEMD_RELAX_ESP_CHECKS=1 is set, the validation checks for the ESP are relaxed, and the path specified with --esp-path= may refer to any kind of file system on any kind of partition. ๐Ÿ˜Œ
  • Similarly, $SYSTEMD_RELAX_XBOOTLDR_CHECKS=1 turns off some validation checks for the Extended Boot Loader partition.

๐ŸŒธ EXAMPLES ๐ŸŒธ

โœจ Example 1. Output from status and list โœจ

okay bestie, this is the moment โ€” here's what it actually looks like when you run it ๐Ÿ’–

$ bootctl status
System:
     Firmware: UEFI 2.40 (firmware-version)  โ† firmware vendor and version
  Secure Boot: disabled (setup)              โ† Secure Boot status
 TPM2 Support: yes
 Boot into FW: supported                     โ† does the firmware support booting into itself

Current Boot Loader:                         โ† details about systemd-boot or another boot loader
      Product: systemd-boot version            implementing the Boot Loader Interface[2]
     Features: โœ“ Boot counting
               โœ“ Menu timeout control
               โœ“ One-shot menu timeout control
               โœ“ Default entry control
               โœ“ One-shot entry control
               โœ“ Support for XBOOTLDR partition
               โœ“ Support for passing random seed to OS
               โœ“ Load drop-in drivers
               โœ“ Boot loader sets ESP information
               โœ“ Menu can be disabled
          ESP: /dev/disk/by-partuuid/01234567-89ab-cdef-dead-beef00000000
         File: โ””โ”€/EFI/systemd/systemd-bootx64.efi

Random Seed:                                 โ† random seed used for entropy in early boot
 Passed to OS: yes
 System Token: set
       Exists: yes

Available Boot Loaders on ESP:
          ESP: /boot/efi (/dev/disk/by-partuuid/01234567-89ab-cdef-dead-beef00000000)
         File: โ””โ”€/EFI/systemd/systemd-bootx64.efi (systemd-boot 251
         File: โ””โ”€/EFI/BOOT/BOOTX64.EFI (systemd-boot 251

Boot Loaders Listed in EFI Variables:
        Title: Linux Boot Manager
           ID: 0x0001
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/...
         File: โ””โ”€/EFI/systemd/systemd-bootx64.efi

        Title: Fedora
           ID: 0x0000
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/...
         File: โ””โ”€/EFI/fedora/shimx64.efi

        Title: Linux-Firmware-Updater
           ID: 0x0002
       Status: active, boot-order
    Partition: /dev/disk/by-partuuid/...
         File: โ””โ”€/EFI/fedora/fwupdx64.efi

Boot Loader Entries:
        $BOOT: /boot/efi (/dev/disk/by-partuuid/01234567-89ab-cdef-dead-beef00000000)

Default Boot Loader Entry:
         type: Boot Loader Specification Type #1 (.conf)
        title: Fedora Linux 36 (Workstation Edition)
           id: ...
       source: /boot/efi/loader/entries/entry-token-kernel-version.conf
      version: kernel-version
   machine-id: ...
        linux: /entry-token/kernel-version/linux
       initrd: /entry-token/kernel-version/initrd
      options: root=...

$ bootctl list
Boot Loader Entries:
         type: Boot Loader Specification Type #1 (.conf)
        title: Fedora Linux 36 (Workstation Edition) (default) (selected)
           id: ...
       source: /boot/efi/loader/entries/entry-token-kernel-version.conf
      version: kernel-version
   machine-id: ...
        linux: /entry-token/kernel-version/linux
       initrd: /entry-token/kernel-version/initrd
      options: root=...

         type: Boot Loader Specification Type #2 (.efi)
        title: Fedora Linux 35 (Workstation Edition)
           id: ...
       source: /boot/efi/EFI/Linux/fedora-kernel-version.efi
      version: kernel-version
   machine-id: ...
        linux: /EFI/Linux/fedora-kernel-version.efi
      options: root=...

         type: Automatic
        title: Reboot Into Firmware Interface
           id: auto-reboot-to-firmware-setup
       source: /sys/firmware/efi/efivars/LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f

so in that listing, (default) is telling you which entry is gonna be used by default โ€” like, the one that just happens by default โœจ โ€” and (selected) is the entry that was picked the last time you booted, aka the one that is currently running right now. two different vibes, both iconic ๐Ÿ’…


๐ŸŽ€ FILES ๐ŸŽ€

  • /etc/systemd/uki/, /run/systemd/uki/, /var/lib/systemd/uki/, /usr/local/lib/systemd/uki/, /usr/lib/systemd/uki/ โ€” okay so these are the directories that the link-auto command digs through to find the UKI it's gonna install. they're listed in decreasing order of priority, meaning the first one is the most main-character ๐Ÿ‘‘. it takes kernel.efi, or the versioned kernel.efi.v/ directory, from the highest-priority directory that actually has one. and the extra sidecar stuff โ€” system extension images, configuration extension images, credential files โ€” gets scooped up from the extras.d/ subdirectory of each one of them, combined across all the directories, no cap ๐Ÿซถ.

and just so you know, /var/lib/systemd/uki/ is the directory where systemd-sysupdate(8) is supposed to drop the downloaded kernels, system extensions, configuration extensions and credentials. that's its whole job, bestie.

Added in version 262. โœจ


๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹

systemd-boot(7), UAPI.1 Boot Loader Specification[1], Boot Loader Interface[2], systemd-boot-random-seed.service(8)


๐Ÿ’œ NOTES ๐Ÿ’œ

  1. UAPI.1 Boot Loader Specification https://uapi-group.org/specifications/specs/boot_loader_specification
  2. Boot Loader Interface https://systemd.io/BOOT_LOADER_INTERFACE
  3. Random Seeds https://systemd.io/RANDOM_SEEDS
  4. UAPI.2 Discoverable Partitions Specification https://uapi-group.org/specifications/specs/discoverable_partitions_specification
  5. Automatic Boot Assessment https://systemd.io/AUTOMATIC_BOOT_ASSESSMENT

and that's a wrap on the whole page, bestie ๐ŸŽ‰ you just read the bootctl(1) manpage from top to bottom, which is genuinely so much reading and I'm obsessed with you for it ๐Ÿ’– this one ships with systemd 262.1, and yeah it's the BOOTCTL(1) page โ€” go forth, boot things, slay ๐Ÿซถโœจ๐ŸŽ€

๐Ÿ“ฆ where this page comes from
  • arch rolling: systemd 262.1-1 ยท LGPL-2.1-or-later AND CC0-1.0 AND GPL-2.0-or-later AND MIT-0
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms