mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
binman: Move entry-data collection into a Entry method
Collecting the data from a list of entries and putting it in a file is a useful operation that will be needed by other entry types. Put this into a method in the Entry class. Add some documentation about how to collect data for an entry type. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
56385c585f
commit
81b71c3200
3 changed files with 118 additions and 10 deletions
|
@ -1358,6 +1358,92 @@ development, since dealing with exceptions and problems in threads is more
|
|||
difficult. This avoids any use of ThreadPoolExecutor.
|
||||
|
||||
|
||||
Collecting data for an entry type
|
||||
---------------------------------
|
||||
|
||||
Some entry types deal with data obtained from others. For example,
|
||||
`Entry_mkimage` calls the `mkimage` tool with data from its subnodes::
|
||||
|
||||
mkimage {
|
||||
args = "-n test -T script";
|
||||
|
||||
u-boot-spl {
|
||||
};
|
||||
|
||||
u-boot {
|
||||
};
|
||||
};
|
||||
|
||||
This shows mkimage being passed a file consisting of SPL and U-Boot proper. It
|
||||
is create by calling `Entry.collect_contents_to_file()`. Note that in this case,
|
||||
the data is passed to mkimage for processing but does not appear separately in
|
||||
the image. It may not appear at all, depending on what mkimage does. The
|
||||
contents of the `mkimage` entry are entirely dependent on the processing done
|
||||
by the entry, with the provided subnodes (`u-boot-spl` and `u-boot`) simply
|
||||
providing the input data for that processing.
|
||||
|
||||
Note that `Entry.collect_contents_to_file()` simply concatenates the data from
|
||||
the different entries together, with no control over alignment, etc. Another
|
||||
approach is to subclass `Entry_section` so that those features become available,
|
||||
such as `size` and `pad-byte`. Then the contents of the entry can be obtained by
|
||||
calling `BuildSectionData()`.
|
||||
|
||||
There are other ways to obtain data also, depending on the situation. If the
|
||||
entry type is simply signing data which exists elsewhere in the image, then
|
||||
you can use `Entry_collection` as a base class. It lets you use a property
|
||||
called `content` which lists the entries containing data to be processed. This
|
||||
is used by `Entry_vblock`, for example::
|
||||
|
||||
u_boot: u-boot {
|
||||
};
|
||||
vblock {
|
||||
content = <&u_boot &dtb>;
|
||||
keyblock = "firmware.keyblock";
|
||||
signprivate = "firmware_data_key.vbprivk";
|
||||
version = <1>;
|
||||
kernelkey = "kernel_subkey.vbpubk";
|
||||
preamble-flags = <1>;
|
||||
};
|
||||
|
||||
dtb: u-boot-dtb {
|
||||
};
|
||||
|
||||
which shows an image containing `u-boot` and `u-boot-dtb`, with the `vblock`
|
||||
image collecting their contents to produce input for its signing process,
|
||||
without affecting those entries, which still appear in the final image
|
||||
untouched.
|
||||
|
||||
Another example is where an entry type needs several independent pieces of input
|
||||
to function. For example, `Entry_fip` allows a number of different binary blobs
|
||||
to be placed in their own individual places in a custom data structure in the
|
||||
output image. To make that work you can add subnodes for each of them and call
|
||||
`Entry.Create()` on each subnode, as `Entry_fip` does. Then the data for each
|
||||
blob can come from any suitable place, such as an `Entry_u_boot` or an
|
||||
`Entry_blob` or anything else::
|
||||
|
||||
atf-fip {
|
||||
fip-hdr-flags = /bits/ 64 <0x123>;
|
||||
soc-fw {
|
||||
fip-flags = /bits/ 64 <0x123456789abcdef>;
|
||||
filename = "bl31.bin";
|
||||
};
|
||||
|
||||
u-boot {
|
||||
fip-uuid = [fc 65 13 92 4a 5b 11 ec
|
||||
94 35 ff 2d 1c fc 79 9c];
|
||||
};
|
||||
};
|
||||
|
||||
The `soc-fw` node is a `blob-ext` (i.e. it reads in a named binary file) whereas
|
||||
`u-boot` is a normal entry type. This works because `Entry_fip` selects the
|
||||
`blob-ext` entry type if the node name (here `soc-fw`) is recognised as being
|
||||
a known blob type.
|
||||
|
||||
When adding new entry types you are encouraged to use subnodes to provide the
|
||||
data for processing, unless the `content` approach is more suitable. Ad-hoc
|
||||
properties and other methods of obtaining data are discouraged, since it adds to
|
||||
confusion for users.
|
||||
|
||||
History / Credits
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -1123,3 +1123,31 @@ features to produce new behaviours.
|
|||
update_hash: True if hash should be updated, False if not
|
||||
"""
|
||||
self.update_hash = update_hash
|
||||
|
||||
def collect_contents_to_file(self, entries, prefix):
|
||||
"""Put the contents of a list of entries into a file
|
||||
|
||||
Args:
|
||||
entries (list of Entry): Entries to collect
|
||||
prefix (str): Filename prefix of file to write to
|
||||
|
||||
If any entry does not have contents yet, this function returns False
|
||||
for the data.
|
||||
|
||||
Returns:
|
||||
Tuple:
|
||||
bytes: Concatenated data from all the entries (or False)
|
||||
str: Filename of file written (or False if no data)
|
||||
str: Unique portion of filename (or False if no data)
|
||||
"""
|
||||
data = b''
|
||||
for entry in entries:
|
||||
# First get the input data and put it in a file. If not available,
|
||||
# try later.
|
||||
if not entry.ObtainContents():
|
||||
return False, False, False
|
||||
data += entry.GetData()
|
||||
uniq = self.GetUniqueName()
|
||||
fname = tools.get_output_filename(f'{prefix}.{uniq}')
|
||||
tools.write_file(fname, data)
|
||||
return data, fname, uniq
|
||||
|
|
|
@ -51,16 +51,10 @@ class Entry_mkimage(Entry):
|
|||
self.ReadEntries()
|
||||
|
||||
def ObtainContents(self):
|
||||
data = b''
|
||||
for entry in self._mkimage_entries.values():
|
||||
# First get the input data and put it in a file. If not available,
|
||||
# try later.
|
||||
if not entry.ObtainContents():
|
||||
return False
|
||||
data += entry.GetData()
|
||||
uniq = self.GetUniqueName()
|
||||
input_fname = tools.get_output_filename('mkimage.%s' % uniq)
|
||||
tools.write_file(input_fname, data)
|
||||
data, input_fname, uniq = self.collect_contents_to_file(
|
||||
self._mkimage_entries.values(), 'mkimage')
|
||||
if data is False:
|
||||
return False
|
||||
output_fname = tools.get_output_filename('mkimage-out.%s' % uniq)
|
||||
if self.mkimage.run_cmd('-d', input_fname, *self._args,
|
||||
output_fname) is not None:
|
||||
|
|
Loading…
Reference in a new issue