| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- # SPDX-License-Identifier: GPL-2.0+
- # Copyright 2022 Google LLC
- #
- """Bintool implementation for cbfstool
- cfstool provides a number of features useful with Coreboot Filesystem binaries.
- Documentation is at https://www.coreboot.org/CBFS
- Source code is at https://github.com/coreboot/coreboot/blob/master/util/cbfstool/cbfstool.c
- Here is the help:
- cbfstool: Management utility for CBFS formatted ROM images
- USAGE:
- cbfstool [-h]
- cbfstool FILE COMMAND [-v] [PARAMETERS]...
- OPTIONs:
- -H header_offset Do not search for header; use this offset*
- -T Output top-aligned memory address
- -u Accept short data; fill upward/from bottom
- -d Accept short data; fill downward/from top
- -F Force action
- -g Generate position and alignment arguments
- -U Unprocessed; don't decompress or make ELF
- -v Provide verbose output
- -h Display this help message
- COMMANDs:
- add [-r image,regions] -f FILE -n NAME -t TYPE [-A hash] \
- [-c compression] [-b base-address | -a alignment] \
- [-p padding size] [-y|--xip if TYPE is FSP] \
- [-j topswap-size] (Intel CPUs only) [--ibb]
- Add a component
- -j valid size: 0x10000 0x20000 0x40000 0x80000 0x100000
- add-payload [-r image,regions] -f FILE -n NAME [-A hash] \
- [-c compression] [-b base-address] \
- (linux specific: [-C cmdline] [-I initrd])
- Add a payload to the ROM
- add-stage [-r image,regions] -f FILE -n NAME [-A hash] \
- [-c compression] [-b base] [-S section-to-ignore] \
- [-a alignment] [-y|--xip] [-P page-size] [--ibb]
- Add a stage to the ROM
- add-flat-binary [-r image,regions] -f FILE -n NAME \
- [-A hash] -l load-address -e entry-point \
- [-c compression] [-b base]
- Add a 32bit flat mode binary
- add-int [-r image,regions] -i INTEGER -n NAME [-b base]
- Add a raw 64-bit integer value
- add-master-header [-r image,regions] \
- [-j topswap-size] (Intel CPUs only)
- Add a legacy CBFS master header
- remove [-r image,regions] -n NAME
- Remove a component
- compact -r image,regions
- Defragment CBFS image.
- copy -r image,regions -R source-region
- Create a copy (duplicate) cbfs instance in fmap
- create -m ARCH -s size [-b bootblock offset] \
- [-o CBFS offset] [-H header offset] [-B bootblock]
- Create a legacy ROM file with CBFS master header*
- create -M flashmap [-r list,of,regions,containing,cbfses]
- Create a new-style partitioned firmware image
- locate [-r image,regions] -f FILE -n NAME [-P page-size] \
- [-a align] [-T]
- Find a place for a file of that size
- layout [-w]
- List mutable (or, with -w, readable) image regions
- print [-r image,regions]
- Show the contents of the ROM
- extract [-r image,regions] [-m ARCH] -n NAME -f FILE [-U]
- Extracts a file from ROM
- write [-F] -r image,regions -f file [-u | -d] [-i int]
- Write file into same-size [or larger] raw region
- read [-r fmap-region] -f file
- Extract raw region contents into binary file
- truncate [-r fmap-region]
- Truncate CBFS and print new size on stdout
- expand [-r fmap-region]
- Expand CBFS to span entire region
- OFFSETs:
- Numbers accompanying -b, -H, and -o switches* may be provided
- in two possible formats: if their value is greater than
- 0x80000000, they are interpreted as a top-aligned x86 memory
- address; otherwise, they are treated as an offset into flash.
- ARCHes:
- arm64, arm, mips, ppc64, power8, riscv, x86, unknown
- TYPEs:
- bootblock, cbfs header, stage, simple elf, fit, optionrom, bootsplash, raw,
- vsa, mbi, microcode, fsp, mrc, cmos_default, cmos_layout, spd,
- mrc_cache, mma, efi, struct, deleted, null
- * Note that these actions and switches are only valid when
- working with legacy images whose structure is described
- primarily by a CBFS master header. New-style images, in
- contrast, exclusively make use of an FMAP to describe their
- layout: this must minimally contain an 'FMAP' section
- specifying the location of this FMAP itself and a 'COREBOOT'
- section describing the primary CBFS. It should also be noted
- that, when working with such images, the -F and -r switches
- default to 'COREBOOT' for convenience, and both the -b switch to
- CBFS operations and the output of the locate action become
- relative to the selected CBFS region's lowest address.
- The one exception to this rule is the top-aligned address,
- which is always relative to the end of the entire image
- rather than relative to the local region; this is true for
- for both input (sufficiently large) and output (-T) data.
- Since binman has a native implementation of CBFS (see cbfs_util.py), we don't
- actually need this tool, except for sanity checks in the tests.
- """
- from binman import bintool
- class Bintoolcbfstool(bintool.Bintool):
- """Coreboot filesystem (CBFS) tool
- This bintool supports creating new CBFS images and adding files to an
- existing image, i.e. the features needed by binman.
- It also supports fetching a binary cbfstool, since building it from source
- is fairly slow.
- Documentation about CBFS is at https://www.coreboot.org/CBFS
- """
- def __init__(self, name):
- super().__init__(name, 'Manipulate CBFS files')
- def create_new(self, cbfs_fname, size, arch='x86'):
- """Create a new CBFS
- Args:
- cbfs_fname (str): Filename of CBFS to create
- size (int): Size of CBFS in bytes
- arch (str): Architecture for which this CBFS is intended
- Returns:
- str: Tool output
- """
- args = [cbfs_fname, 'create', '-s', f'{size:#x}', '-m', arch]
- return self.run_cmd(*args)
- # pylint: disable=R0913
- def add_raw(self, cbfs_fname, name, fname, compress=None, base=None):
- """Add a raw file to the CBFS
- Args:
- cbfs_fname (str): Filename of CBFS to create
- name (str): Name to use inside the CBFS
- fname (str): Filename of file to add
- compress (str): Compression to use (cbfs_util.COMPRESS_NAMES) or
- None for None
- base (int): Address to place the file, or None for anywhere
- Returns:
- str: Tool output
- """
- args = [cbfs_fname,
- 'add',
- '-n', name,
- '-t', 'raw',
- '-f', fname,
- '-c', compress or 'none']
- if base:
- args += ['-b', f'{base:#x}']
- return self.run_cmd(*args)
- def add_stage(self, cbfs_fname, name, fname):
- """Add a stage file to the CBFS
- Args:
- cbfs_fname (str): Filename of CBFS to create
- name (str): Name to use inside the CBFS
- fname (str): Filename of file to add
- Returns:
- str: Tool output
- """
- args = [cbfs_fname,
- 'add-stage',
- '-n', name,
- '-f', fname
- ]
- return self.run_cmd(*args)
- def fail(self):
- """Run cbfstool with invalid arguments to check it reports failure
- This is really just a sanity check
- Returns:
- CommandResult: Result from running the bad command
- """
- args = ['missing-file', 'bad-command']
- return self.run_cmd_result(*args)
- def fetch(self, method):
- """Fetch handler for cbfstool
- This installs cbfstool by downloading from Google Drive.
- Args:
- method (FETCH_...): Method to use
- Returns:
- True if the file was fetched and now installed, None if a method
- other than FETCH_BIN was requested
- Raises:
- Valuerror: Fetching could not be completed
- """
- if method != bintool.FETCH_BIN:
- return None
- fname, tmpdir = self.fetch_from_drive(
- '1IOnE0Qvy97d-0WOCwF64xBGpKSY2sMtJ')
- return fname, tmpdir
|