Skip to content

Leave a grub.cfg on BIOS installs so GRUB-payload firmware boots - #203

Open
felixzsh wants to merge 1 commit into
omacom:quattrofrom
felixzsh:fix/grub-payload-bios-boot
Open

felixzsh wants to merge 1 commit into
omacom:quattrofrom
felixzsh:fix/grub-payload-bios-boot

Conversation

@felixzsh

Copy link
Copy Markdown

What

On BIOS installs, also leave a minimal grub.cfg on the ESP so firmware that
boots through a GRUB payload can hand off to the installed system.

Why

Some coreboot-based firmware boots via a GRUB payload that scans disks for a
boot config (grub.cfg / syslinux / extlinux) and does not chainload the MBR.
Omarchy installs Limine, which writes limine.conf; that firmware does not read
it, so the install completes but the machine does not start — the payload drops
into its scanner with .../i386-coreboot/*.mod not found noise.

The MBR already receives Limine (limine bios-install), but the payload never
boots the MBR on its own: it only looks for a config file. Leaving it one is the
missing piece.

How

In finalize_limine_boot, after Limine is finalized, non-UEFI installs now get a
grub/grub.cfg on the ESP next to limine.conf:

set timeout=3
menuentry "Omarchy" {
  linux /<machine-id>/<kernel>/vmlinuz <cmdline>
  initrd /<ucode> /<machine-id>/<kernel>/initramfs
}

The kernel paths are read back from the generated limine.conf
(path: / module_path:, stripping the boot(): prefix and the content hash),
and the cmdline is the same one Limine uses, so cryptdevice / rootflags /
resume stay correct. intel-ucode.img / amd-ucode.img is prepended when
present.

Impact on normal installs

None.

  • UEFI installs: the code does not run.
  • Legacy BIOS installs: the file is written but never read. The firmware boots
    the MBR Limine, and Limine reads limine.conf; the file is inert.
  • It does not touch the MBR, limine.conf, snapshots, or kernel updates.

Testing

  • Added test/unit/test_bios_grub_config.py: path parsing, the generated config,
    and the no-op case when the entry has no kernel/initramfs paths.
  • ./test/all passes (72 unit tests).
  • The generated config was validated by hand on a no-EFI coreboot machine: with
    the file present the GRUB payload boots the installed system; without it, it
    does not.

Notes

Firmware that boots through a GRUB payload scans disks for a config
(grub.cfg / syslinux / extlinux) and never chainloads the MBR. Omarchy
installs Limine, whose limine.conf that firmware does not read, so the
installed system does not start even though the install succeeds.

Write a minimal grub.cfg next to limine.conf on the ESP for non-UEFI
installs, booting the same kernel with the same cmdline. Ordinary BIOS
boots the MBR Limine and never reads the file, so it is harmless there.
@felixzsh
felixzsh force-pushed the fix/grub-payload-bios-boot branch from 70aadc9 to b461010 Compare October 10, 2026 17:26

This branch has not been deployed

No deployments
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.

1 participant