<<

Building for Protectli platforms

Step-by-step guide

3MDEB CONTACT ul. Burgaska 9D/10 Piotr Król, 3mdeb CEO 80-287 Gdańsk, Poland +48 880 673 344 TAX ID: PL2530164147 [email protected] Website About Us Introduction

This document describes how to build a coreboot image for Protectli platforms using the upstream coreboot repository. Although coreboot is an open-source firmware framework, building firmware for architecture is currently impossible without certain blobs. These blobs consists of:

CPU microcode (automatically included during build process) Support Package - silicon initialization code in binary form require to initialize modern Intel CPU. May be automatically included in coreboot image or an explicitly selected blob file. VGA option ROM - a binary required for BIOS graphics output to display logo or boot menu Preparing environment

In order to build coreboot image a is preferred. Additionally a docker container will be used in the build process to ensure all the libraries and utilities have correct versions, the appropriate toolchain is present and the build will proceed without errors.

. Install Docker for the Linux distribution you are using. You may refer to https://docs.docker.com/engine/install/ for installation process.

The build process is also possible on Windows 10 machine. However it requires Pro version to have correct Docker support and it has not been thoroughly validated. If you are experienced enough, you may try Windows.

. Install git:

sudo apt-get install git # or sudo yum install git # or sudo dnf install git

. Clone the coreboot repository with its submodules:

git clone --recurse-submodules https://review.coreboot.org/coreboot.git

. Enter the container and mount the directory with coreboot inside the container:

docker run --rm -it -v $PWD/coreboot:/home/coreboot/coreboot \ -w /home/coreboot/coreboot coreboot/coreboot-sdk:1.52 /bin/bash

-v $PWD/coreboot:/home/coreboot/coreboot mounts the coreboot directory as /home/coreboot/coreboot inside container. -w /home/coreboot/coreboot automatically changes the working directory to the mounted coreboot source. coreboot/coreboot-sdk:1.52 indicates the name of the container to use. If it is not locally present it will be pulled from dockerhub (it may take a while). /bin/bash tells to enter terminal inside the container.

The terminal should switch to something similar like coreboot@0a222d9455c8:~/coreboot$. Now the environment is ready Configuring the coreboot

If you have set up the environment correctly it is time to select the platform and desired configuration. To do that, follow steps below.

Open configuration menu to select platform and options inside container (in my example it is FW4B): coreboot@0a222d9455c8:~/coreboot$ make menuconfig

A coreboot configuration menu should display: Go to Mainboard submenu, choose vendor Protectli select the platform you need:

Do not touch other settings, otherwise the built image will not be appropriate for flashing on the platform.

You may navigate through the menu using key arrows on the keyboard. To enter a submenu press ENTER. To select/deselect an option press SPACE. You may go back to previous menu with ESC. To display a help for given option press "?" (Shift + /). Now let's have a quick look at submenu (entered from the main menu). For FW2B and FW4B platform there is nothing particular to do. I will just briefly explain few options. Perform MP Initalization by FSP - this option tells coreboot to leave CPU cores initialization to Intel FSP. Typically we leave this option disabled, because we want to have MP initialization under open-source control. Enable SOC debug interface - this option may enable debugging the CPU via Intel DCI or DBC. It is a debugging method over USB 3.0. It requires Intel System Studio to utilize the debug interface. Additionally this option poses a security threat so it should be used by developers for debugging problems with silicon. Leave disabled. Enable VMX for virtualization - enables the virtualization extensions (Intel VT-x). Typically we leave this option as enabled Include CPU microcode in CBFS - this option is very important. By default it tells the coreboot build system to include the microcode update binary from Intel microcode repository submodule. Without microcode update the platform will not boot. If you wish you may include own microcode binary, but be sure that the binary matches the processor on the platform. For the safety better leave this option as is, i.e. Generate from tree. Validate Intel descriptor - this option enables Intel flash descriptor validation. Use with cause as it may make you platform unbootable. Add Intel descriptor.bin file - this option allows to integrate the Intel flash descriptor into the final image. Not needed to deploy coreboot on a platform. Requires extraction of original descriptor from the original platform firmware image. This option also opens a way to include Intel ME firmware to final image. As this is for more advanced users we leave these options as disabled. Protect flash regions - this option allows to select the flash protection, for example to lock the Intel ME region in the image

