Branding changes to unify and update Chrome OS to ChromeOS (removing the space). This CL also includes changing Chromium OS to ChromiumOS as well. BUG=None TEST=N/A Change-Id: I39af9f1069b62747dbfeebdd62d85fabfa655dcd Signed-off-by: Jon Murphy <jpmurphy@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/65479 Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Singer <felixsinger@posteo.net>
		
			
				
	
	
		
			269 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| Rebuilding coreboot image generation
 | ||
| ====================================
 | ||
| 
 | ||
| Current situation
 | ||
| -----------------
 | ||
| ChromeOS (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 ChromeOS 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, ChromeOS 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 ChromeOS 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 ChromeOS
 | ||
| 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 ChromeOS, 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
 | ||
| ChromeOS’ 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 ChromeOS-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.
 | ||
| 
 |