How to Enable Secure Boot on Omarchy (Arch Linux) with Limine and sbctl, Including Legacy BIOS/MBR to UEFI/GPT Conversion Without Reinstalling
A tested, step-by-step guide to enabling UEFI Secure Boot on Omarchy (the Arch Linux + Hyprland setup) that uses the Limine bootloader, sbctl custom keys, signed Unified Kernel Images (UKIs) and Limine config enrollment (BLAKE2B checksum), with LUKS full-disk encryption and btrfs + Snapper snapshots kept working.
It also covers a case most Secure Boot guides skip: Omarchy installed in legacy BIOS mode on an MBR (dos) disk. Secure Boot needs UEFI, so the guide first converts the install to UEFI on GPT in place, without reinstalling or losing data.
Builds on the community guide in omacom/omarchy discussion #2296, which assumes you already boot in UEFI mode.
Tested on: Acer Swift 3 SF314-52 (Insyde H2O firmware) · Omarchy · Limine 12.8 · limine-mkinitcpio-hook 1.38 · limine-snapper-sync 1.31 · sbctl · LUKS2 + btrfs · linux-omarchy kernel. The Limine/sbctl parts apply to any Arch Linux system using limine-entry-tool; the firmware menu names are Acer-specific but similar on most laptops.
⚠️ Warning: rewriting a partition table and firmware Secure Boot keys can make a machine unbootable. Back up your data and LUKS header, and keep a bootable Omarchy/Arch USB nearby.
- Is this guide for you? (symptoms)
- Overview
- Step 0: Check your system and back up
- Step 1: Replace PARTUUID with the LUKS UUID
- Step 2: Make sure the Limine UEFI loader is on the ESP
- Step 3: Convert MBR to GPT without data loss
- Step 4: Switch firmware from Legacy to UEFI
- Step 5: Enable Unified Kernel Images (UKI)
- Step 6: Create sbctl keys, enroll Limine config, sign everything
- Step 7: Enter Setup Mode and enroll keys
- Step 8: Enable Secure Boot and verify
- Keeping Secure Boot working after updates
- Troubleshooting and recovery
- FAQ
You're in the right place if you want Secure Boot on Omarchy / Arch Linux with Limine and any of these apply:
bootctl statusprintsNot booted with EFI/sys/firmware/efidoes not existlsblk -o NAME,PTTYPEshowsdos(MBR) instead ofgpt/proc/cmdlinecontainscryptdevice=PARTUUID=xxxxxxxx-02(an MBR-style partition ID)/etc/default/liminecontainsENABLE_UKI=nosbctl statusfails or shows nothing useful because the system isn't booted via UEFI
If you already boot in UEFI mode on GPT, skip to Step 5.
| Phase | What happens | Reboot? |
|---|---|---|
| 0–1 | Back up, remove dependency on MBR PARTUUID | ✅ test boot (still legacy) |
| 2–3 | Verify UEFI loader, convert MBR → GPT in place | ✅ into firmware |
| 4 | Firmware: Legacy → UEFI, register Limine in NVRAM | ✅ |
| 5 | Switch to Unified Kernel Images | ✅ test UKI boot |
| 6 | sbctl keys, Limine config enrollment, signing, fallback hook | – |
| 7 | Firmware: Setup Mode, enroll custom + Microsoft keys | ✅ into firmware |
| 8 | Secure Boot enforced, verify | ✅ done |
ls /sys/firmware/efi # "No such file or directory" → legacy BIOS boot
lsblk -o NAME,SIZE,FSTYPE,PTTYPE,PARTTYPENAME
cat /proc/cmdlineFor an in-place MBR → GPT conversion you need:
- An EFI System Partition (ESP) already mounted at
/bootas vfat. Omarchy creates one even on BIOS installs. - At least 33 free sectors at the end of the disk for the backup GPT header:
DISK=sda
echo "disk sectors: $(cat /sys/block/$DISK/size)"
for p in /sys/block/$DISK/$DISK*; do echo "$(basename $p) ends at $(( $(cat $p/start) + $(cat $p/size) ))"; doneBack up the LUKS header to external storage. A copy stored on the encrypted disk itself won't help if that disk is damaged:
sudo cryptsetup luksHeaderBackup /dev/sda2 --header-backup-file /run/media/$USER/<usb-label>/luks-header.img
sha256sum /run/media/$USER/<usb-label>/luks-header.img
sudo sfdisk -d /dev/sda > sda-mbr-layout.txt # copy this to the USB too, for rollbackConverting a disk from MBR to GPT changes every PARTUUID. If your kernel command line unlocks the disk with cryptdevice=PARTUUID=…, the next boot can't find the root device. The LUKS UUID is stored inside the LUKS header, so the conversion doesn't change it:
sudo blkid -s UUID -o value /dev/sda2 # → <LUKS-UUID>
sudo cp -a /etc/default/limine /etc/default/limine.bak
sudo sed -i 's|cryptdevice=PARTUUID=<OLD-PARTUUID>:root|cryptdevice=UUID=<LUKS-UUID>:root|' /etc/default/limine
sudo limine-updatelimine-snapper-sync rebuilds snapshot entries from limine_history/snapshots.json, so editing only limine.conf gets reverted. Patch both:
H=/boot/$(cat /etc/machine-id)/limine_history
sudo sed -i 's|cryptdevice=PARTUUID=<OLD-PARTUUID>:root|cryptdevice=UUID=<LUKS-UUID>:root|g' "$H/snapshots.json" /boot/limine.conf
sudo limine-snapper-sync
sudo grep -c 'PARTUUID' /boot/limine.conf # expect 0
grep -E 'PARTUUID' /etc/fstab /etc/crypttab # expect nothing; fstab should use UUID=Reboot now, still in legacy mode, and confirm the system boots and unlocks.
sudo ls -l /boot/EFI/BOOT/BOOTX64.EFI /boot/EFI/limine/limine_x64.efi
sudo cmp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT/BOOTX64.EFI && echo OK || sudo limine-installWhen run from a legacy boot, limine-install copies Limine to the UEFI fallback path EFI/BOOT/BOOTX64.EFI, which any UEFI firmware can boot without an NVRAM entry.
sudo pacman -S --needed gptfdisk
sudo sgdisk -p /dev/sda # read-only preview: "converting MBR to GPT format in memory"Check that the preview shows the same start and end sectors for every partition, with the ESP as type EF00 and Linux as 8300. Then write it:
sudo sgdisk -g /dev/sda && sync
sudo sgdisk -v /dev/sda # expect: "No problems found."Warning: The kernel is still using the old partition table. is expected on a mounted disk and harmless.
After this step legacy BIOS boot stops working. Reboot straight into the firmware.
Reboot and press F2 (Acer; other vendors use F2, F10, F12, Del or Esc):
- Security → Set Supervisor Password. On Acer, Secure Boot options are hidden until one is set. Write it down.
- Boot → Boot Mode: UEFI, and Secure Boot: Disabled for now.
- F10 to save and exit.
- If you get "No Bootable Device": F2 → Security → Select an UEFI file as trusted for executing → HDD0 →
EFI→BOOT→BOOTX64.EFI, then save.
Once Omarchy boots, verify UEFI and register Limine as a proper NVRAM boot entry:
ls /sys/firmware/efi && cat /sys/firmware/efi/fw_platform_size # 64
bootctl status | grep -E 'Firmware Arch|Secure Boot|Product'
sudo limine-install # "EFI boot entry 'Limine' ... added successfully."
efibootmgrFirmware can verify a UKI (kernel + initramfs + stub in one PE file) as a single signed binary. Omarchy enables UKIs in /etc/limine-entry-tool.d/, but a legacy BIOS install writes ENABLE_UKI=no and ENABLE_LIMINE_FALLBACK=no into /etc/default/limine, which is loaded last and overrides it.
Config load order used by limine-entry-tool:
/usr/share/limine-entry-tool.d/*.conf → /etc/limine-entry-tool.conf → /etc/limine-entry-tool.d/*.conf → /etc/default/limine (wins)
sudo sed -i -e '/^ENABLE_UKI=no$/d' -e '/^ENABLE_LIMINE_FALLBACK=no$/d' /etc/default/limine
sudo limine-update
ls /boot/EFI/Linux/ # e.g. omarchy_linux-omarchy.efi
sudo grep -E 'protocol:|path:' /boot/limine.conf | head -4 # protocol: efiReboot and confirm you booted the UKI:
bootctl status | grep -E 'Stub:|Measured UKI'sudo pacman -S sbctl
sudo sbctl create-keysEnable Limine config enrollment. This embeds the BLAKE2B hash of limine.conf in the Limine binary, so an edited config (for example init=/bin/sh) won't boot. This option is only honored in /etc/default/limine:
echo 'ENABLE_ENROLL_LIMINE_CONFIG=yes' | sudo tee -a /etc/default/limine
sudo limine-update
sudo sbctl verifyWith sbctl installed and keys created, limine-update automatically:
- signs every UKI through sbctl's mkinitcpio post hook,
- enrolls the
limine.confhash intoEFI/limine/limine_x64.efiand signs it (/etc/boot/hooks/post.d/90-limine-enroll-config).
❗ Don't run
sbctl signonlimine_history/vmlinuz_*snapshot kernels. Limine verifies them against the hashes in the enrolledlimine.conf. Signing changes the file, breaks the hash, and stops that snapshot from booting.
EFI/BOOT/BOOTX64.EFI is a plain copy of stock Limine. That causes one of two problems:
- Unsigned: firmware that boots the fallback path fails under Secure Boot.
- Signed but unenrolled: anyone can edit
limine.confand get around Secure Boot.
Many firmwares (Acer/Insyde included) reorder BootOrder and put the HDD0 fallback entry first after key changes. The robust fix is a post-hook that keeps the fallback identical to the signed and enrolled binary:
sudo tee /etc/boot/hooks/post.d/92-limine-signed-fallback >/dev/null <<'EOF'
#!/usr/bin/env bash
### Post-hook: Keep the UEFI fallback loader (EFI/BOOT/BOOTX64.EFI) identical to the
### config-enrolled and Secure Boot signed Limine binary (EFI/limine/limine_x64.efi).
### Runs after 90-limine-enroll-config, which enrolls the limine.conf hash and signs it.
esp_path=""
for p in /efi /boot /boot/efi /limine; do
mountpoint -q "$p" 2>/dev/null && {
esp_path="$p"
break
}
done
[[ -n $esp_path ]] || exit 1
src="$esp_path/EFI/limine/limine_x64.efi"
dst="$esp_path/EFI/BOOT/BOOTX64.EFI"
[[ -f $src && -d ${dst%/*} ]] || exit 0
cmp -s "$src" "$dst" && exit 0
if ! cp -f "$src" "$dst"; then
echo "ERROR: Failed to copy '$src' to '$dst'" >&2
exit 2
fi
sync -f "$dst"
echo "Synced signed Limine to fallback: $dst"
exit 0
EOF
sudo chmod 755 /etc/boot/hooks/post.d/92-limine-signed-fallback
sudo limine-update
sudo sbctl verifyExpected: BOOTX64.EFI, limine_x64.efi and all EFI/Linux/*.efi are signed ✓. The only unsigned files should be the limine_history snapshot kernels, which is fine.
systemctl reboot --firmware-setupIn the Acer firmware:
- Boot → Secure Boot: Enabled. The key management options only appear once it's on.
- Security → Erase all Secure Boot Settings → confirm. This clears PK/KEK/db and enters Setup Mode.
- F10 to save. The system still boots, because Setup Mode doesn't enforce signatures.
Back in Omarchy:
sudo sbctl status # Setup Mode: ✗ Enabled · Vendor Keys: none
sudo efibootmgr # note if the firmware reordered BootOrder (fine with the Step 6 hook)
sudo sbctl enroll-keys -m # -m also enrolls Microsoft keys, needed by firmware option ROMs (GPU, NVMe, etc.)
sudo sbctl status # Setup Mode: ✓ Disabled · Vendor Keys: microsoft
sudo sbctl list-enrolled-keysIf
enroll-keysfails with an "immutable" error, runsudo chattr -i /sys/firmware/efi/efivars/{PK,KEK,db}-*and retry. On MSI boards, turn off "Provision Factory Default keys" first, or the firmware re-adds its keys.
Reboot. If you enabled Secure Boot in Step 7, it's enforced now.
bootctl status | grep 'Secure Boot' # Secure Boot: enabled (user)
sudo sbctl status # Secure Boot: ✓ Enabled
cat /sys/kernel/security/lockdown # [none] integrity confidentiality
journalctl -k -b | grep -i 'secure boot' # kernel: Secure boot enabled🎉 The whole chain is now verified: firmware → signed Limine (enrolled config) → signed UKI → LUKS unlock.
- Kernel and Limine package updates: the pacman hooks rebuild and sign UKIs and re-enroll and re-sign Limine, and the fallback hook copies the result to
BOOTX64.EFI. Nothing to do manually. - Hand-editing
/boot/limine.conf: runsudo limine-enroll-configafterwards, or Limine refuses to boot. Prefer editing/etc/default/limineand runningsudo limine-update. - Check any time:
sudo sbctl verify - Keys are in
/var/lib/sbctl/keys. Back them up only to encrypted storage, because anyone holding them can sign code your machine will trust.
| Problem | Fix |
|---|---|
| System won't boot after enabling Secure Boot | Firmware → Boot → Secure Boot: Disabled (needs supervisor password). Boot, run sudo sbctl verify, sign what's missing, re-enable. |
| "No Bootable Device" after switching to UEFI | Firmware → Security → Select an UEFI file as trusted for executing → EFI/BOOT/BOOTX64.EFI |
| Limine stops with a config checksum/hash error | limine.conf changed without re-enrolling. Disable Secure Boot, boot, sudo limine-enroll-config. |
| Boots via fallback instead of "Limine" entry | Normal on Acer/Insyde after key changes. The Step 6 hook keeps the fallback signed. Optional: sudo efibootmgr -o <Limine>,<others> |
| Snapshot entries fail to unlock after GPT conversion | They still use PARTUUID; see the snapshot gotcha. Boot the main entry and patch snapshots.json. |
| Want the factory keys back | Firmware → Restore Secure Boot to Factory Default |
| Partition table conversion went wrong | Boot installer USB → sfdisk /dev/sda < sda-mbr-layout.txt → unlock, mount, arch-chroot → limine bios-install /dev/sda |
| LUKS header damaged | cryptsetup luksHeaderRestore /dev/sda2 --header-backup-file luks-header.img from the installer USB |
Running these steps from a script/AI agent: sudo: a terminal is required to read the password |
Use a SUDO_ASKPASS helper, e.g. one that pipes GETPIN into pinentry-gnome3, and call sudo -A |
Can I enable Secure Boot on Omarchy without reinstalling?
Yes. Even if Omarchy was installed in legacy BIOS mode on an MBR disk, you can convert in place: switch the cmdline to the LUKS UUID, run sgdisk -g, set firmware to UEFI, then follow the sbctl steps.
Does converting MBR to GPT with sgdisk -g erase data?
No, as long as there are at least 33 free sectors at the end of the disk. It rewrites only the partition table, and the partitions keep the same start and end sectors. Always preview with sgdisk -p and back up first.
Why use UKIs instead of vmlinuz + initramfs? Firmware verifies a UKI as one signed image, and systemd-stub measures it into the TPM. Limine can still hash-check plain kernels through an enrolled config, but a signed UKI is simpler and stronger.
What does ENABLE_ENROLL_LIMINE_CONFIG do?
It embeds the BLAKE2B checksum of limine.conf into the Limine EFI binary before signing it. Without it, anyone with physical access could edit limine.conf (for example to add init=/bin/sh) and a signed Limine would boot it anyway.
Do I need sbctl enroll-keys -m (Microsoft keys)?
It's strongly recommended on laptops and desktops. Option ROMs (GPU, NVMe, network) and firmware drivers are signed by Microsoft; leaving those keys out can leave you with a black screen or a missing boot device. It also keeps Windows dual boot working.
Does this work with dual boot Windows?
Yes. Keep -m, and Limine can list Windows with FIND_BOOTLOADERS=yes / sudo limine-scan. BitLocker may ask for its recovery key once after the key changes.
Will anti-cheat that requires Secure Boot accept this? Some anti-cheats (e.g. FACEIT) check for a Microsoft-signed boot chain and may reject self-signed bootloaders, even with Secure Boot enabled.
Does this apply to plain Arch Linux, CachyOS or EndeavourOS with Limine?
Yes. Anything using limine-mkinitcpio-hook / limine-entry-tool and sbctl works the same; only the Omarchy-specific drop-in file names differ.
Keywords: Omarchy secure boot, Arch Linux secure boot Limine, sbctl Limine, Limine enroll-config, limine-entry-tool secure boot, convert MBR to GPT without data loss, legacy BIOS to UEFI Arch Linux, Unified Kernel Image secure boot, LUKS btrfs snapper secure boot, Acer Swift 3 secure boot Linux, Insyde BIOS secure boot custom keys, Not booted with EFI.
If this helped you, ⭐ the gist or leave a comment with your hardware so others know it works there too.