Deep Dive: GRUB vs EFISTUB Bootloaders

The bootloader is the first thing that runs when you power on your machine. Get it wrong, and you’re reaching for a live USB. Get it right, and you have a recovery console that can save you from almost any disaster.

This post documents my two-week experiment with EFISTUB (no bootloader), and why I ultimately returned to GRUB.

What is EFISTUB?

Modern Linux kernels can be EFI executables. Your motherboard’s UEFI firmware can boot them directly—no GRUB, no bootloader at all. The kernel itself is the boot target.

Pros:

  • Blazing fast boot (no menu, no timeout)
  • Zero dependencies (no bootloader package to maintain)
  • Simpler attack surface
  • Secure Boot friendly (if you sign the kernel)

Cons:

  • Kernel arguments are stored in NVRAM (risky to modify frequently)
  • No boot menu (can’t select between kernels)
  • No snapshot recovery menu

The EFISTUB Experiment

I ran EFISTUB for about two weeks. Setup was simple:

# Create EFI boot entry directly to kernel
efibootmgr --create \
  --disk /dev/nvme0n1 \
  --part 1 \
  --label "Gentoo" \
  --loader '\vmlinuz-6.12.47-gentoo' \
  --unicode 'root=/dev/nvme0n1p3 rootflags=subvol=/@ ro quiet splash' \
  --verbose

It worked beautifully. Boot time dropped. The system felt snappier knowing there was one less layer between power button and desktop.

Updating the Kernel

The challenge with EFISTUB: kernel updates require updating the EFI entry.

# After kernel compilation
cp /usr/src/linux/arch/x86/boot/bzImage /boot/efi/vmlinuz-6.12.48-gentoo

# Update EFI entry
efibootmgr --create \
  --disk /dev/nvme0n1 \
  --part 1 \
  --label "Gentoo-New" \
  --loader '\vmlinuz-6.12.48-gentoo' \
  --unicode 'root=/dev/nvme0n1p3 rootflags=subvol=/@ ro quiet'

# Delete old entry
efibootmgr -b 0003 -B  # where 0003 is the old entry number

Manageable, but tedious. And if the new kernel panics? No fallback without a live USB.

The Reversion to GRUB

Week two, I broke something. I don’t remember what—maybe a kernel config issue, maybe a driver mismatch. The system panicked on boot.

With EFISTUB, my recovery options were:

  1. Boot a live USB
  2. Mount the Btrfs partition
  3. Either fix the problem from chroot, or manually change the EFI entry to point at a snapshot subvolume
  4. Hope I got the rootflags right

This process took 20 minutes and violated my “2-minute recovery” rule.

The realization: GRUB isn’t just a bootloader. With grub-btrfs, it’s a recovery console.

GRUB + grub-btrfs: The Recovery Console

Installation

# Install GRUB with EFI support
emerge sys-boot/grub sys-boot/grub-btrfs

# Install to EFI partition
grub-install --efi-directory=/boot/efi --bootloader-id=Gentoo

# Generate configuration
grub-mkconfig -o /boot/grub/grub.cfg

What grub-btrfs Does

grub-btrfs scans your /.snapshots directory and generates boot entries for each snapshot. Your GRUB menu becomes:

Gentoo Linux
Advanced options for Gentoo Linux --->
    Gentoo Linux, with Linux 6.12.47
    Gentoo Linux (snapshot 47) - Before emerge Firefox
    Gentoo Linux (snapshot 48) - After emerge Firefox  
    Gentoo Linux (snapshot 49) - Timeline 2025-11-30 11:00
    Gentoo Linux (snapshot 50) - Before system update

If my system panics, I:

  1. Reboot
  2. Select a snapshot from the menu
  3. System boots into known-good state
  4. Investigate what broke

Total time: under 2 minutes. No live USB needed.

GRUB Configuration

File: /etc/default/grub

# Timeout before auto-boot
GRUB_TIMEOUT=5

# Default boot entry (0 = first entry)
GRUB_DEFAULT=0

# Show GRUB menu (not hidden)
GRUB_TIMEOUT_STYLE=menu

# Kernel command line (quiet boot with splash)
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

# Enable os-prober for dual-boot systems
GRUB_DISABLE_OS_PROBER=false

# Limit snapshot menu entries
GRUB_BTRFS_LIMIT="10"

After editing, regenerate:

grub-mkconfig -o /boot/grub/grub.cfg

Automating GRUB Updates

Kernel Post-Install Hook

Every kernel update should regenerate the GRUB config. Create a hook:

File: /etc/kernel/postinst.d/zz-grub

#!/bin/bash
# Regenerate GRUB config after kernel installation
grub-mkconfig -o /boot/grub/grub.cfg
chmod +x /etc/kernel/postinst.d/zz-grub

Snapshot Change Hook

Optionally, regenerate GRUB when snapshots are created (so new snapshots appear in the menu immediately):

# Add to cron.hourly
cat > /etc/cron.hourly/grub-btrfs-update << 'EOF'
#!/bin/bash
/usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg 2>/dev/null
EOF
chmod +x /etc/cron.hourly/grub-btrfs-update

Recovery Procedures

Scenario 1: System Won’t Boot After Update

  1. At GRUB menu, select Advanced options
  2. Choose a snapshot from before the update
  3. System boots into snapshot (read-only)
  4. If it works, make the rollback permanent:
    snapper rollback
    reboot

Scenario 2: Kernel Panic

  1. At GRUB menu, select a previous kernel version
  2. Remove or fix the problematic kernel
  3. Rebuild with corrected configuration

Scenario 3: Black Screen (GPU Driver Issue)

  1. At GRUB menu, press e to edit boot entry
  2. Add nomodeset to the kernel command line
  3. Press Ctrl+X to boot
  4. Fix GPU drivers from a working (text mode) system

Scenario 4: Can’t Get to GRUB Menu

If the system hangs before GRUB:

  1. Boot from live USB
  2. Mount EFI partition: mount /dev/nvme0n1p1 /mnt
  3. Check if GRUB files exist: ls /mnt/EFI/Gentoo/
  4. Chroot and reinstall GRUB if needed

EFISTUB: When It Makes Sense

EFISTUB isn’t wrong—it’s just a different trade-off:

Use EFISTUB when:

  • You have a separate, stable recovery partition
  • You’re not using Btrfs snapshots for rollback
  • You want minimal boot time and attack surface
  • You’re comfortable with live USB recovery

Use GRUB when:

  • You’re using Btrfs snapshots and want boot-time rollback
  • You dual-boot or need kernel selection
  • You value recovery speed over boot speed
  • You want “just works” kernel updates

The Verdict

I went back to GRUB. The 1-2 second boot time penalty is worth the recovery capability. When something breaks at 2 AM, I don’t want to hunt for a USB drive.

GRUB + grub-btrfs turns every snapshot into a bootable recovery point. That’s not overhead—that’s insurance.


Both approaches are valid. Know what you’re trading off, and choose accordingly.