Taking Command of the First Second: Bootloader Craftsmanship for Hand-Built Linux
Photo: Andrew Dunn, CC BY-SA 2.0, via Wikimedia Commons
There is a moment in every LFS build when the chroot is complete, the kernel is compiled, and the only thing standing between you and a running system is the bootloader. Many builders treat this as a chore — paste in a grub-install command, accept the default config, and reboot with fingers crossed. That approach works. But it also abandons one of the most instructive stages of the entire project: the layer where your system meets its hardware, before a single init script has run.
Why the Bootloader Deserves the Same Attention as the Kernel
The philosophy behind Linux From Scratch holds that understanding trumps convenience. If you spent two weeks compiling Glibc and agonizing over kernel options, outsourcing the boot chain to a distribution's defaults is a strange place to stop asking questions. The bootloader determines which kernel images are trusted, how early microcode and initramfs are loaded, and whether an encrypted root partition can be unlocked at all.
It is also a layer with real operational consequences. A misconfigured boot setup is the most common reason a freshly built LFS system appears "bricked" on first reboot — and the most common reason builders learn to love their live USB rescue stick.
GRUB: The Boring Choice That Still Earns Its Keep
GNU GRUB remains the pragmatic default, and building it from source within your LFS chroot is straightforward: compile for x86_64-efi (or i386-pc for legacy BIOS targets), install to the EFI System Partition, and generate a minimal grub.cfg by hand rather than relying on grub-mkconfig.
Writing the config yourself is the point. A hand-written stanza makes explicit what most users never see — the search --set=root by filesystem UUID, the explicit linux and initrd lines, the kernel command line. When something breaks, you can read your entire boot chain on a single screen.
GRUB's practical advantages are hard to argue with:
- Mature LUKS2 support, including encrypted
/bootwith a detached header workflow - A rescue shell that has saved countless builders from an unbootable first attempt
- Multiboot flexibility if the machine also hosts a Windows partition or a second experimental LFS build
The tradeoffs are code size and attack surface. GRUB is a small operating system in its own right, and its configuration language is idiosyncratic enough that many builders maintain it grudgingly.
Limine: A Leaner Philosophy
Limine has gained a following among LFS and hobby-OS builders for good reason. It is compact, its configuration format is readable in a way GRUB's never was, and it supports modern protocols — including booting via the EFI and Limine boot protocols and the newer Boot Protocol specification used by many from-scratch kernels.
For a single-kernel LFS system, a Limine config file might be twenty lines. There is no script-generated config to audit, no module system, no embedded shell. Boot times on NVMe hardware are noticeably snappy, and the smaller codebase means fewer surprises when you update your toolchain.
The caveats: Limine's LUKS support is more limited than GRUB's, so an encrypted-root setup may require an initramfs that handles unlocking, and its ecosystem documentation assumes more prior knowledge. If your recovery plan involves a rescue shell at the boot menu, GRUB still wins.
EFI Stub: The Minimalist's Endgame
The third option is to skip a bootloader almost entirely. Since kernel 3.3, the Linux kernel image has been a valid EFI executable. With objcopy (or, on newer kernels, simply the compiled image), you can place vmlinuz directly in the ESP and boot it two ways:
- Kernel EFI stub with a boot entry via
efibootmgr, passing the command line and initramfs path as boot parameters - systemd-boot or a bare EFI boot entry that points at the stub
This is the fastest path from power button to kernel, with nothing between firmware and vmlinuz except UEFI itself. It is also the cleanest setup for a system where the kernel command line lives in firmware NVRAM and the root filesystem is unlocked by an initramfs you built yourself.
The fragility is real, though. Firmware updates have been known to wipe boot entries, and debugging a silent EFI failure is less pleasant than dropping into a GRUB shell. Keep a fallback boot entry pointing at a rescue kernel.
Choosing by What You Actually Need
A decision framework, briefly:
- Encrypted root with encrypted
/boot: GRUB, today, remains the least painful option. - Minimal boot time and minimal code: EFI stub, with Limine a close second.
- A machine you experiment on constantly: GRUB's rescue shell and menu editing are worth their weight.
- Learning value: Build all three. A spare partition and an afternoon will teach you more about the UEFI boot process than any amount of reading.
Recovering When the First Second Goes Wrong
Whichever path you choose, your recovery plan should be part of the design, not an afterthought. Maintain a live USB with chroot tooling, keep a copy of your boot partition's contents on another machine, and document your kernel command line somewhere other than the machine itself. US-based builders attending regional meetups — from SCALE in Los Angeles to the various LUG gatherings across the Midwest — will find that nearly every veteran LFS builder has a story about a boot entry lost to a firmware update.
The bootloader is the first code your machine executes that you control. Treating it as your own — written, understood, and owned — completes the promise the rest of the build has already kept.