Skip to content

Claim the removable boot path on the free-space ESP - #158

Open
ryanio wants to merge 1 commit into
omacom:quattrofrom
ryanio:protected-esp-fallback-loader
Open

Claim the removable boot path on the free-space ESP#158
ryanio wants to merge 1 commit into
omacom:quattrofrom
ryanio:protected-esp-fallback-loader

Conversation

@ryanio

@ryanio ryanio commented Sep 6, 2026

Copy link
Copy Markdown

A free-space install alongside Windows 11 on an MSI Cubi NUC (AMI firmware) completed, reported success, and left no way to reach Omarchy. The firmware boot menu and a normal restart both went to Windows.

The partitions were all correct. /dev/nvme0n1p6 was the dedicated Omarchy ESP with Limine under EFI/limine, and /dev/nvme0n1p7 the LUKS root. What was missing was any boot route the firmware would take:

BootCurrent: 0001
BootOrder: 0000,0001
Boot0000* Windows Boot Manager  \EFI\Microsoft\Boot\bootmgfw.efi
Boot0001* UEFI: SanDisk Cruzer Glide

No Limine entry. Copying the loader to EFI/BOOT/BOOTX64.EFI on that same Omarchy ESP and re-creating the entry made the machine boot, so the install itself was fine. It had nothing the firmware would look at.

Why the fallback path was off

Free-space installs turn it off on purpose. de0f013 wrote the rule and the reason:

# Free-space installs may share a Windows ESP. Never claim EFI/BOOT as a
# fallback loader in that mode; use the explicit NVRAM entry instead.
default_text = re.sub(r'^ENABLE_LIMINE_FALLBACK=.*$', 'ENABLE_LIMINE_FALLBACK=no', ...)

Sound at the time. Claiming EFI/BOOT/BOOTX64.EFI on a shared Windows ESP would have displaced the Windows loader.

Eight days later ef3b0e4, "Always create our own ESP", deleted ESP sharing. run_partition_execute now creates a partition in free space, runs wipefs -af over it and mkfs.fat -F32 on it, and mounts the Windows ESP nowhere. The premise was gone; the guard stayed. c50d0bc then lifted it into omarchy_install.boot.enable_fallback as a plain false, and the comment explaining it did not come along.

So the mode most likely to meet crowded or uncooperative NVRAM, and the one where another OS owns the default boot target, is the only mode that declines the path every UEFI implementation tries when nothing in NVRAM matches. Full-disk installs have ENABLE_LIMINE_FALLBACK=yes from omarchy-defaults.conf and are unaffected.

What changed

enable_fallback is now true for free-space installs, matching full-disk, in the configurator and in both orchestrator defaults. limine-install writes EFI/BOOT/BOOTX64.EFI alongside EFI/limine/limine_x64.efi during finalize_limine_boot, and refreshes both on later limine-update runs.

validate_boot checked only that a "Limine" entry existed in efibootmgr and aborted otherwise. It now looks at both routes. Either alone boots the machine, so neither is fatal by itself, and losing both stops the install with a message that says so. The interesting case is firmware that accepts the entry at registration, passes the read-back in _register_limine_efi_entry, and drops it before the install ends. Nothing used to notice. It now warns and points at the firmware boot menu, because some AMI/MSI boards ignore BootOrder and honour only their own priority list.

The Windows ESP is not touched

The fallback lands on the partition run_partition_execute created and formatted minutes earlier, so EFI/BOOT/BOOTX64.EFI there is empty and unclaimed. Nothing mounts, reads or writes the Windows ESP, and no existing EFI entry is deleted or reordered beyond the BootOrder rewrite that was already there. The full-disk path is unchanged.

On BootOrder

On the machine that prompted this, a valid Boot0002* Omarchy with BootOrder: 0002,0000,0001 still booted Windows on a normal restart, while F11 booted Omarchy. MSI Setup's persistent boot list offered Windows Boot Manager and not Omarchy. I did not find a standards-compliant way to override that from the installer, and the alternative would be editing Windows Boot Manager, which this should not do. It is reported instead. limine-entry-tool's own README documents the same class of board and gives the same remedy, adjusting the boot order in firmware setup.

Validation

./test/all on Arch, which is where the harness runs (Arch's python package ships no stdlib test module, so the repo's test namespace package resolves; on Debian or a pyenv build the stdlib one shadows it and discovery fails before any test runs):

tests result
quattro 63 2 errors, 1 skipped
this branch 75 2 errors, 1 skipped

Both errors are test_keyboard.py calling localectl in a container with no systemd as PID 1, present before this change and unrelated to it. All shell tests pass on both.

test/unit/test_protected_boot_fallback.py adds the 12. Nine fail against quattro, including the one that matters:

