// guide
Features
What Visor does, and how each piece behaves.
Modular builds
Since 1.5.6 Visor is assembled from a registry of named features: every
optional capability is a build-time switch, so you compile exactly the manager
you want — from a tiny text-only booter to everything below. The feature list
lives in features/features.json; each feature has a
blurb, a stub (a no-op compile unit used when the
feature is off, so the build always links), deps (features it
requires), and a config list of boot.conf keys it brings in.
- Profiles — ready-made feature sets:
minimal,standard,hardened,ricer,full(the default profile), andcustom— a profile with no fixed set, meant for an explicitFEATURES=name,name,…list.make list-featuresshows every feature with its on/off state;make list-featuresalso lists the available profiles. - Flags —
make PROFILE=… FEATURES=-blur,+captureadds/removes specific features on top of a profile. Removing something another feature depends on pulls those features out too;make list-featuresshows every feature with its on/off state, andmake check-featuresre-validates the registry and dependency graph. - Installer passthrough —
install.shandvisor installaccept--profileand--features, use the same registry, and filter the generatedboot.confso keys belonging to missing features never reach the ESP. - Manifest — the built binary carries an embedded
VISORFT1build manifest (version, arch, profile, feature registry and image list, font pixel size), andinstall.shwrites a matching feature manifest file on the ESP so — for example — Visor Studio knows exactly what an installed image contains.verify_manifestalso warns if the installed binary doesn't match the build request.
The menu
The graphical menu renders into a full-screen back buffer and presents via
GOP — no flicker, ever. Selection changes slide and cross-fade, pages flip
with an animation, and the whole screen fades in and out around boot. The
selection highlight can be a flat rounded card or a frosted-glass blur.
Entries beyond entries_per_page paginate with chevron indicators.
A text-mode menu (text_menu=1) covers headless setups and firmware
that refuses graphics — Visor falls back to it automatically.
Auto-detection (no boot.conf)
With no config, Visor builds the menu itself. Scan order, across every
readable volume (by default — scan=quick restricts the walk to the
volume Visor booted from plus the ESPs and any XBOOTLDR /boot
partitions, widening back to a full scan if it finds nothing):
- Windows Boot Manager —
\EFI\Microsoft\Boot\bootmgfw.efiand friends. - BLS entries —
\loader\entries\*.conf(systemd-boot style), including sort tries/ostree indexes. - UKIs — every
*.efiin\EFI\Linux. - Raw kernels —
vmlinuz*/bzImage*in\boot,\@\boot, and the volume root, each paired with its initramfs. This scan always runs (a UKI does not hide your plain kernels); it is only skipped when BLS entries already reference the same files. - Distro loaders —
\EFI\<distro>\{shimx64,grubx64}.efi, as a last resort.
Automatic kernel cmdline
A detected raw kernel still needs root= to reach userspace, so Visor
derives an accurate cmdline at boot, with no sidecar file, from the first
available source:
- UKI
.cmdlinesection — a UKI in\EFI\Linuxembeds the distro's complete cmdline (root UUID, btrfsrootflags=subvol=, crypt flags). Visor parses the PE section table and reuses it. /etc/fstab— on any volume the firmware can read (e.g. via an EfiFs driver), the/line supplies the exact root spec and btrfs subvolume flags, honoringro.- GPT root partition type — the Discoverable Partitions root GUID for the build architecture yields
root=PARTUUID=… rw, straight from the partition table via BlockIo — no filesystem access at all.
The boot log records which source was used and the exact line derived.
Live USB hotplug
When the menu is armed, Visor first scans all volumes that are already connected (including USB sticks that were plugged in before the menu appeared). It then watches for volumes that appear later and adds their entries live — the new icon fades and scales in while the existing row slides over. Entries are pinned to the stick's partition GUID and volume handle, so files load from the stick that brought them. Unplugging reverses it: the entries leave and the surviving icons slide back together. Replug never duplicates. Hotplugged and pre-connected volumes derive cmdlines only from sources on the stick itself. Disable with hotplug=0. The setting scan_existing=1 forces scanning of pre-connected volumes even when boot.conf has manual entries.
Btrfs snapshots
Press V to open the snapshot panel for the selected Linux entry and boot any snapshot once. Sources, in order:
\EFI\visor\snapshots.conf, generated on the host bytools/visor-snapshot-sync— carries exact per-snapshot cmdlines/kernels, supports multiple OSes. Visor also reads\EFI\visor\snapshot.conf(singular) as a fallback.- Direct btrfs detection (needs the btrfs EfiFs driver): snapper's
.snapshots/N/snapshot, Timeshift'stimeshift-btrfs/snapshots/<ts>/@, and named subvolumes under.snapshots,snapshots,@snapshots.
The scanner rewrites the entry's rootflags=subvol= to the snapshot
subvolume and shows the newest twelve. Visor never makes a snapshot writable
or performs a rollback — your initramfs must support the distro's read-only
snapshot workflow. snapshots = 0 | manifest | 1 selects the mode.
Animated backgrounds
background= accepts PNG and BMP for static wallpapers, plus GIF and MP4/MOV (MJPEG) for animated looping wallpapers. The decoders are self-contained — GIF89a (LZW, disposal, loops) and MJPEG MP4 (bounded decode, loop budget) — with bounded memory; the accent palette is taken from frame one and the frosted-glass panels reuse their blur while the animation plays so the menu stays fast. Frames advance on a wall-clock schedule that drops time on a slow redraw instead of spiralling, and the animation stops cleanly when its loop budget is spent. For best results use the compact VBG format via visor convert --vbg — it is ~10–20× smaller than MJPEG and decodes cheaper at boot.
Tip — try background=\EFI\visor\backgrounds\witch.vbg from the gallery; it is a tiled-quantized delta stream with motion compensation that stays smooth even on slow firmware GOPs.
Live clock
A firmware-RTC clock rendered as a live overlay outside the selection cache — it ticks without forcing a full redraw. Configure with clock / show_clock (unified colorSpec: 0, 1, a palette role or #RRGGBB), clock_size, clock_format (24h/12h), clock_seconds, clock_position (topright, bottomleft, center … hyphens/spaces equivalent, auto-avoids the centered header), plus clock_date/clock_date_format (long, iso, dmy, mdy) and decoration clock_blur (frosted backing) / clock_shadow. See Configuration → Clock.
Screensaver
Two stages while the graphical menu is idle: after screensaver_delay (default 60 s) the UI cross-fades to the bare background (plus the clock if screensaver_clock=1); after screensaver_blank (default 600 s) the panel blanks to black and the render loop idles. The next key or pointer move cross-fades back and restarts the boot countdown so a stray key never instantly boots. Idle is suspended during the countdown, the command-line editor and the file browser. Animated wallpapers keep playing while dimmed, and are fully idle while blanked.
Enable with screensaver=1 or the shorthand screensaver=60 (on with 60 s delay). Configuration → Screensaver lists all keys.
Boot sound (built-in HDA audio)
Visor bundles a self-contained Intel HD Audio driver that plays a short sound at startup before the OS takes over — no external driver and no dependence on the OS having configured audio. It is built for the common case of a small menu_sound sting or a bundled occasional flash moment; see Architecture → Audio for how it fits the boot flow and Configuration → Sound for the key.
- Headphone priority. When a codec reports jack-presence, a plugged-in headphone pin is chosen over the built-in speakers; speakers are the fallback when nothing is plugged in. Other output pins sharing the same converter are muted for the duration so a sound never plays out of both.
- Plays once. The buffer is padded with silence and played as a prepared stream that drains to the audible end, so a short sting is not cyclically replayed by the DMA engine.
- Simultaneous fade-in. The sound starts at the same instant the menu begins to fade in, rather than playing to completion first, so picture and audio arrive together.
TPM2 measured boot
When a EFI_TCG2_PROTOCOL is present Visor measures the on-disk boot.conf into PCR 5 and the booted kernel command line (including its terminating NUL) into PCR 12 via HashLogExtendEvent, matching systemd's tpm_log_load_options layout so a sealed policy stays portable. The active PCR banks are published as volatile LoaderTpm2ActivePcrBanks and advertised in LoaderFeatures. Configure with tpm / measure and tpm_pcr_config / tpm_pcr_cmdline (0–23). Set tpm=0 to skip entirely.
Boot Loader Interface
Visor speaks the systemd Boot Loader Interface (vendor GUID 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f). When loader_vars=1 (default, alias loader_interface) it publishes LoaderInfo, LoaderFirmwareInfo/Type, LoaderDevicePartUUID, LoaderImageIdentifier, LoaderFeatures, LoaderEntries, LoaderTimeInitUSec/MenuUSec/ExecUSec, LoaderTpm2ActivePcrBanks, and honors LoaderConfigTimeout / LoaderConfigTimeoutOneShot and LoaderEntryDefault / LoaderEntryOneShot (one-shot vars are consumed whether or not they match). One-shot is the one-boot mechanism for OS agents like bootctl and systemd-bless-boot. Disable all of it with loader_vars=0.
Accent colors (Material You)
With accent=1, Visor extracts a seed color from the wallpaper —
Celebi quantization then scoring, the same pipeline as Android's Material You —
and builds a tonal palette used for icons, underline, and text. Variants:
tonal, vibrant, expressive, fidelity, content, neutral, monochrome
(accent_variant=). The whole HCT/CAM16 color pipeline runs in Q16
fixed-point integer math (firmware has no floating point) and tracks the
reference Material You implementation closely — chromatic wallpapers match
hue within half a degree.
Immutable distros & OSTree
BLS configs from OSTree-based systems (Fedora Silverblue/Kinoite, etc.) are grouped into one entry per OS with a version panel: V cycles deployments (current, rollback, pinned), so an atomic system shows one clean icon instead of three near-identical entries.
Non-FAT filesystems
UEFI firmware only reads FAT. To auto-detect kernels living on ext4, btrfs,
xfs, and friends, Visor loads EfiFs drivers
from \EFI\visor\drivers\. The installer (and visor drivers)
detects the /boot filesystem and downloads the matching driver —
pinned to a fixed EfiFs release and SHA-256 verified. Drivers are
deferred: loaded at startup but only started when a file actually needs
them or the fast scan finds nothing, keeping the menu at ~1 second even with
the btrfs driver installed.
File browser
Press B at the menu — or run browse [PATH] in the
recovery shell — to open a full-screen browser over every readable volume.
The boot volume comes first; others are labelled by partition UUID. Entries
show sizes and sort directories-first, case-insensitively, with a merge
sort, so even very large directories don't stall the menu.
- Enter — open a directory, or boot the selected file.
- Backspace/← — parent directory.
- Tab/→ — next volume; PgUp/PgDn and the mouse wheel — page.
- Esc (or B again in the GUI) — close.
Booting from the browser is a one-shot override: a kernel boots with a
sibling initrd* paired automatically, an initrd sets the initrd
override, and a .efi is chainloaded. The load is pinned to the
volume the file was picked from (partition GUID and volume handle),
so an MBR stick without a GUID can't be answered by a same-named file on
the ESP. Rough edges: booting needs a selected entry to attach the override
to, very slow USB media can make large listings take a moment, and
filesystems without a loaded driver (ext4 without the EfiFs driver) don't
appear in the browser.
Windows
Windows entries chainload bootmgfw.efi by device path, so BitLocker
and the BCD store behave exactly as if the firmware had booted Windows
directly. If an entry has no kernel path at all, Visor searches for the
Windows Boot Manager across volumes (honoring the uuid= pin).
Editing & recovery
- e edits the kernel cmdline for one boot (
editor=1). - Esc at the boot menu opens the options / rescue console — same as after a failed boot: list and pick entries, edit kernel options, read
boot.log, reboot, or enter firmware setup. Esc there returns to the menu. recovery_entries=1auto-adds(recovery)variants bootingsystemd.unit=rescue.target nomodeset.- If a boot fails, Visor drops into a recovery console (commands like
log,browse,reboot) instead of hanging — see Debugging.
When a LUKS entry (luks=1) is selected, Visor shows a passphrase prompt. F2 toggles showing what you typed (check your keyboard layout). luks_confirm=1 requires typing the passphrase twice — a mismatch reprompts instead of booting. luks_verbose=1 removes quiet splash from the cmdline so the initramfs retry prompt is visible when a passphrase is rejected.
Immunity to Windows
Two layered defences that take over where OS updates like to break things: Visor repairs the boot entry and fallback path that Windows routinely rewrites, and it catches and fixes corrupted GPT tables before they strand a disk.
- Boot self-heal — at every startup Visor checks the damage an
OS update can leave behind: a Visor Boot
Boot####entry that was removed or pushed downBootOrder, and a\EFI\BOOT\BOOTx64.EFIfallback that Windows feature updates and 24H2 replace with a copy ofbootmgfw.efi. Nothing is written when there is nothing to fix, and removable media are never touched. Tricks:boot_order=first(keep Visor at the head ofBootOrderafter a normal boot-manager boot),boot_order=ensure(only recreate a missing entry),boot_order=off,restore_fallback=1, andselfheal=0to skip the pass. - GPT corruption repair — at menu startup Visor scans whole-disk block devices for GPT damage. A disk with a valid backup header but a damaged primary (corruption, bad CRC, clobbered signature) gets a warning modal: overview, details, confirm (type YES), working, done. The primary GPT is rebuilt from the verified backup only when the plan is confirmed safe — never when the layout is invalid, the backup is itself corrupt, or the disk is read-only.
- The same engine is available from the recovery console:
gptscans for damage,gpt Ndetails one disk, andgpt repair Nrebuilds the primary header from the backup.