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
|