aboutsummaryrefslogtreecommitdiff
path: root/Documentation/technotes/2015-11-rebuilding-coreboot-image-generation.md
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/technotes/2015-11-rebuilding-coreboot-image-generation.md')
-rw-r--r--Documentation/technotes/2015-11-rebuilding-coreboot-image-generation.md266
1 files changed, 266 insertions, 0 deletions
diff --git a/Documentation/technotes/2015-11-rebuilding-coreboot-image-generation.md b/Documentation/technotes/2015-11-rebuilding-coreboot-image-generation.md
new file mode 100644
index 0000000000..d2a8fdcc0d
--- /dev/null
+++ b/Documentation/technotes/2015-11-rebuilding-coreboot-image-generation.md
@@ -0,0 +1,266 @@
+Rebuilding coreboot image generation
+====================================
+
+Current situation
+-----------------
+Chrome OS (CrOS) probably has the most complex image bundling process in the
+coreboot ecosystem. To make CrOS features more accessible to the wider
+coreboot community, we want to move these capabilities into upstream
+coreboot’s build system.
+
+Right now, the CrOS build system creates coreboot images, and various
+instances of the payload (with different configuration options), plus some
+more files (eg. EC firmware), then passes them to a CrOS-specific utility
+(`bundle_firmware.py`) to build the final image from that.
+
+`bundle_firmware` adds a flashmap (fmap) to the final image and creates
+additional CBFS filesystems in fmap regions. It then extracts some files from
+the original CBFS region (that was put in place carefully to later match to
+the default fmap region) and copies some of them into the others, as well as
+putting more data (eg. the bitmap data, keys) as raw data into other fmap
+regions.
+
+With the recent addition of more files to CBFS, both on the coreboot side
+(dsdt, FSP, and so on) and with Chrome OS specifics (eg. more files describing
+boot screens) we either need to expand the scope of bundle\_firmware or move
+the capability to build complex images to upstream coreboot’s build system.
+This document proposes to do the latter and outlines how this could be
+achieved.
+
+Problems with the current build system parts
+--------------------------------------------
+One common sentiment is that it should be possible to reuse some of the
+existing mechanisms that are supposed to be supplanted by this.
+The main concern during this design that precluded their use was that none of
+them provides a comprehensive solution to building complex coreboot based
+images:
+* fmap.dts and fmd provide a flash layout, but no assignment of files of regions
+* cbfs-files-y ends up as an internal make variable using
+ `weird|formatting|to|deal|with|make’s|limitations`
+* make isn’t powerful enough to deal with ordering these entries in said
+ variable to guarantee success if there’s enough room for the files. While that
+ could be added, that becomes more make macro work indistinguishable from magic
+ that people fail to understand, break and with good reason complain about
+ to work around such issues, Chrome OS firmware uses a custom tool with even
+ more special cases to finally build the image it needs. If coreboot upstream
+ is to support vboot, it should also be powerful enough not to need magic tools
+ that only live within downstream projects.
+
+Requirements
+------------
+A complete Chrome OS coreboot image consists of (depending on the device)
+* platform specific data in raw fmap regions (eg IFD, ME firmware),
+* the bootblock (coming from the bootblock),
+* three copies of coreboot, consisting of the stages (verstage, romstage,
+ ramstage) plus data,
+* depthcharge plus data (with each of the coreboot copies),
+* EC firmware files (with each of the coreboot copies),
+* signatures over several parts of the image and
+* some final checksumming over parts of the image to satisfy boot ROM
+ tests on ARM
+
+A complete upstream coreboot image (with fallback/normal switch configuration,
+using a yet to be implemented switching scheme based on fmaps) consists of
+* platform specific data in raw fmap regions (eg IFD, ME firmware),
+* two copies of coreboot, consisting of
+ * the bootblock and
+ * the stages (romstage, ramstage) plus data,
+* payload plus data (with each of the coreboot copies),
+
+Since a single platform is potentially built with different payload
+configurations (eg. modding a Chromebook to not use the verified Chrome OS
+boot scheme), some concerns need to be kept separate:
+* Platform requirements that have nothing to do with the payload or boot schemes
+ * IFD, ME, … need to copied to the right place
+ * boot ROM requirements such as checksums must be honored
+* Payload/boot scheme requirements
+ * Having one to three regions with certain files copied into them
+
+Proposal
+--------
+The proposal is based on manifest files that describe certain aspects of the
+final image.
+The number of manifest files may change over time, but this seems to be a
+reasonable approach for now. As long as coreboot uses fmap and cbfs, there
+should be few need to change the language, since composition is done through
+files.
+
+The final image is generated by a utility that is handed a number of manifests
+and the size of the flash (derived from `CONFIG_ROM_SIZE`). These manifest files
+deal with different concerns, with the following an example that should match
+current use cases:
+
+Chipset manifest
+----------------
+The chipset details if there are any non-coreboot regions, and assigns them
+names, locations, sizes and file contents and prepares a region for what is
+“platform visible” (eg. IFD’s BIOS region) that may be of flexible size
+(depending on the flash chip’s size). For the purpose of this document, that
+region is called “BIOS”.
+It can also specify if there’s a post processing requirement on the final
+image.
+
+coreboot manifest
+-----------------
+coreboot provides lists of the files it generates for each category it’s
+building (eg. bootblock, verstage, romstage, ramstage). They not only contain
+the stages themselves, but also additional files (eg. dsdt belongs to ramstage
+since that’s where it is used)
+
+Boot method manifest
+--------------------
+The boot method manifest can subdivide the BIOS region, eg. using it directly
+(for coreboot’s “simple” bootblock), splitting it in two (for coreboot’s
+fallback/normal) or in many parts (for Chrome OS, which requires two CBFS
+regions, one for GBB, several for VPD, …).
+It also specifies which of the file lists specified earlier belong in which
+region (eg. with verstage verifying romstage, verstage needs to be only in
+Chrome OS’ RO region, while romstage belongs in RO and both RW regions).
+It can also specify a post processing step that is executed before the
+chipset’s.
+
+Payload and additional manifests
+--------------------------------
+External components should also provide manifests to add files to categories.
+This way the payload and other components (eg. EC firmware) can be developed
+without needing to touch the central boot method manifest (that likely resides
+in the coreboot tree, given that coreboot needs to deal with choosing fmap
+regions already).
+
+coreboot build system
+---------------------
+The coreboot build system will be split more distinctly in two phases: The
+first is about building the files (with results like romstage.elf), while the
+second phase covers the assembly of the final image.
+
+By having a global picture of the final image’s requirements, we can also
+avoid issues where files added earlier may prevent later additions that have
+stricter constraints - without resorting to hacks like
+https://chromium-review.googlesource.com/289491 that reorder the file addition
+manually.
+
+Example
+-------
+As an example, we’ll define an Intel-based board with a postprocessing tool
+(something that doesn’t exist, but isn’t hard to imagine):
+
+It specifies an IFD region, an ME, and the BIOS region. After the image is
+built, the entire image needs to be processed (although the tool likely works
+only on a small part of it)
+
+It’s built in a Chrome OS-like configuration (simplified at places to avoid
+distracting from the important parts), so it has three CBFS regions, and
+several data regions for its own purpose (similar to GBB, FWID, VPD, …). After
+the regions are filled, one data region must be post-processed to contain
+signatures to enable verifying other regions.
+
+Chipset manifest
+================
+# A region called IFD, starting at 0, ending at 4K
+region IFD: 0 4K
+# Add the specified file “raw” into the region.
+# If the file is smaller than the region, put it at the bottom and fill up
+# with 0xff
+raw IFD: build/ifd.bin align=bottom empty=0xff
+# Call the postprocessor on the data that ends up in IFD (in this example it
+# might lock the IFD)
+postprocess IFD: util/ifdprocess -l
+
+# a region called ME, starting at 4K, ending at 2M
+region ME: 4K 2M
+raw ME: 3rdparty/blobs/soc/intel/xanadu/me.bin align=bottom empty=0x00
+
+# a region called BIOS, starting at 2M, filling up the free space
+# filling up fails (build error) if two regions are requested to fill up
+# against each other
+region BIOS: 2M *
+
+# This would define a region that covers the last 4K of flash.
+# The BIOS region specified above will end right before it instead of
+# expanding to end of flash
+# region AUX: -4K -0
+
+# specify the tool that post-processes the entire image.
+postprocess image: util/intelchksum/intelchksum.sh
+
+coreboot manifest
+=================
+# declare that build/verstage.elf belongs into the group ‘verstage’
+# these groups are later referred to by the “cbfs” command.
+group verstage: build/verstage.elf stage xip name=fallback/verstage
+group romstage: build/romstage.elf stage xip name=fallback/romstage
+group ramstage: build/ramstage.elf stage name=fallback/ramstage
+compression=lzma
+group ramstage: build/dsdt.aml compression=lzma
+
+boot method manifest
+====================
+# Define RO as region inside BIOS, covering the upper half of the image.
+# It’s a build error if the result crosses outside BIOS.
+# math expressions are wrapped with ( ),
+# and mentions of regions therein always refer to their size
+subregion BIOS RO: ( image / 2 ) -0
+
+# Define RW to cover the rest of BIOS.
+# The order of RW and RO doesn’t matter except to keep comments clearer.
+# Dynamic items like RW (“*”) will be sized to fill unused space after
+# everything else is placed.
+subregion BIOS RW: 0 *
+
+# It may be necessary to separate the RO/RW definition into another manifest
+# file
+# that defines the RO configuration of the flash
+
+# Some more subregions, with dynamically calculated sizes
+subregion RW RW_A: 0 ( RW / 2 )
+subregion RW RW_B: * -0
+subregion RW_A FW_MAIN_A: RW_A * -0
+subregion RW_A VBLOCK_A: 0 64K
+# foo +bar specifies start + size, not (start, end)
+# also, start is given as “the end of VBLOCK_A”
+# (while using a region in the “end” field means “start of region”)
+subregion RW_A FWID_A: VBLOCK_A +64
+
+# To make the example not too verbose, RO only has the CBFS region
+subregion RO BOOTSTUB: 0 *
+
+# Postprocess the data that ends up in VBLOCK_A,
+# passing the listed regions as additional arguments.
+# Circular dependencies are build errors.
+postprocess VBLOCK_A(FW_MAIN_A): signtool
+
+# binding files to regions indirectly through groups
+cbfs BOOTSTUB: verstage, romstage, ramstage, payload
+cbfs FW_MAIN_A: romstage, ramstage, payload
+
+# defining defaults: unless overridden, in all regions that use CBFS (“*”),
+# we want all files to come with SHA256 hashes.
+# Wildcard defaults have lower priority than specific defaults.
+# Other conflicts lead to a build error.
+cbfsdefaults *: hash=sha3
+
+payload manifest
+================
+group payload: payload.elf payload
+group payload: bootscreen.jpg name=splashscreen.jpg type=splashscreen
+
+EC firmware manifest
+====================
+# overrides the cbfsdefault above
+group payload: ecrw.bin name=ecrw hash=sha256
+group payload: pdrw.bin name=pdrw hash=sha256
+
+manifest parsing
+================
+The exact BNF is work in progress.
+
+Some parser rules are
+* one line per statement
+* # introduces a command until the end of line
+
+Some processing rules
+* When there’s a conflict (eg. two statements on what to do to a region,
+ overlap, anything that can’t be determined), that is a build error.
+* the order of statements doesn’t matter, enabling simple addition of more
+ manifests where the need arises.
+