AssertionError: 'ENABLE_LIMINE_FALLBACK=yes' not found in
'ESP_PATH="/boot"\n\nKERNEL_CMDLINE[default]+="root=UUID=... "\nENABLE_LIMINE_FALLBACK=no\n'

They cover the install intent, the /etc/default/limine line it produces, the configurator JSON, and each combination of the two boot routes in validate_boot, including that an explicit enable_fallback: false is still honoured and that an empty loader file does not count as a route.

Not verified

I have not run this end to end on the MSI machine or in a VM. bin/omarchy-iso-test-windows-disk already builds the right fixture, a GPT disk with a 512MiB ESP holding EFI/Microsoft, a data partition and 64GiB of free space, so whoever verifies this has the disk half ready. It is a standalone helper though, referenced by neither test/integration nor bin/omarchy-iso-test, and the automated scenarios in test/integration.d/ run against a full_disk cidata install. Wiring a free-space scenario in means driving the configurator's interactive path rather than adding a file, and that plus an x86_64 ISO build and KVM is more than I could stand up here. The reasoning above is from the code and from limine-entry-tool's source, where limine-update runs limine-install --no-efi-register, the fallback block writes ${ESP_PATH}/EFI/BOOT/BOOTX64.EFI, and registration is gated separately on SKIP_UEFI and EFI_REGISTER, so turning the fallback on does not disturb the NVRAM entry. Worth a real dual-boot install before it ships.

Related

#127 is the same missing file reached the other way, where efibootmgr --create fails outright and the install dies. #126 proposed catching that and writing the fallback as a rescue; it was closed by its author shortly after opening. This is the silent version of the same gap: registration succeeds, the install reports success, and the entry is gone by the time the machine reboots. Turning the fallback on for the mode that had it off addresses both, and would give #127's traceback a machine that still boots.

A free-space install writes Limine only to EFI/limine and registers a
"Limine" NVRAM entry. Firmware that discards or ignores that entry leaves
the machine with no route to the install: it reboots into Windows, the
install having reported success. An MSI Cubi NUC with AMI firmware hit
this, and copying the loader to EFI/BOOT/BOOTX64.EFI on the Omarchy ESP
was enough to make it boot.

The mode has been suppressing that path on purpose. de0f013 set
ENABLE_LIMINE_FALLBACK=no for free-space installs because "Free-space
installs may share a Windows ESP", where claiming EFI/BOOT would have
displaced the Windows loader. ef3b0e4 then removed ESP sharing: the
configurator now always creates, wipefs'es and mkfs.fat's a dedicated
Omarchy ESP in free space. The guard outlived its reason, and c50d0bc
carried it into omarchy_install.boot.enable_fallback without the comment
that explained it.

Turn the fallback on for free-space installs, matching full-disk. The
removable path is unclaimed on a partition created minutes earlier, so
nothing is overwritten and the Windows ESP is never mounted.

validate_boot now checks both routes instead of only the NVRAM entry.
Either one boots the machine, so neither is fatal alone; losing both
stops the install. Firmware that takes the entry at registration and
drops it before the install ends now says so, and points at the boot
menu, since some AMI/MSI boards ignore BootOrder and honour only their
own priority list.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 6, 2026 00:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Boot-path and installer validation changes are boot-critical and should be confirmed with at least one real protected dual-boot/free-space install scenario before approval.

Pull request overview

This PR addresses protected (free-space) installs that can complete successfully but leave the machine booting straight into Windows due to lacking a firmware-reachable Omarchy boot route. It enables Limine’s removable-media fallback (EFI/BOOT/BOOTX64.EFI) for protected installs (now that protected mode uses its own ESP) and updates boot validation to accept either the NVRAM entry or the fallback path, failing only if both are missing.

Changes:

  • Enable enable_fallback by default for protected installs in both orchestrator defaults and the configurator-generated JSON.
  • Update validate_boot to validate both UEFI boot routes (NVRAM “Limine” entry and EFI/BOOT/BOOTX64.EFI) and only fail when neither is present.
  • Add unit tests covering the default intent, /etc/default/limine output, configurator output, and the route-combination validation behavior.
File summaries
File Description
test/unit/test_protected_boot_fallback.py Adds unit coverage for protected-install fallback intent, defaults emission, configurator output, and boot-route validation logic.
configs/airootfs/usr/share/omarchy-iso/orchestrator/phases_impl.py Enables fallback by default for protected installs and introduces _validate_uefi_boot_routes used by validate_boot.
configs/airootfs/usr/share/omarchy-iso/orchestrator/context.py Updates orchestrator default omarchy_install boot settings to enable fallback in both modes.
configs/airootfs/root/configurator Emits "enable_fallback": true for protected installs and documents why it’s safe (dedicated ESP).
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants