coreboot Firmware on Purism Librem devices

 

coreboot is a modern, lightweight, open-source replacement for the proprietary (usually UEFI) system firmware shipped on most PCs/laptops today. It is designed to perform only the minimum number of tasks necessary to initialize the hardware, and pairs with a payload (such as SeaBIOS) to boot a modern operating system (such as PureOS) as quickly as possible. It brings increased performance and security, avoiding widespread security issues (see “What the CIA Vault 7 Documents Mean“, follow-up posts #1, #2, #3, etc.), and provides the foundation for our new PureBoot firmware, which offers a tamper-resistant boot process via Heads and a Librem Key and is now available as a public beta.

Since the summer of 2017, Purism has shipped coreboot firmware (featuring SeaBIOS as the payload) on all Librem laptops. We also offer an easy to use coreboot update/flashing script for all Librem models (including those older models which didn’t ship with coreboot). This script allows you to update the firmware on your Librem, using either a pre-built binary firmware update image or compiling from source.  Pre-built images for our PureBoot firmware are available as well.  The script uses only files available from public Purism repositories, and performs numerous checks to ensure the integrity of the downloaded/compiled firmware update all the way through the flashing process.

Since coreboot initializes the bare metal hardware, it must be tailored specifically to every chipset and motherboard — and so each Librem model has its own unique build. You can track our progress through our contributions to coreboot, our timeline of long-term involvement with the coreboot project, and our freedom roadmap. And remember to keep things in perspective!

NOTE: If you have an older model Librem which shipped with proprietary AMI firmware, and your OS was installed in UEFI mode, you will need to reinstall it after, or migrate it before flashing our coreboot image (see ‘Migrating a UEFI-based install’ below).


Using the coreboot utility/update script

Purism offers an easy to use coreboot update script, which provides users of our “standard” coreboot/SeaBIOS firmware the option between using a pre-built firmware image, or building the update from source. Users wishing to test our beta PureBoot firmware can also do so, using a pre-built firmware image (building PureBoot from source is also possible, but not yet integrated into the main coreboot update script).

A few preliminary notes:

  • The coreboot utility script should be run on the Librem you want to update
    (though you can run on another machine in a pinch to download/build an update if needed)
  • These instructions assume you are running PureOS (or another Debian/Ubuntu distribution)
  • Under PureOS (and possibly other distros), you may need to add ‘iomem=relaxed’ to the grub kernel boot parameters for flashrom to read/write the firmware
  • Before flashing the firmware, make sure you are not running low on battery (or better yet, connect AC power). Do not interrupt the process in any way – do not suspend or shut down the machine, do not close the lid, do not close the terminal. Otherwise, you risk bricking the device

Full documentation for the coreboot utility script can be found in the README at https://source.puri.sm/coreboot/utility, but here’s the TL;DR: simply open a terminal and run the following commands:

mkdir ~/updates 
cd ~/updates 
wget https://source.puri.sm/coreboot/utility/raw/master/coreboot_util.sh -O coreboot_util.sh 
sudo bash ./coreboot_util.sh

The script will check for basic dependencies (which are documented in above README), then present a menu with several options:

1) Update firmware using pre-built image
2) Build firmware update from source
3) Modify default boot order
4) Set device serial number

we’ll cover the first two here, since those are the ones of interest to the majority of users, and the latter two are fairly self-explanatory 🙂

Updating your firmware using a pre-built image

When selecting this option, the script will prompt you to select/confirm your Librem device model:

After selecting/verifying your Librem model, the script will give you the option between the “standard” coreboot/SeaBIOS firmware and the beta PureBoot (coreboot/Heads) firmware.

Note: this option is not currently available for the older Broadwell-based Librem models (13 v1 and 15 v2). The firmware type selection menu will skipped if either of those models is selected.

Following selection of the firmware type to be flashed, the script will prompt to confirm/enter the device serial number.  As with the PureBoot firmware option, this will be skipped for Broadwell-based Librem models. If run from a Librem running coreboot firmware, the default option will be the device’s current serial number:

At this point, the script will download and validate the appropriate firmware image based on selections to this point.  If the standard coreboot/SeaBIOS firmware option was selected, the script will prompt to set the default boot order. If your Librem has multiple internal storage drives, you will need to ensure your boot device has the higher priority between the two.  You may also wish to prioritize external/USB devices when attached (by default, external devices have the lowest priority).

Selecting a device moves it to the top of the list; when you are happy with the ordering, simply press enter to continue. As noted in the script, one can always override the default by pressing ESC on the boot splash and selecting the device to be booted.

Lastly, if running coreboot/SeaBIOS firmware, the script will prompt you to flash the update.  If running PureBoot firmware, the script will prompt you to copy the update to USB and to update via the Heads menu option.

If the option to flash the update is chosen, the script will check for a compatible version of flashrom,  download/compile from source if needed, and then flash the update.  You will be prompted to reboot when it has completed (~2 mins) and should do so.

Building the firmware update from source

Currently this function only supports building our standard coreboot/SeaBIOS firmware. We plan on adding support to build the PureBoot firmware soon.  Until then, instructions to do so can be found in the main PureBoot documentation.

As with using a pre-built image, the option for building the coreboot/SeaBIOS firmware from source starts with device selection/confirmation, followed by serial number confirmation/entry on non-Broadwell models, and setting the default boot order:

Next, the script will clone Purism’s coreboot repository using git, then check for the required firmware blobs (downloading a pre-built coreboot image and extracting from it as needed).  Once that is completed, the script will inform the user that it is ready to build coreboot, and that it may take some time (due to needing to compile coreboot’s toolchain first).

