Brainstorm: an EFI stick that autoports coreboot before the OS exists

#coreboot#uefi#efi#firmware#autoport#brainstorm#reverse-engineering

This is a scratchpad. None of it is built yet. I’m writing it down so the idea stops bouncing around at 2am.

The itch

Every time I want to port a new board to coreboot, the ritual is the same:

  1. Install Linux on the target (or boot a live image and pray the right tools are there).
  2. Become root.
  3. Build inteltool, ectool, superiotool from the coreboot tree because the distro packages are always stale.
  4. Run autoport from util/autoport/, which shells out to all of the above plus lspci, dmidecode, acpidump.
  5. Collect a logs/ directory.
  6. Carry it to my dev machine and let autoport scaffold the board.

Steps 1–3 are pure friction. You’re installing an entire operating system whose only job is to be a thin shim that reads PCI config space and a handful of MMIO registers. That’s absurd. The OS is in the way.

What if we skip the OS entirely?

The pitch

A single BOOTX64.EFI on a FAT32 stick. Drop it at EFI/BOOT/BOOTX64.EFI, boot the target off it, it dumps everything autoport wants into logs/ on the same stick, then it reboots. You never install anything. You never touch the target’s disk. You pull the stick, plug it into the dev box, and run autoport against the dumped logs.

The vendor firmware is still the environment when an EFI app runs. That’s the point: we read the hardware while the factory firmware has it configured, which is exactly the state autoport assumes when it reads a running Linux box. We’re just removing the Linux layer that sits between us and the registers.

Working name: corepile.efi. Or autoport.efi. Bikeshed later.

What does autoport actually consume?

Let me pin this down before I get excited, because the whole thing hinges on whether EFI can produce the same inputs. autoport reads a logs/ dir and generates Kconfig, devicetree.cb, gpio.c, early_init.c, hda_verb.c, etc. The inputs it leans on:

So the question becomes: can an EFI application, running pre-OS, get at each of these?

Can EFI even do this? Going down the list

PCI config space: yes, cleanly. EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL gives Pci.Read() over the whole config space, or I just bang CF8/CFC and ECAM directly with port/MMIO I/O. An EFI app runs at ring 0 during boot services, so direct I/O is fair game. This one’s free.

ACPI tables: free. They’re hanging off the EFI System Table as a configuration table under EFI_ACPI_TABLE_GUID (and the old ACPI_10_TABLE_GUID). Walk the RSDP → XSDT → every table. No acpidump needed; the firmware already laid them out for us.

SMBIOS: free. Same trick, SMBIOS_TABLE_GUID / SMBIOS3_TABLE_GUID in the config table. Walk the structures, pull the board/vendor strings.

Super I/O (0x2e/0x2f) and EC (0x62/0x66): port I/O, ring 0, trivial. This is inb/outb in inline asm from the app. The logic is the annoying part, not the access.

MSRs: rdmsr is a privileged instruction and we’re privileged. Inline asm rdmsr from the app works at boot-services time. So CPU feature/config MSRs are reachable.

Intel GPIO / PMBASE / RCBA / SPIBAR: this is where it gets real. inteltool finds these by reading the LPC/eSPI bridge’s PCI config (00:1f.0) to get the base addresses, then memory-maps them. EFI has identity-mapped physical memory during boot services, so once I read GPIOBASE out of PCI config I can just dereference the MMIO. The work is porting inteltool’s per-PCH knowledge tables, not the access mechanism.

So: access is solved on every axis. What I’d actually be writing is a re-implementation of inteltool’s chipset knowledge in a freestanding EFI binary. That’s the real cost, and I shouldn’t pretend otherwise.

Writing the dump back to the stick

EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on the boot device handle. Open the volume, create logs/, write files. FAT32 is natively supported by every UEFI. So I can emit:

logs/
  lspci.txt            # reconstructed in the format autoport's parser expects
  inteltool.log
  ectool.log
  superiotool.log
  acpi/                # raw table blobs
  dmesg.txt            # probably fake/minimal, does autoport need it?

Open question flagged below: autoport parses human tool output, not raw binary. So I either (a) format my dumps to mimic lspci/inteltool text exactly, or (b) patch autoport to accept a native format from the EFI tool. (a) is gross but means zero changes to coreboot’s util. (b) is cleaner but is now a coreboot patch I have to upstream and maintain. Leaning (a) for the proof of concept, (b) if it ever gets real.

The part I keep hand-waving

inteltool is thousands of lines of “if PCH is Sunrise Point do this, if it’s Cannon Point do that.” Reimplementing all of it in EFI is a fool’s errand. So the honest scope for a v0:

If the round-trip works once, end to end, then I generalize. Trying to be universal on day one is how this ends up in the drafts graveyard with the other 30 files.

Why this is better than a live Linux USB, concretely

Why it might be a bad idea

Open questions for next session

  1. At EFI-app launch time, are the GPIO/PMBASE/SPIBAR lock bits already set by vendor firmware, or still open? (go/no-go on the whole premise: test on real hardware first, before writing a line of code)
  2. Does autoport strictly require the textual tool output, or can I feed it a native format with a small patch?
  3. EDK2 or gnu-efi for the build? gnu-efi is lighter and I don’t need DXE driver machinery, leaning gnu-efi.
  4. HDA codec verb dump from EFI: reachable via the HDA controller’s MMIO (corb/rirb), but is it worth it for v0 or do I punt hda_verb.c to manual?
  5. Can I read the EC right, or does the vendor EC firmware get cranky when something pokes 0x62/0x66 outside its expected handshake?

Step zero is question 1. Boot a throwaway EFI app on the one board, read GPIOBASE, dump the pad config, and compare it against what inteltool prints from Linux on the same box. If they match, the idea lives. If the EFI dump is all lock-bit zeros, it dies here and I saved myself a month.

That’s the experiment. Everything else is downstream of it.