LamBoot: a Linux bootloader that shows its work

· 8 min read #bootloader #linux #rust #secure-boot #uefi

I pushed a new LamBoot build to one of my machines, rebooted it, and checked the trust log it writes to the EFI System Partition on every boot. The log file's timestamp read 09:16. The binary had gone out at 09:32. A log older than the deployment could mean only one thing: LamBoot hadn't run on that reboot at all. I knew it within a minute of logging in, and I knew it from a record, not from guesswork.

That's the idea in one incident. LamBoot is a memory-safe UEFI bootloader for Linux, written in Rust, and the thing that makes it different is right there in the story: It shows its work.

Product page: lamco.ai/products/lamboot/. Source and releases: github.com/lamco-admin/lamboot.

The most trust-demanding software you run says the least

A Linux bootloader runs before the kernel, before init, before any logging you'd recognize. It decides which kernel image executes and with what command line, and every security property your system has downstream depends on it getting that right. Then it vanishes. GRUB, systemd-boot, rEFInd, Limine: None of them can tell you afterward what they verified, how they verified it, or whether the image they loaded is the image you think it is. We extend more trust to the bootloader than to almost anything else on the machine, and we get the least visibility back.

LamBoot is my answer to that. It's a UEFI boot manager that speaks the Boot Loader Specification, treats Unified Kernel Images as first-class menu entries, and runs on x86_64 and aarch64 UEFI firmware. The whole thing is about 21,200 lines of no_std Rust across 62 modules, around 1.05 MB on disk, at v0.16.5 as I write this. Three commitments shape the design: Record every trust decision, survive the bad day, and read your real /boot in code you can audit.

A trust-evidence log, written every boot