After you hit enter, the build process will kick off, validating/building coreboot’s toolchain, then building coreboot itself for the selected device. Once it has completed, the contents of the firmware will be printed, and the hash of the compiled image will be compared against the expected/known good hash.

If the hash matches the expected value, and if currently running coreboot/SeaBIOS firmware, the script will prompt you to flash the update.  If running the PureBoot firmware, the script will prompt you to copy the update to USB and to update via the Heads menu option.

If the hash does not match, the script will recommend you not flash the image, and you should not do it manually either, as it could brick the machine

If you have any questions, or if you just want to know more about the coreboot utility/update script, you may also want to check out the main forum thread for it.


Confirming the presence of the correct coreboot image

If you want to feel warm and fuzzy by confirming you have coreboot installed properly after you see the cool Purism logo during boot, here is an easy to confirm coreboot booted and was installed properly.

  1. Grab coreboot source (or better yet, simply use the source checked out as part of the update script above)
    git clone --depth=1 https://review.coreboot.org/coreboot.git
  2. Change to the cbmem tool directory
    cd coreboot/util/cbmem
  3.  Build cbmem
    make
  4. Run cbmem to confirm coreboot booted
    sudo ./cbmem -c | egrep -i "coreboot-|purism|librem"
  5.  Verify output looks similar to:
    coreboot-4.8.1-10-gade55f0fa4-4.8.1-Purism-4 Sun Jan 20 19:24:19 UTC 2019 bootblock starting...
    coreboot-4.8.1-10-gade55f0fa4-4.8.1-Purism-4 Sun Jan 20 19:24:19 UTC 2019 romstage starting...
    coreboot-4.8.1-10-gade55f0fa4-4.8.1-Purism-4 Sun Jan 20 19:24:19 UTC 2019 postcar starting...
    coreboot-4.8.1-10-gade55f0fa4-4.8.1-Purism-4 Sun Jan 20 19:24:19 UTC 2019 ramstage starting...
    Root Device (Purism Librem 13 v2)
    Found mainboard Purism Librem 13 v2
    
    

Verifying the Intel ME is neutralized

You can confirm the ME condition by utilizing the same cbmem utility as above:

coreboot/util/cbmem$ sudo ./cbmem -c | grep ^ME

the most important lines are the 7 that match these output:

for Librem 13v1/15v2:

ME: FW Partition Table : OK
ME: Bringup Loader Failure : NO
ME: Firmware Init Complete : NO
ME: Manufacturing Mode : YES
ME: Boot Options Present : NO
ME: Update In Progress : NO
ME: Current Working State : Initializing
...

for Librem 13v2/15v3 and newer:

ME: Host Firmware Status Register 1 : 0xFFFFFFFF
ME: Host Firmware Status Register 2 : 0xFFFFFFFF
ME: Host Firmware Status Register 3 : 0xFFFFFFFF
ME: Host Firmware Status Register 4 : 0xFFFFFFFF
ME: Host Firmware Status Register 5 : 0xFFFFFFFF
ME: Host Firmware Status Register 6 : 0xFFFFFFFF
ME: FW Partition Table      : BAD
ME: Bringup Loader Failure  : YES
ME: Firmware Init Complete  : YES
ME: Manufacturing Mode      : YES
ME: Boot Options Present    : YES
ME: Update In Progress      : YES
ME: D3 Support              : YES
ME: D0i3 Support            : YES
ME: Low Power State Enabled : YES
ME: CPU Replaced            : YES
ME: CPU Replacement Valid   : YES
ME: Current Working State   : Unknown (15)
...

Disclaimer: ME neutralization and disablement is an ongoing and repeated effort requiring tailored work across different models and chipsets (for example, we once found the ME cleaner tool to cause problems with Wi-Fi on Skylake, and had to solve that first).


Migrating a UEFI-based install

If you have an older Librem which shipped with proprietary AMI firmware, and your existing operating system was installed in UEFI mode, you will not be able to boot it after flashing coreboot on your Librem, because the SeaBIOS payload used in conjunction with coreboot provides support for Legacy BIOS boot mode, rather than UEFI. Additionally, UEFI installations typically use a GPT partition layout, and if you were to simply switch to the older MBR layout, everything on the disk would be lost — so don’t do that! Please follow the instructions below instead, which modifies the GPT/UEFI partition layout to one which allows grub to boot from a GPT layout disk in legacy BIOS mode (using a special 1 MB partition at the start of the disk). Here are the steps:

  1. Back up your data. (disclaimer: the steps below have had only limited testing so far, exercise caution)
  2. Using gparted, prepare the new target partition with one of these two approaches:
    • Shrinking your EFI partition 1 MiB smaller, then creating a new partition in the newly freed 1 MiB space, or;
    • Reformating your EFI partition.
  3. Using gparted, apply the “bios_grub” flag to the new target partition.
  4. Remove the old EFI partition from /etc/fstab
  5. Reinstall GRUB with one of these two commands, where X is the physical storage device’s identifier:
    • If your OS is installed on a NVMe M.2 SSD:
      sudo grub-install /dev/nvmeX
      (most likely /dev/nvme0n1)
    • If your OS is installed on a SATA drive (either m.2 or in the 2.5″ slot):
      sudo grub-install /dev/sdX
      (most likely /dev/sda)

You can find more advanced techniques or explanations in the GRUB documentation on Arch Linux’s wiki or AskUbuntu question #360543.