[PATCH v7 1/8] binman: add support for skipping file concatenation for mkimage

Quentin Schulz foss+uboot at 0leil.net
Fri Sep 2 15:10:48 CEST 2022


From: Quentin Schulz <quentin.schulz at theobroma-systems.com>

Some image types handled by mkimage require the datafiles to be passed
independently (-d data1:data2) for specific handling of each. A
concatenation of datafiles prior to passing them to mkimage wouldn't
work.

That is the case for rkspi for example which requires page alignment
and only writing 2KB every 4KB.

This adds the ability to tell binman to pass the datafiles without
prior concatenation to mkimage, by adding the multiple-data-files
boolean property to the mkimage node.

Cc: Quentin Schulz <foss+uboot at 0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
Reviewed-by: Simon Glass <sjg at chromium.org>
---

v6:
 - added Rb,
 - put tests at the end of the file,
 - added test for multiple data files passed to mkimage with one data
 file having no content (thanks Simon for the suggestion),
 - added SPDX license to test files,
 - renumbered test files,

v5:
 - changed to use full path from input dir with tools.get_input_filename
 to make it possible to run the unit tests,
 - added unit test,

 tools/binman/entries.rst                      | 22 ++++++++++
 tools/binman/etype/mkimage.py                 | 41 +++++++++++++++++--
 tools/binman/ftest.py                         | 23 +++++++++++
 tools/binman/test/252_mkimage_mult_data.dts   | 21 ++++++++++
 .../test/253_mkimage_mult_no_content.dts      | 22 ++++++++++
 5 files changed, 125 insertions(+), 4 deletions(-)
 create mode 100644 tools/binman/test/252_mkimage_mult_data.dts
 create mode 100644 tools/binman/test/253_mkimage_mult_no_content.dts

diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index b3613d7cbd..18bd328c5c 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -1175,6 +1175,9 @@ Properties / Entry arguments:
     - args: Arguments to pass
     - data-to-imagename: Indicates that the -d data should be passed in as
       the image name also (-n)
+    - multiple-data-files: boolean to tell binman to pass all files as
+      datafiles to mkimage instead of creating a temporary file the result
+      of datafiles concatenation
 
 The data passed to mkimage via the -d flag is collected from subnodes of the
 mkimage node, e.g.::
@@ -1205,6 +1208,25 @@ a section, or just multiple subnodes like this::
         };
     };
 
+To pass all datafiles untouched to mkimage::
+
+    mkimage {
+        args = "-n rk3399 -T rkspi";
+        multiple-data-files;
+
+        u-boot-tpl {
+        };
+
+        u-boot-spl {
+        };
+    };
+
+This calls mkimage to create a Rockchip RK3399-specific first stage
+bootloader, made of TPL+SPL. Since this first stage bootloader requires to
+align the TPL and SPL but also some weird hacks that is handled by mkimage
+directly, binman is told to not perform the concatenation of datafiles prior
+to passing the data to mkimage.
+
 To use CONFIG options in the arguments, use a string list instead, as in
 this example which also produces four arguments::
 
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index ddbd9cec65..5f4bc6fa3c 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -18,6 +18,9 @@ class Entry_mkimage(Entry):
         - args: Arguments to pass
         - data-to-imagename: Indicates that the -d data should be passed in as
           the image name also (-n)
+        - multiple-data-files: boolean to tell binman to pass all files as
+          datafiles to mkimage instead of creating a temporary file the result
+          of datafiles concatenation
 
     The data passed to mkimage via the -d flag is collected from subnodes of the
     mkimage node, e.g.::
@@ -51,6 +54,25 @@ class Entry_mkimage(Entry):
     Note that binman places the contents (here SPL and TPL) into a single file
     and passes that to mkimage using the -d option.
 
+	To pass all datafiles untouched to mkimage::
+
+		mkimage {
+			args = "-n rk3399 -T rkspi";
+			multiple-data-files;
+
+			u-boot-tpl {
+			};
+
+			u-boot-spl {
+			};
+		};
+
+	This calls mkimage to create a Rockchip RK3399-specific first stage
+	bootloader, made of TPL+SPL. Since this first stage bootloader requires to
+	align the TPL and SPL but also some weird hacks that is handled by mkimage
+	directly, binman is told to not perform the concatenation of datafiles prior
+	to passing the data to mkimage.
+
     To use CONFIG options in the arguments, use a string list instead, as in
     this example which also produces four arguments::
 
