From coreboot
Revision as of 03:58, 13 February 2015 by Solb (talk | contribs) (Describe two shortcomings: upstreaming and duplicated configuration)
Jump to navigation Jump to search

The wiki is being retired!

Documentation is now handled by the same processes we use for code: Add something to the Documentation/ directory in the coreboot repo, and it will be rendered to https://doc.coreboot.org/. Contributions welcome!


Toward a unified representation for the layout of coreboot flash images

N.B. The changes described herein are being made as part of the Chromium OS project; as such, they will initially be committed to the project's own fork of the main coreboot repository, which is available at https://chromium.googlesource.com/chromiumos/third_party/coreboot. Unless otherwise noted, the paths and processes described throughout this page are as they exist(ed) in a checkout of the master branch of the Chromium OS sources as they appeared at the beginning of 2015. One of the guiding design principles is to keep the tools general enough that they will be helpful to others, and the resulting work will be upstreamed to the main repository once it has been regression-tested in the context of Chromium OS hardware.

How it's currently done (how the Chromium OS project presently constructs firmware images)

Most Intel-based Chromium OS devices currently use an 8 MB firmware image that includes—among other things—the Intel ME firmware, a copy of coreboot including the ramstage and depthcharge (bootloader) payload, two additional copies of the ramstage and bootloader payload, and a separate SeaBIOS payload. The primary description of this format exists in board-specific flattened device tree files, which are used by a script called cros_bundle_firmware to modify the image produced by the coreboot build system. For instance, the layout of the Panther board's firmware exists at https://chromium.googlesource.com/chromiumos/platform/depthcharge/+/master/board/panther/fmap.dts, and results in a final image that looks like this:

Intel Chromium OS firmware flash layout with component packaging notes

Section Offset Contents Original source cros_bundle_firmware flag(s) Packaging procedure Coreboot Kconfig entr[yi](es)
0x700000 Bootstub (coreboot image) coreboot.rom (coreboot build system) --coreboot coreboot.rom

--coreboot-elf depthcharge.elf

cros_bundle_firmware helper adds both depthcharge.elf as a payload (which—md5sums confirm—is exactly equivalent to just adding depthcharge.payload) and a compiled (then mod if ied) version of fmap.dts to the existing CBFS CONFIG_CMOS_POST_OFFSET, CONFIG_CBFS_SIZE
0x611000 GBB (Google Binary Block) /chromeos-config/ entries in fmap.dts --dt fmap.dts

--bmpblk bmpblk.bin

cros_bundle_firmware helper generates and inserts it
0x610840 (Reserved)
0x610800 RO-FWID (Firmware ID) /model entry in fmap.dts concatenated with build number --dt fmap.dts cros_bundle_firmware helper performs the concatenation
0x610000 FMAP (Flash MAP) fmap.dts itself --dt fmap.dts cros_bundle_firmware helper generates it while assembling the ultimate image file
0x604000 (Reserved)
0x600000 RO-VPD (Vital Product Data) cros_bundle_firmware fills this section with 0xff s
0x400000 Legacy (SeaBIOS image) seabios.cbfs --seabios seabios.cbfs cros_bundle_firmware helper inserts the file verbatim, as confirmed by an md5sum on the final image
0x3fa000 (Reserved)
0x3f8000 RW-VPD (Vital Product Data) cros_bundle_firmware fills this section with 0xff s
0x3f6000 Vblock-dev (third-party kernel signing keys) cros_bundle_firmware fills this section with 0xff s
0x3f4000 Shared-data (RW firmware calibration data) cros_bundle_firmware fills this section with 0x00 s
0x3f0000 ELOG (Event LOG) cros_bundle_firmware fills this section with 0xff s
0x3e0000 MRC-cache (Memory Reference Code training data) cros_bundle_firmware fills this section with 0xff s
0x3dffc0 FWID-B (Copy of RO-FWID above)
0x300000 Main-B (copy of coreboot ramstage and payload) (Same as main-A below)
0x2f0000 Vblock-B (signing keys) (Same as vblock-A below)
0x2effc0 FWID-A (Copy of RO-FWID above)
0x210000 Main-A (copy of coreboot ramstage and payload) depthcharge.payload and ramstage.stage --uboot depthcharge.payload

--add-blob ramstage ramstage.stage

Because fmap.dts lists its type as "blob boot,ramstage" , cros_bundle_firmware concatenates the blob called ramstage onto the end of coreboot
0x200000 Vblock-A (signing keys) cros_bundle_firmware helper signs the main-A section and puts the signature here
0x001000 ME (Intel Management Engine firmware blob) coreboot.rom --coreboot coreboot.rom Present in the original image generated by the coreboot build system (which simply inserted some Intel blob verbatim)
0x000000 FD (Intel Firmware Descriptor header) coreboot.rom --coreboot coreboot.rom cros_bundle_firmware helper invokes ifdtool to create the final image, using the original coreboot.rom file's ME and "skeleton" (template) IFD, and concatenating on verbatim the rest of the pieces it assembled to form the (Intel-dubbed) "BIOS" section

What's so bad about that (the pitfalls of this build model that we hope to solve)

While the layout of the flash image is obvious from a board's fmap.dts file, the actual process by which the image is constructed—and most importantly, the transformation and other processing applied to each input file—is poorly documented and not widely understood. After examining the overall assembly procedure and distilling it into the above tables, the following shortcomings are apparent:

The build system organization favors divergence from upstream coreboot

This implies two subproblems: upstreaming code from Chromium OS to the main coreboot source tree is difficult, and it isn't easy to build upstream coreboot for a Chromium OS device. It's important to note that, while related, these are not identical shortcomings: while the upstreaming difficulty certainly prohibits building some devices, other devices have enough code already pushed that it would be possible to run them if the coreboot build system were able to produce an image that was ready to flash on the hardware.

As can be seen from the above table, there's no technical reason that sufficient functionality to build a complete image can't be upstreamed to coreboot itself: with the exception of ramstage.stage—which is actually just another copy of a binary generated by the coreboot build system—everything that needs to be added to the coreboot-generated image is either a binary blob or compiles without depending on any part of coreboot besides libpayload.

There is error-prone duplication in the image layout configuration

Because image assembly is currently a multistage process, several offsets and sizes need to be duplicated across multiple configuration files; if these files are not manually kept in step, the process can result in an obviously broken (e.g. part or all of coreboot or the CBFS is overwritten with another binary) or more subtly broken (e.g. coreboot assumes an FMAP exists at a particular flash location, but when it attempts to find it at runtime, it isn't there). To make matters worse, the redundant configuration parameters are stored in separate repositories, so checking out a different version of one boot component can silently result in a mismatch. Adding insult to injury, one of said configurations is stored in binary form within the IFD, which forces us to check in an IFD blob for each boardmaking it even more difficult to rearrange the flash layout.

Why you should care (how this pertains to all coreboot users)

How do we fix it (the solution being pursued)