When FW6 is selected as a platform few additional options may appear:

Enable Hyperthreading - enables Hyperthreading technology (1 core may have 2 threads) Board can contain Skylake/Kaby Lake - this option tells coreboot build system to include more microcode updates in case platform (or its variants have different CPU series). Leave the default choice. Enable Guard Extensions (SGX) if available - as name indicates, it enables Intel SGX secure enclaves Next submenu is Device. Here we can configure the graphics.

For FW2B/FW4B in order to have BIOS graphics output to select the boot device one must include an VGA option ROM.

In order to do this select: Add a VGA BIOS image and provide the path to the VGA option ROM. The path is relative to coreboot root directory. The blob can be downloaded from 3mdeb cloud:

FW2B/FW4B VGA option ROM FW6 VGA option ROM

In case of the FW2B and FW4B the VGA PCI device ID should be set to 8086,22b0 so it matches the graphics device identification on the platform. For FW6A it must be 8086,5906 and for FW6B/FW6C 8086,5916. Be sure to use the correct option ROM for the platform and the correct device identification.

Additionally there is certain trick for FW2B/FW4B that has to be made to avoid build failure. coreboot expects another VGA option ROM for different stepping of the graphics device. So copy the downloaded vgabios.bin with: cp vgabios.bin vgabios_c0.bin. When VGA BIOS image addition is enabled the field Graphics initialzation will change to None. Since the payload will use the option ROM to initialize graphics, coreboot doesn't need to do it.

An alternative option to initialize graphics on FW6 platform is an open-source graphics initialization library called libgfxinit. It can be selected in Graphics initialzation option as Use libgfxinit. The VGA option ROM will no longer be required in such case (although libgfxinit has some limitations). With libgfxinit one should set the desired mode. So got Display submenu and change the Framebuffer mode:

Legacy VGA will simply give basic text output on the screen from BIOS. Displaying images like logo will be impossible. Linear "high-resolution" framebuffer will enable the graphical mode to display images in BIOS.

When Linear framebuffer is enabled one may select the maximum resolution for the graphical display. More about it a little bit later. Another important submenu is the Generic drivers. Enter this submenu from the main menu.

The example view of Generic drivers submenu when FW2B/FW4B is selected: Typically there is nothing to do here, but pay attention to the following options:

Add Intel FSP binary to flash image - this must be always selected to include FSP blob that initializes the CPU. Otherwise the platform will not boot. Intel FSP binary location in CBFS - this is the location where FSP will be placed in coreboot image. Leave the default value, otherwise FSP will not be executed correctly and the platform will not boot. Use FSP binary from 3rdparty/fsp repo - this option tells coreboot to automatically include FSP binary for the right CPU during build process. Unless you want to use different FSP binary which is appropriate for your platform, leave it enabled. The right FSP binary will be take from official Intel FSP repository mirror. Enable protection on MRC setting - this option will protect the memory training results from overwriting during firmware updates. It may be useful, because these settings allow the platform to boot much faster and avoid retraining (which is time-consuming).

The example view of Generic drivers submenu when FW6 is selected: Typically there is nothing to do here, but pay attention to the following options:

Use binaries of the Intel FSP repository on GitHub - this option tells coreboot to automatically include FSP binary for the right CPU during build process. Unless you want to use different FSP binary which is appropriate for your platform, leave it enabled. The right FSP binary will be take from official Intel FSP repository mirror. If the option is deselected another options to include different FSP binary will appear, but it is out of scope. Enable protection on MRC setting - this option will protect the memory training results from overwriting during firmware updates. It may be useful, because these settings allow the platform to boot much faster and avoid retraining (which is time-consuming). Another important submenu is Console it controls the debugging output from coreboot. Enter this submenu from main menu.

The only one important option worth attention is Default console log level. It controls the verbosity of coreboot process. If set to high value like 7 (DEBUG) it will be very verbose and make the booting process longer, since console output is selected (serial ports are slow). If you would like to debug coreboot you may leave the log level 7. If you would like a production- like image set it to 0 (EMERG) so that only very critical error will be printed on the serial port (COM).

Additionally there is an option to send POST codes to LPC and use a debug card to track the progress of booting. To do this, select Send POST codes to an external device and set Device to send POST codes to to LPC. Send POST codes to an IO port must be selected and IO port for POST codes should be 0x80. To use this debugging method a LPC POST debug card is needed like this one: https://www.aliexpress.com/item/32961958821.html This card should be plugged in place of mSATA disk on Protectli platforms. The last submenu which is of our interest is the Payload submenu. Payloads in coreboot are responsible for launching the target application or operating system. There is a variety of payload available in coreboot:

SeaBIOS - default coreboot payload which provides a legacy BIOS interface to boot from various disks and launch of the operating systems. This is the payload we will use. ELF executable payload - an arbitrary ELF application that should be run by coreboot FILO - it is a which loads boot images from a local filesystem, without help from legacy BIOS services. GRUB2 - one of the most popular open-source bootloader present in many Linux distributions LinuxBoot - LinuxBoot is a firmware for modern servers that replaces specific firmware functionality like the UEFI DXE phase with a Linux kernel and runtime. May be also integrated with Slimbootloader and coreboot U-boot - an open-source, primary boot loader used in embedded devices to package the instructions to boot the device's operating system kernel. Rather not so popular on x86 architecture, but ideal for ARM embedded systems. Yabits - an open-source implementation of UEFI standard (stale) A Linux payload - as simple as its name. The Linux kernel along with initrd and commandline is integrate into coreboot image. When coreboot finishes hardware initialization it just hands over he control to Linux kernel. Tianocore payload - a payload based on Efi Development Kit 2 (EDK2) and provides UEFI compliant services to load operating system. In short, it is an UEFI payload. One may select the desired payload in the Add a payload option, but we will focus on SeaBIOS. The most important options in this submenu are:

Hardware init during option ROM execution - parallelizes the hardware enumeration and initialization in SeaBIOS to speed up the boot process. Use with care, may impact the reliability of hardware initialization (for example not reliable USB detection) Hardware Interrupts - tells SeaBIOS to use hardware interrupts. Must be selected, otherwise SeaBIOS will hang at user input to enter the boot menu Include generated that implements legacy VGA BIOS compatibility - this option will be available only if FW6 is selected and libgfxinit is enabled. It tells SeaBIOS to build open-source VGA option ROM necessary for graphics output in SeaBIOS. SeaBIOS debug level (verbosity) - by default it is -1 to use defautl debug level, however it may introduce another problems with hardware enumeration due to delays related to serial port debug prints. Set it to 0 to avoid debugging information on serial port (COM). Add a PXE ROM - this option enabled the capability. If selected PXE Options submenu will appear.

To configure PXE network boot enter PXE Options submenu and:

Select Build and add an iPXE ROM in the PXE ROM to use Deselect Enable iPXE serial console (otherwise the serial output from iPXE will be doubled, iPXE itself prints on serial and SeaBIOS as well) Set the correct network card PCI IDs (although it should be correct by default): FW2B: 8086,1539 FW4B: 8086,157b FW6: 8086,150c Optionally we may add a logo image to be displayed during boot.

Go back to the main menu and enter General setup.

Select the Add a bootsplash image and provide the path to the bootsplash file. The supported formats are BMP and JPG.

