[PATCH v2 17/38] binman: Add a bintool implementation for cbfstool

Simon Glass sjg at chromium.org
Mon Jan 10 04:13:52 CET 2022


Add a Bintool for this, which is used to run CBFS tests. It supports
the features needed by the tests as well as fetching a binary from
Google Drive. Building it from source is very slow since it is not
separately supported by the coreboot build system and it builds an
entire gcc toolchain before starting.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

(no changes since v1)

 tools/binman/btool/cbfstool.py | 219 +++++++++++++++++++++++++++++++++
 1 file changed, 219 insertions(+)
 create mode 100644 tools/binman/btool/cbfstool.py

diff --git a/tools/binman/btool/cbfstool.py b/tools/binman/btool/cbfstool.py
new file mode 100644
index 00000000000..29be2d8a2b5
--- /dev/null
+++ b/tools/binman/btool/cbfstool.py
@@ -0,0 +1,219 @@
+# 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
-- 
2.34.1.575.g55b058a8bb-goog



More information about the U-Boot mailing list