BOOSTER(1)
β¨ NAME β¨
Okay bestie, this is the BOOSTER(1) page from the General Commands Manual β and the command itself is booster, literally the fast and secure initramfs generator. π
πΈ DESCRIPTION πΈ
So booster is the tool that creates initramfs images β the little early-boot starter pack Linux needs before the real root filesystem shows up. It was made with speed and the full-disk-encryption use-case in mind, no cap. β¨
Why is booster iconic? Let's get into it:
- Fast image build time and fast boot time. β‘ Two kinds of fast, periodt.
- Out-of-box support for LUKS-based full disk encryption setup. π It just gets it.
- Clevis style data binding. The encrypted filesystem can be bound to a TPM2 chip or to a network service. This helps to unlock the drive automatically but only if the TPM2/network service is present. π«Ά
- Automatically detects and unlocks
systemd-cryptenroll(fido2 and tpm2) types of partition encryption. π - Easy to configure. Lowkey a gift.
- Automatic host configuration discovery. This helps to create minimalistic images specific for the current host. π
π CONFIG FILE π
The booster generator config file lives at /etc/booster.yaml β that's the main character file, bestie. Here's a sample config file:
network:
interfaces: enp0s31f2,2e:1d:61:30:a3:63
dhcp: on
# either dhcp above or static configuration below can be used
ip: 10.0.2.15/24
gateway: 10.0.2.255
dns_servers: 192.168.1.1,8.8.8.8
ssh_host_key: /etc/booster/ssh_host_ed25519_key
ssh_authorized_keys: /etc/booster/authorized_keys
ssh_listen: :22
universal: false
modules: -*,hid_apple,kernel/sound/usb/,kernel/fs/btrfs/btrfs.ko,kernel/lib/crc4.ko.xz
compression: zstd
mount_timeout: 5m6s
strip: true
extra_files: vim,/usr/share/vim/vim82/,fsck,fsck.ext4
vconsole: true
enable_lvm: true
enable_mdraid: true
token_timeout: 30s
pin_delay: 5s
serialize_tokens:
enabled: true
clevis_timeout: 45s
Now let's go through the keys one by one, because every single one matters:
networkβ if present, this node initializes the network at boot time. It's needed if mounting a root fs requires access to the network (e.g. in case of Tang binding). The network can be either configured dynamically with DHCPv4 or statically within this config. In the former casedhcpis set toon. In the latter case the config lets you specifyipβ the machine IP address and its network mask βgatewayβ default gateway β anddns_serversβ comma-separated list of DNS servers. Thenetworknode also accepts theinterfacesproperty β a comma-separated list of network interfaces (specified either with name or MAC address) to enable at boot time. Network names likeenp0s31f6get resolved to MAC addresses at generation time and then passed to init. If theinterfacesnode is not specified then all the interfaces are activated at boot. Thenetworknode also acceptsssh_host_key,ssh_authorized_keys, andssh_listento enable remote LUKS unlock over SSH.ssh_host_keyis a path to an OpenSSH- or PEM-encoded SSH host private key,ssh_authorized_keysis a path to anauthorized_keysfile, andssh_listenis the listen address (default:22). Bothssh_host_keyandssh_authorized_keysmust be set together, and SSH requiresdhcp: trueor a staticip. See REMOTE UNLOCK below. πuniversalβ a boolean flag that tells booster to generate a universal image. By default booster generates a host-specific image that includes kernel modules used at the current host. For example if the host does not have a TPM2 chip thentpmmodules are ignored. A universal image includes many kernel modules and tools that might be needed at a broad range of hardware configurations. πmodulesβ a comma-separated list of extra modules to add to or remove from the generated image. One can use a module name or a path relative to the modules dir (/usr/lib/modules/$KERNEL_VERSION). The compression algorithm suffix (e.g..xz,.gz) can be omitted from the module filename. If the element starts with a minus sign (-) then it means "do not add it to the image", otherwise modules are added. If the path ends with a slash symbol (/) then it is considered a directory and all modules from this directory need to be added recursively. A special symbol*(star) means all modules. It can be used for example to add all modules or remove all predefined modules from the image. Booster also takes module dependencies into account β all dependencies of the specified modules will be added to the image as well. π§modules_force_loadβ list of module names that are forcibly loaded during the boot process before switching into user-space. Any module in this list is automatically added to the image, so there's no need to duplicate it at themodulesproperty. π₯append_all_modaliasesβ a boolean flag that instructs booster to add all the host's module aliases to the booster image. This flag is useful for debugging boot timeout issues when some important modules are missed from the image. Setting the flag totruewill help to print module names for aliases that were requested by kernel but missed in the image. π΅οΈcompressionβ a flag that specifies compression for the output initramfs file. Currently supported algorithms are"zstd","gzip","xz","lz4","none". If no option is specified,"zstd"is used as the default compression. ποΈmount_timeoutβ timeout for waiting for the root filesystem to appear. The field format is a decimal number and then unit number. Valid units are"s","m","h". If no value is specified, the default timeout (3 minutes) is used. To disable the timeout completely specify"0s". β³stripβ a boolean flag that enables stripping of ELF files before adding them to the image. Binaries, shared libraries and kernel modules are examples of ELF files that get processed with thestripUNIX tool. π§
This option is not compatible with signed modules. If you seebooster: finit(crc32,generic): key was rejected by serviceas a boot error, please set thestripconfig option tofalse. π
extra_filesβ a comma-separated list of extra files to add to the image. If an item starts with slash (/) then it is considered an absolute path. Otherwise it is a path relative to/usr/bin. If the item is a directory then its content is added recursively. There are a few special cases:- Adding
busyboxto the image enables an emergency shell in case of a panic during the boot process. π¨ - Adding
fsckenables boot time filesystem check. It also requires filesystem specific binary calledfsck.$rootfstypeto be added to the image. Filesystems are corrected automatically and if it fails then boot stops and it is the responsibility of the user to fix the root filesystem. π οΈ
- Adding
vconsoleβ a flag that enables early-user console configuration. If it is set totruethen booster reads configuration from/etc/vconsole.confand/etc/locale.confand adds required keymap and fonts to the generated image. The following config properties are taken into account:KEYMAP,KEYMAP_TOGGLE,FONT,FONT_MAP,FONT_UNIMAP. See also manvconsole.confathttps://man.archlinux.org/man/vconsole.conf.5.en. π¨enable_lvmβ a flag that enables LVM volume assembly at boot time. This flag also makes sure all the required modules/binaries are added to the image. π½enable_mdraidβ a flag that enables MdRaid assembly at boot time. This flag also makes sure all the required modules/binaries are added to the image. π§±enable_zfsβ a flag that enables ZFS filesystem as root filesystem. This flag also makes sure all the required modules/binaries are added to the image. Note that if ZFS is enabled thenzfs=boot option must be used instead ofroot=boot option. πcrypttab_pathβ path to the crypttab file to read at image build time. Defaults to/etc/crypttabif not set. Can be overridden by the--crypttabflag. If set, any read error is reported as a failure. πenable_plymouthβ a flag that enables Plymouth boot splash support. When enabled, booster bundles the Plymouth daemon, plugins, theme, and fonts into the initramfs. GPU driver must be included inmodules_force_load. Thequiet splashkernel parameters are also required. π«Ά
Note thatbooster.log=consoleconflicts with Plymouth's graphical display; when console logging is active, Plymouth reverts to thedetailsplugin (text-based fallback). π
enable_fido2β a boolean flag that enables FIDO2 hardware token support. πserialize_tokensβ makes booster try a device's LUKS tokens one at a time in ascending token-ID order instead of racing them concurrently (default off). A non-interactive token (TPM2 PCR-only, touchless FIDO2, clevis) enrolled before a PIN token then unlocks the device before the PIN prompt is reached. Each non-interactive token is bounded by a per-type timeout so a stuck one cannot hang the boot; on expiry booster moves to the next. PIN tokens are not bounded (empty-Enteralready skips them). Keys:serialize_tokens.enabledβ boolean, defaultfalse. ποΈserialize_tokens.clevis_timeout/serialize_tokens.tpm2_timeout/serialize_tokens.fido2_timeoutβ per-token bounds for clevis, non-PINsystemd-tpm2, and non-PINsystemd-fido2. Go duration. Defaults45s/15s/30s. No effect unlessserialize_tokens.enabledis set. β±οΈ
token_timeout(top-level, applies in both modes) β bounds how long booster waits for tokens before it also starts the keyboard passphrase prompt. The tokens keep racing after the prompt appears; whichever path wins first dismisses the other (see LUKS unlock concurrency and prompt order in NOTES). It is the booster-config equivalent of thecrypttab/rd.luks.optionstoken-timeout=(seerd.luks.optionsunder BOOT TIME KERNEL PARAMETERS). Go duration. Precedence, highest first:- an explicit per-device
token-timeout=β on the kernel cmdline (rd.luks.options) or in crypttab; the cmdline value wins when both set it for the same device. - this
token_timeout. - in serialize mode, the sum of the device's per-token timeouts (so the keyboard prompt never preempts a token that has not had its turn).
- the
30sdefault.
- an explicit per-device
In serialize mode prefer leaving token_timeout unset so tier 3 applies: a fixed value shorter than the token chain can start the keyboard prompt before a token has had its turn. π«Ά
pin_delayβ ok so this is the concurrent-mode bestie ofserialize_tokensπ it holds the first interactive PIN prompt (TPM2-PIN, FIDO2-PIN) for this long, so a parallel non-interactive token can swoop in and unlock first, and the prompt literally never gets drawn β cancelled before render if a token wins, shown like normal if the delay runs out (no unlock path is lost, the delay only postpones the prompt, promise π«Ά). It's a Go duration; unset (the default) means no delay at all. No effect in serialize mode, and no effect when no parallel non-PIN token is enrolled (a PIN-only device just prompts immediately, no waiting around). Set it longer than the racing token's real unlock time β TPM2/FIDO2 hardware bring-up, or for clevis the network/DHCP round-trip β but well belowtoken_timeout, otherwise the prompt gets drawn anyway π. A few seconds suits a fast PCR-only TPM2 unseal; clevis-over-network or a universal image with slow module loading needs more.
Once you're done editing your config file and you wanna regenerate booster images under /boot, pls use /usr/lib/booster/regenerate_images β¨. It's a lil convenience script that does the same type of image regeneration as if you installed booster with your package manager. Slay.
π COMMAND-LINE FLAGS π
Application Options
-v,--verboseβ turn on verbose output, so you can see everything happening π
SUBCOMMANDS
π οΈ build
Build the initrd image, obvs. Usage: booster [OPTIONS] build [build-OPTIONS] output
-f,--forceβ overwrite the existing initrd file (no fear, no hesitation π)--init-binary <default: /usr/lib/booster/init>β where the Boosterinitbinary lives.--compression <default: zstd>β compression of the output file. Possible values:zstd,gzip,xz,lz4,none.--kernel-versionβ Linux kernel version to generate the initramfs for.--config <default: /etc/booster.yaml>β path to the configuration file.--universalβ add a wide range of modules/tools so this image can boot on different machines π--stripβ strip ELF files (binaries, shared libraries and kernel modules) before adding them to the image.--crypttab <default: /etc/crypttab>β path to the crypttab file to read at image build time. Overridescrypttab_pathfrom the config file. If neither is set, booster reads/etc/crypttaband silently skips it if the file is absent or unreadable. But if you specify it explicitly, any read error gets reported as a failure, no cap.
π± cat
Show the content of a file inside the image. Usage: booster [OPTIONS] cat image file-in-image
π ls
List the content of the image. Usage: booster [OPTIONS] ls image
π¦ unpack
Unpack the image. Usage: booster [OPTIONS] unpack image output-dir
π¦ BOOT TIME KERNEL PARAMETERS π¦
Some parts of booster boot functionality can be tweaked with kernel boot parameters π. These are usually set through your bootloader config. Booster boot uses the following kernel parameters:
root=$devicerefβ device reference to the root device. See "Device Reference" in NOTES for how to specify it, and "ROOT PARTITION DISCOVERY" for how booster handles unencrypted, LUKS, and autodiscovered roots.rootfstype=$TYPE(e.g.rootfstype=ext4) β by default booster tries to detect the root filesystem type. But if the autodetection doesn't work, this kernel parameter is the save π. Also pls file a ticket so we can improve the code that detects filetypes.rootflags=$OPTIONSβ mount options for the root filesystem, e.g.rootflags=user_xattr,nobarrier. In partition autodiscovery mode, GPT attribute 60 ("read-only") is taken into account.rd.luks.uuid=$UUIDβ UUID of the LUKS partition where the root partition is enclosed. booster will try to unlock this LUKS device.rd.luks.name=$UUID=$NAMEβ same vibe as therd.luks.uuidparameter, but it also specifies the name used for opening the LUKS device.rd.luks.key=$UUID=$PATHβ absolute path to a keyfile in the initrd/initramfs that can be used to unlock the device identified by UUID. If this file doesn't exist or fails to unlock it, it falls back to a password request.rd.luks.header=$UUID=$PATHβ detached LUKS header for the device identified by$UUID.$PATHcan take three forms:- Initramfs file β an absolute path (e.g.
/etc/luks/root.hdr) to a header file bundled into the initramfs at build time viaextra_files. - Raw block device β a device path (e.g.
/dev/sdb) where the LUKS header begins at byte offset 0. Booster waits for the device to appear and passes it directly to cryptsetup without mounting. - File on a separate device β
$path:$devicerefwhere$devicerefisUUID=...,LABEL=...,PARTUUID=..., orPARTLABEL=.... Booster mounts the device read-only, reads the header file, then unmounts before unlocking.
- Initramfs file β an absolute path (e.g.
rd.luks.options=opt1,opt2β a comma-separated list of LUKS flags. Supported options arediscard,same-cpu-crypt,submit-from-crypt-cpus,no-read-workqueue,no-write-workqueue.token-timeout=<duration>sets how long to wait for hardware tokens (FIDO2, TPM2) before also prompting for a keyboard passphrase. Accepts a decimal number followed by a unit (s,m,h), or a bare integer treated as seconds. Default is30 s. Note that booster also supports LUKS v2 persistent flags stored with the partition metadata. Any command-line options are added on top of the persistent flags, periodt.rd.modules_force_loadβ a comma-separated list of extra kernel modules that should be force loaded.resume=$devicerefβ device reference to the suspend-to-disk device.zfs=$pool/$datasetβ specifies what ZFS dataset needs to be used for the root partition. This option is only used if the ZFS config option is enabled. If the ZFS filesystem is enabled then theroot=boot param is ignored π»booster.logβ configures booster init logging. It accepts a comma separated list of the following values:- One of the level values (from more verbose to less verbose) β
debug,info,warning,errorornull. That last level ofnulldisables any logging, so β use it only if know what you are doingβ . If the level isn't specified theninfois used by default. consoleβ print booster init logs to console.
- One of the level values (from more verbose to less verbose) β
The debug log is also printed to the kernel kmsg buffer and available for reading either with dmesg or with journalctl -b. If debug level is enabled then kmsg throttling gets disabled automatically β¨
booster.debugβ an obsolete option that's equivalent tobooster.log=debug,console.quietβ set booster init verbosity to minimum. This option is ignored ifbooster.debugorbooster.logis set.init=$PATHβ path to the user-space init binary. If not specified then the default value/sbin/initis used.
π ROOT PARTITION DISCOVERY π
Booster identifies the root filesystem from the kernel cmdline and, if it's encrypted, unlocks the LUKS container before mounting π. Most setups land on one of the configurations below.
Unencrypted root
root=UUID=<filesystem-uuid>
PARTUUID=, LABEL=, or a /dev/... path also work π
Encrypted (LUKS) root
There are four ways to set it up. Pick whichever fits your bootloader and existing tooling.
Named via cmdline.
rd.luks.name=<luks-partition-uuid>=<name> root=/dev/mapper/<name>
See rd.luks.name, rd.luks.uuid, and friends under BOOT TIME KERNEL PARAMETERS for the full set.
Named via /etc/crypttab. Add an entry marked x-initrd.attach; the first column becomes the mapper name. Pair with root=/dev/mapper/<name> on the cmdline. See CRYPTTAB below for syntax and bundling rules.
Auto-named. With no rd.luks.* on the cmdline and no crypttab entry covering this volume, point root= at the LUKS container itself:
root=UUID=<luks-partition-uuid>
Booster unlocks it as /dev/mapper/root and mounts that. PARTUUID=, LABEL=, or a /dev/... path resolving to the container also work.
Zero kernel parameters. Tag the partition with the per-architecture root GUID and booster discovers it with no root= argument at all π§ See GPT autodiscovery below.
GPT autodiscovery (no cmdline at all)
Set the root partition's GPT type to "Linux root" for your CPU architecture using any GPT editor (gdisk, sgdisk, fdisk, cfdisk, parted, ...). On x86-64 with gdisk, for instance, the type code is 8304. Other tools and architectures use different shortcuts; consult your editor's type list. The full per-architecture GUID list is in the Discoverable Partitions Specification https://uapi-group.org/specifications/specs/discoverable_partitions_specification/.
The same GUID covers both plain-filesystem and LUKS-encrypted roots β booster handles either, iconic π Booster scans only the disk that holds the active EFI System Partition; root-tagged partitions on other disks are ignored. Tag exactly one partition on that disk.
When boot stalls
If root=/dev/mapper/<name> is set but no source above produces that mapper, booster prints
root=/dev/mapper/<name> but no LUKS unlock spec was found for "<name>"
before stalling at the mount-timeout π Add any of the unlock recipes above and rebuild.
π CRYPTTAB π
okay so booster can totally unlock your LUKS volumes if you just tell it about them in /etc/crypttab β like, that's the whole vibe. see crypttab(5) (https://man7.org/linux/man-pages/man5/crypttab.5.html) if you need the lore. π
but β and this is the important part, bestie β only the entries that have the x-initrd.attach option on them get bundled into the initramfs at image build time. no option, no entry, no nothing. π«Ά
also the generator has got to be able to read that file, so either run it as root, or pass --crypttab <path> pointing at a copy your user can actually read. no cap.
π when both show up (cmdline vs crypttab)
this is where it gets juicy. if you've got both a rd.luks.* cmdline parameter and a crypttab entry covering the same device, then the cmdline wins for:
- the device reference
- the mapper name
- any security option it sets explicitly (
keyfile,header,tries,token-timeout, β¦)
and the crypttab entry only fills in the stuff the cmdline left unset. it's giving "cmdline is the main character, crypttab is the supportive bestie." β¨
and crypttab entries for devices that rd.luks.* doesn't cover? those just get appended as brand-new mappings. slay.
π booster-specific behaviour for selected options
these three options have special sauce, so listen up:
keyfile/path:UUID=xxx(orLABEL=,PARTUUID=,PARTLABEL=) β this is a keyfile living on a separate device. booster mounts that device read-only at boot, reads the key, then unmounts it. the file does not get bundled into the initramfs. she reads it live, she doesn't take it home with her. πheader=β if the path is a plain absolute path, the generator auto-bundles that file into the initramfs for you, no extra steps. the/path:devicerefform mounts the device at boot instead. and if it's/dev/...it just goes straight at the raw block device. πfido2-device=β the moment this shows up in a crypttab entry, the generator automatically bundlesfido2plugin.so. so you do not needenable_fido2: truein the config file for this. iconic. (also, bothfido2-device=andtpm2-device=are otherwise accepted for compatibility β but booster discovers enrolled tokens from the LUKS2 header, not from whatever value you put in the crypttab option. iykyk. π₯)keyfile-timeout=/token-timeout=β these take either a bare integer (that's seconds) or literally any duration string that Go'stime.ParseDurationaccepts. so like30s,2m, whatever floats your boat. πΈ
π¦ REMOTE UNLOCK π¦
okay this is the part where i get actually excited. booster can unlock your LUKS volumes from a remote SSH client during early boot. like, from another machine. before your system is even fully up. it's giving hacker movie but make it cozy. π
here's the flow: the SSH server starts once networking is up (either a DHCP lease got acquired or a static ip got configured), and then it prompts the connecting client for a LUKS passphrase. the passphrase you submit gets broadcast to every LUKS device currently sitting at a keyboard prompt. and if one unlocks, it seeds the in-boot passphrase cache β so sibling volumes with the same key just open up with no further prompting. obsessed. π
it's the equivalent of Debian's dropbear-initramfs setup, except it's native to booster β it uses Go's golang.org/x/crypto/ssh instead of bundling dropbear. no extra dependency drama. β¨
ποΈ step one: make a host key
generate it once, keep it on the host, and it gets embedded into the image at build time:
$ ssh-keygen -t ed25519 -f /etc/booster/ssh_host_ed25519_key -N ''
π step two: make an authorized_keys
one or more public keys, one per line, exactly like this:
ssh-ed25519 AAAAC3Nz...user1@laptop
ssh-ed25519 AAAAC3Nz...user2@phone
π§ step three: wire both files into /etc/booster.yaml
network:
dhcp: on
ssh_host_key: /etc/booster/ssh_host_ed25519_key
ssh_authorized_keys: /etc/booster/authorized_keys
ssh_listen: :22
both ssh_host_key and ssh_authorized_keys get read at image build time and embedded into the initramfs. and heads up β one without the other is a config error. you can't just show up with half the fit. π
also: SSH needs network.dhcp: true or a static network.ip. no network, no party.
π» step four: connect from a client
connect as root and paste the passphrase right at the prompt:
$ ssh -p 22 root@<host>
that's it. that's the whole ritual. π«Ά
β οΈ security notes (please actually read these, bestie)
these aren't the fun part but they are the important part. don't skip. π
- pubkey-only auth. password auth is simply not supported. per-session attempts are capped at 10 wrong submissions before disconnect, and the SSH handshake itself has to complete within 15 seconds β that's the slow-loris guard. β±οΈ
- the host private key and the enrolled
authorized_keysare read at image build time and embedded into the initramfs. anyone with read access to/boot(or to the image file) can extract both. treat them as compromised whenever/bootis exposed, and rebuild the image to rotate the host key. this is not a drill. π - the host key fingerprint is stable across reboots β no auto-regen β so
known_hostsdoesn't churn. your client stays happy. π - the SSH port plus a stolen copy of any private key listed in
authorized_keysis enough for an attacker to keep guessing LUKS passphrases against the live server. yes, we disconnect a session after 10 wrong submissions β but nothing stops the attacker from reconnecting and trying 10 more. the cap slows brute force, it does not stop it. anyone who can reach the SSH port is in a position roughly equivalent to direct LUKS keyslot exposure. π¨ ssh_listen: :22listens on every network interface that comes up at boot, on both IPv4 and IPv6 β including link-local IPv6 addresses (fe80::...) that auto-configure without DHCP. so pinssh_listento an exact address (for example10.0.0.5:22) so only the interface you actually intend to expose is reachable, and firewall the port at the network boundary. don't leave the door open and then act surprised. π- the session is restricted to the passphrase prompt β no shell, no command execution, no port forwarding, no PAM, no PTY allocation. it does one thing and it does it well. β¨
π NOTES π
π Device Reference π
So a "device reference" is literally just the way you name a device or partition inside kernel parameters β it's the thing labelled $deviceref above. And bestie, it can be one of these:
/dev/XXXβ a path to a specific device file. Could be a real device/partition like/dev/sda1,/dev/nvme0n1, or a dm-mapper virtual device like/dev/mapper/rootor/dev/vg_mesos/lv_mesos_containers. iykyk.UUID=$UUIDor/dev/disk/by-uuid/$UUIDβ references the device by its filesystem/LUKS UUID. (Peep the UUID formatting rules down below π)LABEL=$LABELor/dev/disk/by-label/$LABELβ references the device by its filesystem/LUKS label.PARTUUID=$UUIDor/dev/disk/by-partuuid/$UUIDβ references the device by its GPT partition UUID.PARTUUID=$UUID/PARTNROFF=$OFFSETβ references a device by$OFFSETfrom a GPT partition specified by$UUID, e.g.PARTUUID=fd59d06d-ffa8-473b-94f0-6584cb2b6665/PARTNROFF=2.PARTLABEL=$LABELor/dev/disk/by-partlabel/$LABELβ references the device by its GPT partition label.HWPATH=$PATHor/dev/disk/by-path/$PATHβ references the device by its deterministic hardware path, e.g.pci-0000:02:00.0-nvme-1-part2.WWID=$IDor/dev/disk/by-id/$IDβ references the device by its wwid, e.g.nvme-KXG6AZNV256G_TOSHIBA_40SA13GZF6B1-part3.
β¨ UUID parameters β¨
Boot parameters like root=UUID=$UUID and rd.luks.uuid=$UUID let you point at a block device by its UUID. The format is literally:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
β¦where every x is a hexadecimal symbol, lowercase or uppercase, no cap. And yes, you can wrap the UUID parameter in the quote symbol " β but please don't, it's not recommended π. Here's what correct parameter formats actually look like:
root=UUID=ac8299a8-91ce-4bf6-a524-55a62844b787,
root=UUID="ac8299a8-91ce-4bf6-a524-55a62844b787" (not recommended),
rd.luks.uuid=ac8299a8-91ce-4bf6-a524-55a62844b787,
rd.luks.uuid="ac8299a8-91ce-4bf6-a524-55a62844b787" (not recommended).
π«Ά Password entry π«Ά
Editing keys beyond the standard ones, bestie β memorize these:
- Ctrl+W β erase the previous word.
- Ctrl+U β erase the entire entry.
- Tab β toggle visibility of the typed characters (asterisks β literal).
π LUKS unlock concurrency and prompt order π
Booster runs its LUKS unlock paths concurrently per volume β multiple enrolled tokens dispatch in parallel where possible, and the keyboard passphrase prompt runs alongside them as a fallback. This subsection sums up the deterministic ordering and the cancel-on-win behaviour that ties the whole thing together.
PIN-token serialization. Tokens that need a PIN (TPM2-PIN, FIDO2-PIN) prompt serially, in ascending LUKS2 token-ID order β booster never races two PIN prompts against the same keyboard. Tokens that don't need a PIN (TPM2 PCR-only, FIDO2 touchless) dispatch in parallel and can win the race without any user interaction. Wanna preview the PIN prompt order for a volume? Run cryptsetup luksDump <device> and read the token IDs. π
FIDO2 credential pre-flight. When a LUKS volume has multiple FIDO2 tokens enrolled (say, a primary key and a backup), booster identifies the matching device before prompting for its PIN. It runs a CTAP2 assertion with up=false against each FIDO2-capable hidraw, asking the authenticator whether it holds this volume's credential β devices that don't are skipped silently and the dispatcher advances to the next FIDO2 token (or the next unlock method) without prompting for the wrong key's PIN. Tokens enrolled with fido2-uv-required=true skip the pre-flight (per CTAP 2.1 Β§7.4) and go straight to the full assertion.
Cancel-on-win. Any prompt β keyboard passphrase, FIDO2-PIN, or TPM2-PIN β gets dismissed automatically the moment a parallel unlock path wins (a touchless token completes, a sibling volume's keyfile reads successfully, etc.). This applies on both the kernel console and the Plymouth splash. On Plymouth the on-screen prompt clears immediately on the server side once Plymouth MR !393 is picked up; older Plymouth builds release the prompt server-side but leave its UI drawn until the splash is otherwise cleared. π
PIN attempt caps. Each PIN-bearing token accepts up to 3 attempts; submit an empty PIN (just press Enter) to skip the token and dispatch the next one.
π Modules selection π
This is the note that summarizes the algorithm computing what modules end up in your generated booster image. The initial module list for booster is defaultModulesList β a set of predefined hard-coded modules defined at generator.go. These are the selected modules that most likely cover most system boot needs: disk, filesystem, keyboard, tpm, ethernet, usb drivers.
If the universal config option is set to false (the default value) then so-called host mode is used. I.e. the image is generated with only the drivers needed for the current host hardware. To do that, booster fetches all currently loaded modules from /sys/module/ and computes the intersection with defaultModulesList.
Then booster looks at the modules config option β a comma-separated list of elements β and iterates over all of them left-to-right. The host mode filtering rule does not apply to this list of manually specified modules.
If an element starts with a minus sign - then it removes the given modules from the image; otherwise the modules are added to the image.
If the element is a module name, that module gets added/removed. Note that by convention a kernel module name can be computed from its filename by replacing all dashes with underscores β e.g. for the module hid-apple.ko.gz the name will be hid_apple.
If the element is a path to the module file relative to /usr/lib/modules/$KERNEL_VERSION, the module gets added/removed. Note that the compression algorithm suffix can be omitted from the module filename.
If the element ends with the slash symbol / then that element is considered a directory relative to /usr/lib/modules/$KERNEL_VERSION. Booster goes over this directory recursively and adds/removes the modules to the image. Minus sign can be used with directories too.
The star symbol * is a shortcut for "all modules" β use it to add all modules or remove all modules from the image.
Next booster moves to the modules_force_load option, which consists of module names to load at boot time. All of these modules are also added to the image.
At the final step booster computes dependency graphs between modules and all required dependencies. For example, if a user manually added ext4 and the kernel build system says the ext module requires mbcache and jbd2, then both mbcache and jbd2 are automatically added to the image. Slay. β¨
π¦ Unified Kernel Image π¦
A Unified Kernel Image β https://uapi-group.org/specifications/specs/unified_kernel_image/ β (UKI) is a PE binary that bundles various boot components (e.g. kernel, initrd, and a UEFI boot stub) as a single executable. This allows for booting directly through the firmware (UEFI) as well as authenticating all of the boot components at once for Secure Boot. Main character energy fr fr.
To generate UKIs in Booster, please install the systemd UKI generator (systemd-ukify) from your distribution's package manager and use /usr/lib/booster/regenerate_uki. It's a convenience script that performs the same type of image regeneration as if you installed booster with your package manager, then passes the result to systemd's UKI generator (ukify) as input. The script only passes a subset of boot components, namely the system's microcode(s), initrd, os-release file, boot splash image and kernel. Kernel command-line entries of the UKI are inherited from /etc/booster.yaml.
Please note that to boot the UKI by default, it may be necessary to configure your system's boot loader configuration file(s) accordingly. π
π DEBUGGING π
If you've got a problem with the booster boot tool you can enable debug mode to get more info about what's going on. Just add the booster.log=debug,console kernel parameter and booster provides additional logs. Easy.
π Use TFTP to download logs for unbootable device π
In case of a boot failure, when the devices are missing, logs can still be retrieved from busybox using the network. First, set up a tftp server (port 69) on another machine/VM. For example on Archlinux, pacman -S atftp; systemctl start atftpd. Then edit /etc/booster.yaml and add network support and busybox (extra_files: busybox). Regenerate the initramfs and reboot. Once inside busybox, get the logs and send them to the tftp server:
$ dmesg >boot.log
$ lsmod >mods.log
$ tftp -pl boot.log <server ip>
$ tftp -pl mods.log <server ip>
The logs will be in /srv/atftp on the server. Iconic. π
π§ Boot timeout π§
If you got booster: Timeout waiting for root filesystem error please add the append_all_modaliases config flag and rebuild the image. With this flag you'll get a list of modules that were requested by the kernel but absent in the booster image. Some of these modules might be required to boot your system β so like, actually look at them π.
β¨ EXAMPLES β¨
okay bestie, example time β this is where it all clicks π
Create an initramfs file specific for the current kernel/host. The output file is booster.img:
$ booster build booster.img
Create an universal image with many modules (such as SATA/TPM/NVME/... drivers) included:
$ booster build --universal booster.img
Create an initramfs for kernel version 5.4.91-1-lts and copy it to /boot/booster-lts.img:
$ booster build --kernel-version 5.4.91-1-lts /boot/booster-lts.img
Here is a systemd-boot configuration stored at /boot/loader/entries/booster.conf. In this example e122d09e-87a9-4b35-83f7-2592ef40cefa is a UUID for the LUKS partition and 08684949-bcbb-47bb-1c17-089aaa59e17e is a UUID for the encrypted filesystem (e.g. ext4). Please refer to your bootloader documentation for more info about its configuration.
title Linux with Booster
linux /vmlinuz-linux
initrd /booster-linux.img
options rd.luks.uuid=e122d09e-87a9-4b35-83f7-2592ef40cefa root=UUID=08684949-bcbb-47bb-1c17-089aaa59e17e rw
For hardware-token unlock with a FIDO2 device, enroll the LUKS slot once with systemd-cryptenroll:
$ systemd-cryptenroll --fido2-device=auto /dev/sda2
Then add a /etc/crypttab entry. Booster takes the mapper name from the first column; the generator auto-bundles fido2plugin.so whenever it sees fido2-device=. token-timeout= sets how long booster waits for the FIDO2 touch before also opening the keyboard passphrase prompt (default 30s; 0 waits forever):
cryptroot UUID=e122d09e-87a9-4b35-83f7-2592ef40cefa none fido2-device=auto,token-timeout=60s,x-initrd.attach
The bootloader entry points root= at the future mapper node:
title Linux with Booster
linux /vmlinuz-linux
initrd /booster-linux.img
options root=/dev/mapper/cryptroot rw
Boot with no root= on the kernel cmdline at all using GPT autodiscovery. Tag the root partition with the per-architecture GUID β on x86-64 that's 4f68bce3-e8cd-4db1-96e7-fbcaf984b709:
$ sgdisk --typecode=2:4f68bce3-e8cd-4db1-96e7-fbcaf984b709 /dev/sda
For a LUKS-encrypted root, add a /etc/crypttab entry naming the mapper (otherwise booster synthesises /dev/mapper/root):
cryptroot UUID=e122d09e-87a9-4b35-83f7-2592ef40cefa none x-initrd.attach
The bootloader entry then carries only the mount-style flags:
title Linux with Booster
linux /vmlinuz-linux
initrd /booster-linux.img
options rw
Users of the Btrfs filesystem with a system installed on a subvolume should add rootflags corresponding to their entry in /etc/fstab. In this example 69bc4dd2-7f6c-4821-aa6b-d80d9c97d470 is a UUID for Btrfs partition, with the system installed on subvolume called root and /etc/fstab looks like this:
UUID=69bc4dd2-7f6c-4821-aa6b-d80d9c97d470 / btrfs rw,relatime,autodefrag,compress=zstd:2,space_cache,subvol=root 0 0
So /boot/loader/entries/booster.conf should look like this:
title Linux with Booster
linux /vmlinuz-linux
initrd /booster-linux.img
options root=UUID=69bc4dd2-7f6c-4821-aa6b-d80d9c97d470 rw rootflags=relatime,autodefrag,compress=zstd:2,space_cache,subvol=root
Booster has no built-in Btrfs subvolume default. If subvol= (or subvolid=) is omitted, the kernel mounts the filesystem's configured default subvolume β set with btrfs subvolume set-default <id> <path> β falling back to the top-level subvolume (ID 5) when no default has been configured. Distro conventions like @ (Arch), root (some Debian-derived installers), or @/.snapshots/N/snapshot (openSUSE) must be set explicitly in your bootloader entry; both subvol=NAME and subvolid=ID are accepted.
Create a Unified Kernel Image and write the result to /boot/EFI/Linux:
$ /usr/lib/booster/regenerate_uki build /boot/EFI/Linux
π COPYRIGHT π
Booster is Copyright (C) 2020 Anatol Pomazau http://github.com/anatol
π SEE ALSO π
Project homepage https://github.com/anatol/booster
later, bestie β that's the whole BOOSTER(1) page, June 2026 edition, and you absolutely ate it π
β¨π«Ά
π¦ where this page comes from
- arch rolling: booster 0.13-1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms