[RFC PATCH v2 1/8] binman: mkimage: Support ':'-separated inputs

Andrew Abbott
2022-05-16T11:08:36Z

mkimage supports combining multiple input binaries separating them
with colons (':'). This is used at least for Rockchip platforms to
encode payload offsets and sizes in the image header. It is required for
Rockchip SPI boot since for the rkspi format, after the input binary
combining, the entire image is spread across only the first 2K bytes of
each 4K block.

Previous to this change, multiple inputs to a binman mkimage node would
just be concatenated and the combined input would be passed as the -d
argument to mkimage. Now, the inputs are instead passed colon-separated.

Signed-off-by: Andrew Abbott <andrew@mirx.dev>
---
This is a bit of a messy implementation for now and would probably break
existing uses of mkimage that rely on the concatenation behaviour.

Questions:
- Should this be a separate entry type, or an option to the mkimage
entry type that enables this behaviour?
- What kind of test(s) should I add?

(no changes since v1)

tools/binman/etype/mkimage.py | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)

diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index 5f6def2287..8cea618fbd 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -51,21 +51,30 @@ class Entry_mkimage(Entry):
self.ReadEntries()

def ObtainContents(self):
- # Use a non-zero size for any fake files to keep mkimage happy
- data, input_fname, uniq = self.collect_contents_to_file(
- self._mkimage_entries.values(), 'mkimage', 1024)
- if data is None:
- 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:
+ # For multiple inputs to mkimage, we want to separate them by colons.
+ # This is needed for eg. the rkspi format, which treats the first data
+ # file as the "init" and the second as "boot" and sets the image header
+ # accordingly, then makes the image so that only the first 2 KiB of each
+ # 4KiB block is used.
+
+ data_filenames = []
+ for entry in self._mkimage_entries.values():
+ # First get the input data and put it in a file. If any entry is not
+ # available, try later.
+ if not entry.ObtainContents():
+ return False
+
+ input_fname = tools.get_output_filename('mkimage-in.%s' % entry.GetUniqueName())
+ data_filenames.append(input_fname)
+ tools.write_file(input_fname, entry.GetData())
+
+ output_fname = tools.get_output_filename('mkimage-out.%s' % self.GetUniqueName())
+ if self.mkimage.run_cmd('-d', ":".join(data_filenames), *self._args, output_fname):
self.SetContents(tools.read_file(output_fname))
+ return True
else:
- # Bintool is missing; just use the input data as the output
self.record_missing_bintool(self.mkimage)
- self.SetContents(data)
-
- return True
+ return False

def ReadEntries(self):
"""Read the subnodes to find out what should go in this image"""
--
2.36.0