==========
== icon ==
==========
My blog about open-source firmware & communities

BL31 -- coreboot's new BIOS?

coreboot firmware BIOS
Here is an opinion piece that I once wrote for blogs.coreboot.org, but
actually wasn't published there. Back then, we were debating if an odd
combination of a proprietary ARM trusted firmware with a reduced core-
boot ramstage should be supported upstream and if this should be added
to the Arm Base Boot Requirements [1].  We ended up adding the regular
coreboot boot flow, along with this combination to the spec. A similar
topic reminded me of this lately, so I decided to publish it in Decem-
ber 2025, two years late.

[1] https://developer.arm.com/documentation/den0044/latest/

I had an odd brainwave yesterday, when two memories of the past few days suddenly were associated. The first was about a discussion on IRC about LogoFAIL and its impact on Intel BootGuard (a tech that allows OEMs to prevent you from running your own firmware). The other was an answer on Gerrit about when a new “coreboot port” for an ARM emulator runs in the overall boot process:

>> Is this supposed to run after BL1 or after BL2?

> Currently it runs after BL31.

Um, what does that mean? And how do these two topics relate? Let’s have a look at some background first.

Background

Basic Input/Output System (BIOS)

It started with the first IBM PC, I guess, I wasn’t there back then. It had a firmware ROM that contained something called the Basic Input/Output System (BIOS). This BIOS implemented device (I/O) drivers as a service to the operating system (OS). It contained machine specific information that the OS didn’t possess. But there was also another necessity for firmware: RAM was too expensive for device drivers that are practically needed all the time. So putting this part of the OS into a ROM seems like a good idea for 1980’s hardware.

With the decades, the hardware evolved. Operating systems did too, they learned how to control the hardware directly. And at some point there was always enough RAM available for device drivers. Today, there are a few operating systems for x86 that can run bare-metal, without any need to call BIOS services. This allows us to run fully open-source operating systems that do not execute proprietary firmware services!

coreboot’s role in the boot process

Almost two decades after the original BIOS came LinuxBIOS, that later evolved into coreboot. LinuxBIOS was not really a BIOS. Same as coreboot today, it didn’t implement services to call into. The idea is to only implement machine specific parts, to initialize the hardware up to a state where a more generic, though bare-metal, OS can take over.

If you know coreboot, its payload concept and SeaBIOS, it’s roughly like this: coreboot implements the machine specific parts, and SeaBIOS implements the services for legacy operating systems and their bootloaders that can’t run bare-metal.

And BL1/2/31?

ARM provides a firmware framework and reference implementation called Trusted Firmware-A (TF-A). The list of features is quite long. In short, I believe it promises about everything coreboot does, a BIOS would do, and all what Trusted Execution Technology (TXT) would bring. The reference implementation is BSD licensed and I’m told real hardware implementations are often proprietary.

TF-A defines a bunch of boot loader stages:

  • Boot Loader stage 1 (BL1) AP Trusted ROM
  • Boot Loader stage 2 (BL2) Trusted Boot Firmware
  • Boot Loader stage 3-1 (BL31) EL3 Runtime Software
  • and more…

AIUI, EL3 is the highest privilege level on ARM, comparable to Ring -2, the System Management Mode (SMM) on x86.

Here’s a crude attempt to compare these stages to the coreboot world: BL1, as ROM code, is somewhat outside the scope of coreboot. It can be quite simple and only load BL2 from writable memory. But it can also implement something like BootGuard, i.e. checking a cryptographic signature of BL2, and also restrict BL2 to a lower privilege level. At least in the latter case, it would offer services to call into, AIUI.

BL2 seems to roughly match the original idea of coreboot. However, coreboot does a lot more today, like providing SMBIOS and ACPI tables, including ACPI runtime code.

BL31 offers some kind of BIOS services to the OS. Note that this is already called software, not firmware in the TF-A documentation.

coreboot on ARM so far

coreboot was ported to ARM a decade ago. In TF-A terms, it seems to replace BL2. I have never looked deep into the architecture, personally. However, when I looked into coreboot’s hardware initialization for ARM SoCs, it always seemed all to fit well together.

There is an intriguing wrinkle, though: We always load a TF-A BL31 after coreboot. This seems odd, given the original idea to support bare-metal operating systems. However, we always build this BL31 from open source. Right now, I’m seeing this open-source BL31 as some kind of a walking cane for operating systems that never learned to run bare-metal. After all, TF-A calls it runtime software, which should be part of the operating system, right?

Let’s finally get back to LogoFAIL

Three days ago, during an IRC discussion, somebody asked if a LogoFAIL exploit would help to get coreboot onto machines that are locked down with BootGuard. LogoFAIL, however, attacks vulnerabilities in rather late stages of UEFI firmware, roughly between the hardware initialization and the runtime services part. This is almost at the point, where the firmware would ask the user what program to run next anyway. So I answered that this would be only good for a frankencoreboot, some kind of coreboot abomination in a way. At this point, it would only make sense to run a coreboot payload, but it’s too late for coreboot.

Now how does this relate to what was proposed on Gerrit, a coreboot port that runs after BL31? The proposed port is also part of a bigger discussion to get coreboot into a boot specification for ARM servers (LBBR), merely to provide SMBIOS and ACPI tables to a LinuxBoot kernel. And whether such a coreboot after TF-A should still be called coreboot. Given that BL31 is closer to the OS than to firmware, I think this is worse than the frankencoreboot I imagined could run after a LogoFAIL exploit. From my point of view: coreboot after BL31, never. coreboot after BL2, if you have to, but please don’t call it coreboot.

Moreover, assuming the idea of coreboot was to encourage software development that doesn’t rely on BIOS services, this would be a step further back than we ever were. A coreboot that doesn’t discourage a BIOS but actually builds on and calls into a usually proprietary BIOS? Who really wants that?

Using the walking-cane analogy again, a coreboot after BL31 would be an additional walking cane because the first, potentially proprietary one (BL31) isn’t sufficient. Without looking closer into the kernel situation, it seems to me that something is going horribly wrong on that end. Maybe we should first implement open-source kernels, that don’t depend on BIOS services, so we don’t have to openwash firmware with a diluted coreboot.