blob: 29be2d8a2b55112e2921f44a1f7a130f5fce966f [file] [log] [blame]
Simon Glassb8dbca92022-01-09 20:13:52 -07001# SPDX-License-Identifier: GPL-2.0+
2# Copyright 2022 Google LLC
3#
4"""Bintool implementation for cbfstool
5
6cfstool provides a number of features useful with Coreboot Filesystem binaries.
7
8Documentation is at https://www.coreboot.org/CBFS
9
10Source code is at https://github.com/coreboot/coreboot/blob/master/util/cbfstool/cbfstool.c
11
12Here is the help:
13
14cbfstool: Management utility for CBFS formatted ROM images
15
16USAGE:
17 cbfstool [-h]
18 cbfstool FILE COMMAND [-v] [PARAMETERS]...
19
20OPTIONs:
21 -H header_offset Do not search for header; use this offset*
22 -T Output top-aligned memory address
23 -u Accept short data; fill upward/from bottom
24 -d Accept short data; fill downward/from top
25 -F Force action
26 -g Generate position and alignment arguments
27 -U Unprocessed; don't decompress or make ELF
28 -v Provide verbose output
29 -h Display this help message
30
31COMMANDs:
32 add [-r image,regions] -f FILE -n NAME -t TYPE [-A hash] \
33 [-c compression] [-b base-address | -a alignment] \
34 [-p padding size] [-y|--xip if TYPE is FSP] \
35 [-j topswap-size] (Intel CPUs only) [--ibb]
36 Add a component
37 -j valid size: 0x10000 0x20000 0x40000 0x80000 0x100000
38 add-payload [-r image,regions] -f FILE -n NAME [-A hash] \
39 [-c compression] [-b base-address] \
40 (linux specific: [-C cmdline] [-I initrd])
41 Add a payload to the ROM
42 add-stage [-r image,regions] -f FILE -n NAME [-A hash] \
43 [-c compression] [-b base] [-S section-to-ignore] \
44 [-a alignment] [-y|--xip] [-P page-size] [--ibb]
45 Add a stage to the ROM
46 add-flat-binary [-r image,regions] -f FILE -n NAME \
47 [-A hash] -l load-address -e entry-point \
48 [-c compression] [-b base]
49 Add a 32bit flat mode binary
50 add-int [-r image,regions] -i INTEGER -n NAME [-b base]
51 Add a raw 64-bit integer value
52 add-master-header [-r image,regions] \
53 [-j topswap-size] (Intel CPUs only)
54 Add a legacy CBFS master header
55 remove [-r image,regions] -n NAME
56 Remove a component
57 compact -r image,regions
58 Defragment CBFS image.
59 copy -r image,regions -R source-region
60 Create a copy (duplicate) cbfs instance in fmap
61 create -m ARCH -s size [-b bootblock offset] \
62 [-o CBFS offset] [-H header offset] [-B bootblock]
63 Create a legacy ROM file with CBFS master header*
64 create -M flashmap [-r list,of,regions,containing,cbfses]
65 Create a new-style partitioned firmware image
66 locate [-r image,regions] -f FILE -n NAME [-P page-size] \
67 [-a align] [-T]
68 Find a place for a file of that size
69 layout [-w]
70 List mutable (or, with -w, readable) image regions
71 print [-r image,regions]
72 Show the contents of the ROM
73 extract [-r image,regions] [-m ARCH] -n NAME -f FILE [-U]
74 Extracts a file from ROM
75 write [-F] -r image,regions -f file [-u | -d] [-i int]
76 Write file into same-size [or larger] raw region
77 read [-r fmap-region] -f file
78 Extract raw region contents into binary file
79 truncate [-r fmap-region]
80 Truncate CBFS and print new size on stdout
81 expand [-r fmap-region]
82 Expand CBFS to span entire region
83OFFSETs:
84 Numbers accompanying -b, -H, and -o switches* may be provided
85 in two possible formats: if their value is greater than
86 0x80000000, they are interpreted as a top-aligned x86 memory
87 address; otherwise, they are treated as an offset into flash.
88ARCHes:
89 arm64, arm, mips, ppc64, power8, riscv, x86, unknown
90TYPEs:
91 bootblock, cbfs header, stage, simple elf, fit, optionrom, bootsplash, raw,
92 vsa, mbi, microcode, fsp, mrc, cmos_default, cmos_layout, spd,
93 mrc_cache, mma, efi, struct, deleted, null
94
95* Note that these actions and switches are only valid when
96 working with legacy images whose structure is described
97 primarily by a CBFS master header. New-style images, in
98 contrast, exclusively make use of an FMAP to describe their
99 layout: this must minimally contain an 'FMAP' section
100 specifying the location of this FMAP itself and a 'COREBOOT'
101 section describing the primary CBFS. It should also be noted
102 that, when working with such images, the -F and -r switches
103 default to 'COREBOOT' for convenience, and both the -b switch to
104 CBFS operations and the output of the locate action become
105 relative to the selected CBFS region's lowest address.
106 The one exception to this rule is the top-aligned address,
107 which is always relative to the end of the entire image
108 rather than relative to the local region; this is true for
109 for both input (sufficiently large) and output (-T) data.
110
111
112Since binman has a native implementation of CBFS (see cbfs_util.py), we don't
113actually need this tool, except for sanity checks in the tests.
114"""
115
116from binman import bintool
117
118class Bintoolcbfstool(bintool.Bintool):
119 """Coreboot filesystem (CBFS) tool
120
121 This bintool supports creating new CBFS images and adding files to an
122 existing image, i.e. the features needed by binman.
123
124 It also supports fetching a binary cbfstool, since building it from source
125 is fairly slow.
126
127 Documentation about CBFS is at https://www.coreboot.org/CBFS
128 """
129 def __init__(self, name):
130 super().__init__(name, 'Manipulate CBFS files')
131
132 def create_new(self, cbfs_fname, size, arch='x86'):
133 """Create a new CBFS
134
135 Args:
136 cbfs_fname (str): Filename of CBFS to create
137 size (int): Size of CBFS in bytes
138 arch (str): Architecture for which this CBFS is intended
139
140 Returns:
141 str: Tool output
142 """
143 args = [cbfs_fname, 'create', '-s', f'{size:#x}', '-m', arch]
144 return self.run_cmd(*args)
145
146 # pylint: disable=R0913
147 def add_raw(self, cbfs_fname, name, fname, compress=None, base=None):
148 """Add a raw file to the CBFS
149
150 Args:
151 cbfs_fname (str): Filename of CBFS to create
152 name (str): Name to use inside the CBFS
153 fname (str): Filename of file to add
154 compress (str): Compression to use (cbfs_util.COMPRESS_NAMES) or
155 None for None
156 base (int): Address to place the file, or None for anywhere
157
158 Returns:
159 str: Tool output
160 """
161 args = [cbfs_fname,
162 'add',
163 '-n', name,
164 '-t', 'raw',
165 '-f', fname,
166 '-c', compress or 'none']
167 if base:
168 args += ['-b', f'{base:#x}']
169 return self.run_cmd(*args)
170
171 def add_stage(self, cbfs_fname, name, fname):
172 """Add a stage file to the CBFS
173
174 Args:
175 cbfs_fname (str): Filename of CBFS to create
176 name (str): Name to use inside the CBFS
177 fname (str): Filename of file to add
178
179 Returns:
180 str: Tool output
181 """
182 args = [cbfs_fname,
183 'add-stage',
184 '-n', name,
185 '-f', fname
186 ]
187 return self.run_cmd(*args)
188
189 def fail(self):
190 """Run cbfstool with invalid arguments to check it reports failure
191
192 This is really just a sanity check
193
194 Returns:
195 CommandResult: Result from running the bad command
196 """
197 args = ['missing-file', 'bad-command']
198 return self.run_cmd_result(*args)
199
200 def fetch(self, method):
201 """Fetch handler for cbfstool
202
203 This installs cbfstool by downloading from Google Drive.
204
205 Args:
206 method (FETCH_...): Method to use
207
208 Returns:
209 True if the file was fetched and now installed, None if a method
210 other than FETCH_BIN was requested
211
212 Raises:
213 Valuerror: Fetching could not be completed
214 """
215 if method != bintool.FETCH_BIN:
216 return None
217 fname, tmpdir = self.fetch_from_drive(
218 '1IOnE0Qvy97d-0WOCwF64xBGpKSY2sMtJ')
219 return fname, tmpdir