If adding a bootsplash on FW6 with libgfxinit be sure to set linear framebuffer and use the BMP file. JPG will have problems with displayed colors due to unavailable 16bpp in libgfxinit. It is time to save our configuration and proceed with building.

To save the configuration press TAB and move the selection to the < Save > button and press enter. Confirm the the configuration file name and path (leave default) by pressing ENTER:

When the configuration is saved press TAB and move selection to < Exit > button and press ENTER. This should result in terminal inside container back again. Building the coreboot

When configuration is done invoke the building process from docker container:

(container) make

The build process will start, you will see many messages what is currently compiled. At the end (after 1-2 minutes, or even 5 minutes with PXE enabled) the build system will print the coreboot image contents:

FMAP REGION: COREBOOT Name Offset Type Size Comp cbfs master header 0x0 cbfs header 32 none fallback/romstage 0x80 stage 42716 none cpu_microcode_blob.bin 0xa7c0 microcode 402432 none fallback/ramstage 0x6cc40 stage 118207 none vgaroms/seavgabios.bin 0x89a40 raw 28672 none config 0x90ac0 raw 120 none revision 0x90b80 raw 680 none fallback/dsdt.aml 0x90e80 raw 10553 none vbt.bin 0x93840 raw 1167 LZMA etc/sercon-port 0x93d40 raw 8 none (empty) 0x93d80 null 24 none fspm.bin 0x93dc0 fsp 405504 none payload_config 0xf6e00 raw 1710 none payload_revision 0xf7500 raw 234 none (empty) 0xf7640 null 1880 none fsps.bin 0xf7dc0 fsp 188416 none fallback/postcar 0x125e00 stage 18084 none fallback/payload 0x12a500 simple elf 69499 none (empty) 0x13b4c0 null 4884696 none bootblock 0x5e3dc0 bootblock 49152 none HOSTCC cbfstool/ifwitool.o HOSTCC cbfstool/ifwitool (link) Built protectli/vault_kbl (FW6)

** WARNING ** coreboot has been built without an Intel Firmware Descriptor. Never write a complete coreboot.rom without an IFD to your board's flash chip! You can use 's IFD or layout parameters to flash only to the BIOS region.

That means the build process finished with success. Be aware of the warning. If you haven't added ME firmware and flash descriptor, do not flash whole file. The result binary is placed in coreboot/build/coreboot.rom. In order to flash your firmware with coreboot, install flashrom utility, that is used to update the platform firmware: sudo apt-get install flashrom # or sudo yum install flashrom # or sudo dnf install flashrom

For FW6 you have to use flashrom v1.1 at least in order to get it working.

Copy the coreboot.rom on your target Protectli platform and flash it with command: sudo flashrom -p intenal -w coreboot.rom --ifd -i

Example output of successfull flashing on FW6: root@:~# flashrom -p internal -w /tmp/coreboot.rom --ifd -i bios flashrom v1.1-rc1-127-g370a9f3 on Linux 4.19.0-9-amd64 (x86_64) flashrom is , get the source code at https://flashrom.org Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns). coreboot table found at 0x6fa9d000. Found chipset "Intel Kaby Lake U w/ iHDCP2.2 Prem.". This chipset is marked as untested. If you are using an up-to-date version of flashrom *and* were (not) able to successfully update your firmware with it, then please email a report to [email protected] including a verbose (-V) log. Thank you! Enabling flash write... Warning: Setting Bios Control at 0xdc from 0x8b to 0x89 failed. New value is 0x8b. SPI Configuration is locked down. OK. Found Programmer flash chip "Opaque flash chip" (8192 kB, Programmer-specific) mapped at physical address 0x0000000000000000. Reading ich descriptor... done. Using region: "bios". Reading old flash chip contents... done. Erasing and writing flash chip... Erase/write done. Verifying flash... VERIFIED.

After flashing, reboot the platform and wait until it brings up. At this point you may enjoy coreboot on your Protectli platform.