Every boot, LamBoot writes \loader\boot-trust.log to the EFI System Partition, fresh each time: One JSON object per line, with a line for every image-authentication decision. Each record names the event, the image path, how the image was verified (the firmware trust database, shim via your enrolled MOK cert, shim's vendor cert, or rejected), the UEFI status, and the SHA-256 of the image. The image LamBoot verified and the image it loaded carry the same hash, checked in code, so the log describes what actually ran rather than what was supposed to.

You read it from Linux after boot:

cat /boot/efi/loader/boot-trust.log | jq .

Here's what two lines of it look like:

{"seq":1,"event":"driver_loaded","path":"\\EFI\\LamBoot\\drivers\\ext4_x64.efi","size":134144,"sha256":"6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b","verified_via":"shim_mok","status":"Success","note":""}
{"seq":2,"event":"boot_attempt","path":"\\EFI\\Linux\\ubuntu-6.11.efi","size":42139648,"sha256":"d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35","verified_via":"firmware_db","status":"Success","note":"uki"}

No mainstream bootloader writes a per-image authentication record like this. And I want to be precise about what it is: It's a record you can read and verify, not a cryptographic seal. It lives on a writable ESP, so it's evidence rather than tamper-proof attestation. The attestation side is separate, and LamBoot covers it by measuring the kernel, the policy file, and the command line into TPM PCRs 4, 5, and 12 when a TPM is present. The full field vocabulary, the four documented Secure Boot configurations, and the exact point where LamBoot's verification ends and the kernel's begins are all on the security page.

The trust-evidence loop Three stages in a loop. Boot: LamBoot verifies every image via the firmware db, shim, or MOK, then loads the kernel with its own PE loader. Evidence: It writes one JSON record per decision to boot-trust.log on the EFI System Partition, naming what was verified, how, and the SHA-256 that ran. Audit: You read the log from Linux after boot, and the next boot writes a fresh log. 1. Boot happens 2. Evidence is written 3. You read it from Linux LamBoot verifies every image it loads via firmware db, shim, or MOK, then loads the kernel with its own PE loader Evidence to the ESP \loader\boot-trust.log one JSON record per decision: What, how it was verified, and the SHA-256 that ran Audit after boot cat boot-trust.log | jq . Check what verified what, match the hash to the image. A stale stamp is a finding. The next boot writes a fresh log.
Every boot, LamBoot writes what it verified and what it ran to the ESP, and you audit it from Linux afterward.

Crash-loop recovery, kept in NVRAM

Showing its work covers the boots that happen. The other half of the design is the boot that keeps not happening. LamBoot keeps a small state machine in NVRAM (Fresh, Booting, BootedOK, CrashLoop), counts boot attempts, and at a threshold selects a fallback entry on its own. It's compatible with systemd-bless-boot, so it cooperates with the wider boot-assessment ecosystem instead of inventing a private one. systemd-boot gets partway there with boot counting; for the rest of the field, recovery is you, a USB stick, and an evening.

One of my machines tells this story better than I can. Its NVRAM crash counter climbed to 19, through repeated EFI-fallback attempts, before a good boot finally landed. Without that counter, the machine's history would read "it was down for a while, and then it wasn't."

Native filesystem reading, in memory-safe Rust

Underneath both of those features sits the unglamorous foundation that makes them possible: LamBoot reads your real /boot, in place, with filesystem code compiled into the loader. It reads ext4, btrfs, FAT, XFS, exFAT, and ZFS natively, including XFS on an LVM logical volume, which is the default RHEL layout. Your kernels stay where your distribution put them, with no copies onto the ESP and no dependence on firmware filesystem drivers.

The rest of the field treats this differently, and the comparison lays it out against GRUB, systemd-boot, rEFInd, and Limine in one table. The short version: systemd-boot reads FAT only and leans on firmware for everything else. Limine dropped ext4 support on purpose in version 9.0. GRUB reads all of these, but inside a large C codebase. rEFInd reads them through separate driver binaries that aren't memory safe. Reading this set natively, from a memory-safe Linux bootloader, is LamBoot alone.

The same instinct runs through the load path. LamBoot verifies and loads the kernel with its own PE loader instead of handing it to firmware LoadImage, which structurally removes a shim 15.8 failure mode that breaks ext4 /boot under Secure Boot.

All of this runs on my own machines: My Proxmox VE hosts, plus Debian, Ubuntu, Arch, and EndeavourOS VMs. Both incidents in this post happened on them, not on a test rig.

When another bootloader is the better pick

Fairness is part of showing your work, so here's mine. If you need legacy BIOS, GRUB is the right pick, because LamBoot is UEFI only, on x86_64 and aarch64. If you want an interactive rescue console at the boot prompt, that's GRUB or Limine; LamBoot's menu selects an entry, and its diagnostics are chainloaded EFI modules rather than a shell. If a FAT-only /boot and strict minimalism are exactly what you want, systemd-boot already does that well. And LamBoot isn't a drop-in GRUB replacement: It speaks BLS entries and UKIs, not grub.cfg, so switching means generating boot entries, not porting your GRUB scripting. A kernel-install plugin and distro hooks keep those entries current after that.

Two more boundaries need stating plainly. Secure Boot today means enrolling LamBoot's signing key once through MOK, and the shim-review submission that removes even that one-time step is on the roadmap. And LamBoot starts where your UEFI firmware hands off and ends where the kernel takes over; it doesn't replace or modify the firmware itself.

If what you actually have is a broken boot to fix rather than a bootloader to choose, the companion lamboot-tools toolkit diagnoses and repairs UEFI boot for any bootloader, LamBoot installed or not.

Install it and read your first log

LamBoot is free, MIT OR Apache-2.0, with packages on apt.lamco.ai, the AUR, and OBS builds for the Fedora and openSUSE families, plus signed tarballs on GitHub. The install guide walks every channel, from a homelab with Secure Boot off to Proxmox zero-touch. Install it on a machine you care about, reboot, and then do something no mainstream UEFI bootloader lets you do: Read exactly what just verified your kernel, how it verified it, and the hash of what ran.