@@ -96,6 +118,7 @@ class Entry_mkimage(Entry):
     """
     def __init__(self, section, etype, node):
         super().__init__(section, etype, node)
+        self._multiple_data_files = fdt_util.GetBool(self._node, 'multiple-data-files')
         self._mkimage_entries = OrderedDict()
         self._imagename = None
         self.align_default = None
@@ -122,10 +145,20 @@ class Entry_mkimage(Entry):
     def ObtainContents(self):
         # Use a non-zero size for any fake files to keep mkimage happy
         # Note that testMkimageImagename() relies on this 'mkimage' parameter
-        data, input_fname, uniq = self.collect_contents_to_file(
-            self._mkimage_entries.values(), 'mkimage', 1024)
-        if data is None:
-            return False
+        fake_size = 1024
+        if self._multiple_data_files:
+            fnames = []
+            uniq = self.GetUniqueName()
+            for entry in self._mkimage_entries.values():
+                if not entry.ObtainContents(fake_size=fake_size):
+                    return False
+                fnames.append(tools.get_input_filename(entry.GetDefaultFilename()))
+            input_fname = ":".join(fnames)
+        else:
+            data, input_fname, uniq = self.collect_contents_to_file(
+                self._mkimage_entries.values(), 'mkimage', fake_size)
+            if data is None:
+                return False
         if self._imagename:
             image_data, imagename_fname, _ = self.collect_contents_to_file(
                 [self._imagename], 'mkimage-n', 1024)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 5422940e07..e0850b760b 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5898,6 +5898,29 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
         self.assertIn("Node '/binman/u-boot-dtb': The zstd compression "
                       "requires a length header", str(e.exception))
 
+    def testMkimageMultipleDataFiles(self):
+        """Test passing multiple files to mkimage in a mkimage entry"""
+        data = self._DoReadFile('252_mkimage_mult_data.dts')
+        # Size of files are packed in their 4B big-endian format
+        expect = struct.pack('>I', len(U_BOOT_TPL_DATA))
+        expect += struct.pack('>I', len(U_BOOT_SPL_DATA))
+        # Size info is always followed by a 4B zero value.
+        expect += tools.get_bytes(0, 4)
+        expect += U_BOOT_TPL_DATA
+        # All but last files are 4B-aligned
+        align_pad = len(U_BOOT_TPL_DATA) % 4
+        if align_pad:
+            expect += tools.get_bytes(0, align_pad)
+        expect += U_BOOT_SPL_DATA
+        self.assertEqual(expect, data[-len(expect):])
+
+    def testMkimageMultipleNoContent(self):
+        """Test passing multiple data files to mkimage with one data file having no content"""
+        with self.assertRaises(ValueError) as exc:
+            self._DoReadFile('253_mkimage_mult_no_content.dts')
+        self.assertIn('Could not complete processing of contents',
+                      str(exc.exception))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/252_mkimage_mult_data.dts b/tools/binman/test/252_mkimage_mult_data.dts
new file mode 100644
index 0000000000..a092bc39bf
--- /dev/null
+++ b/tools/binman/test/252_mkimage_mult_data.dts
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		mkimage {
+			args = "-T script";
+			multiple-data-files;
+
+			u-boot-tpl {
+			};
+
+			u-boot-spl {
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/253_mkimage_mult_no_content.dts b/tools/binman/test/253_mkimage_mult_no_content.dts
new file mode 100644
index 0000000000..dd65666c62
--- /dev/null
+++ b/tools/binman/test/253_mkimage_mult_no_content.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		mkimage {
+			args = "-T script";
+			multiple-data-files;
+
+			_testing {
+				return-unknown-contents;
+			};
+
+			u-boot-spl {
+			};
+		};
+	};
+};
-- 
2.37.2



More information about the U-Boot mailing list