Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | # 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 # Version 4.22.01 fname, tmpdir = self.fetch_from_drive( '1gxNxRuJgD0Iiy9LAPCSB_0959eJCp98g') return fname, tmpdir |