From: Alice Guo <alice....@nxp.com>

To support passing specific commands defined in enum imx8image_cmd to
the imx8image_copy_image() function, this patch introduces a new entry
type nxp-imx9image. This entry generates a plain text data file
containing the relevant commands, enabling flexible configuration during
image creation.

Signed-off-by: Alice Guo <alice....@nxp.com>
---
 tools/binman/entries.rst            | 12 ++++++
 tools/binman/etype/nxp_imx9image.py | 77 +++++++++++++++++++++++++++++++++++++
 tools/binman/ftest.py               |  8 ++++
 tools/binman/test/350_nxp_imx95.dts | 22 +++++++++++
 4 files changed, 119 insertions(+)

diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
index 12a39d070e4..8922d6cd070 100644
--- a/tools/binman/entries.rst
+++ b/tools/binman/entries.rst
@@ -1689,6 +1689,18 @@ together. See imx95_evk.rst for how to get DDR PHY 
Firmware Images.
 
 
 
+.. _etype_nxp_imx9image:
+
+Entry: nxp_imx9image: data file generator and mkimage invocation
+-----------------------------------------------------------------------------
+
+This entry is used to generate a data file that is passed to mkimage with the 
-n
+option. Each line in this data file represents a command defined in the enum
+imx8image_cmd. The imx8image_copy_image() function parses all commands and
+constructs a .bin file accordingly.
+
+
+
 .. _etype_opensbi:
 
 Entry: opensbi: RISC-V OpenSBI fw_dynamic blob
diff --git a/tools/binman/etype/nxp_imx9image.py 
b/tools/binman/etype/nxp_imx9image.py
new file mode 100644
index 00000000000..e82f82b5129
--- /dev/null
+++ b/tools/binman/etype/nxp_imx9image.py
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2025 NXP
+
+import os
+from binman.etype.mkimage import Entry_mkimage
+from dtoc import fdt_util
+from u_boot_pylib import tools
+
+class Entry_nxp_imx9image(Entry_mkimage):
+    """NXP i.MX9 .bin configuration file generator and mkimage invocation
+
+    Properties arguments:
+        - append: appends the specified blob file as-is
+        - boot-from: indicates the boot device to be used
+        - cntr-version: sets the image container format version
+        - container: indicates that it is a new container
+        - dummy-ddr: specifies the memory address for storing the DDR training
+                     data image
+        - dummy-v2x: specifies the memory address for storing V2X firmware
+        - hold: reserves a specified number of bytes after the previous image
+        - image: defines the option type, image filename, and the memory 
address
+                 where the image will be stored
+        - soc-type: specifies the target SoC for which the .bin file is 
generated
+    """
+
+    def __init__(self, section, etype, node):
+        super().__init__(section, etype, node)
+        self.config_filename = None
+
+    def ReadNode(self):
+        super().ReadNode()
+        cfg_path = fdt_util.GetString(self._node, 'cfg-path')
+        self.config_filename = tools.get_output_filename(cfg_path)
+        accepted_keys = [
+            'append', 'boot-from', 'cntr-version', 'container', 'dummy-ddr',
+            'dummy-v2x', 'hold', 'image', 'soc-type'
+        ]
+
+        with open(self.config_filename, 'w', encoding='utf-8') as f:
+            for prop in self._node.props.values():
+                key = prop.name
+                value = prop.value
+
+                if not any(key.startswith(prefix) for prefix in accepted_keys):
+                    continue
+
+                formatted_key = key.replace('-', '_')
+
+                if key.startswith('image') and isinstance(value, list) and 
len(value) == 3:
+                    image_path = os.path.join(tools.get_output_dir(), value[1])
+                    value[1] = image_path
+
+                    combined = ' '.join(map(str, value))
+                    f.write(f'image {combined}\n')
+                elif isinstance(value, str):
+                    f.write(f'{formatted_key} {value}\n')
+                elif isinstance(value, bool):
+                    f.write(f'{formatted_key}\n')
+                elif isinstance(value, bytes):
+                    hex_value = hex(int.from_bytes(value, byteorder='big'))
+                    f.write(f'{formatted_key} {hex_value}\n')
+
+    def BuildSectionData(self, required):
+        data, input_fname, uniq = 
self.collect_contents_to_file(self._entries.values(), 'imx9image')
+
+        outfile = f'imx9image-out.{uniq}'
+        output_fname = tools.get_output_filename(outfile)
+
+        args = [
+            '-d', input_fname, '-n', self.config_filename, '-T', 'imx8image',
+            output_fname
+        ]
+
+        result = self.mkimage.run_cmd(*args)
+        if result is not None and os.path.exists(output_fname):
+            return tools.read_file(output_fname)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index a90db3c9351..f0e45c977fd 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -7906,6 +7906,14 @@ fdt         fdtmap                Extract the devicetree 
blob from the fdtmap
                          len(IMX_LPDDR_DMEM_DATA).to_bytes(4, 'little') +
                          IMX_LPDDR_IMEM_DATA + IMX_LPDDR_DMEM_DATA, data)
 
+    def testNxpImx9Image(self):
+        """Test that binman can generate a .bin file"""
+        testdir = tempfile.mkdtemp(prefix='binman.')
+        image_path = os.path.join(testdir, 'image.bin')
+        with open(image_path, 'w') as f:
+            pass
+        self._DoTestFile('350_nxp_imx95.dts', output_dir=testdir)
+
     def testFitSignSimple(self):
         """Test that image with FIT and signature nodes can be signed"""
         if not elf.ELF_TOOLS:
diff --git a/tools/binman/test/350_nxp_imx95.dts 
b/tools/binman/test/350_nxp_imx95.dts
new file mode 100644
index 00000000000..be7e2c447b0
--- /dev/null
+++ b/tools/binman/test/350_nxp_imx95.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       binman {
+               u-boot {
+                       type = "nxp-imx9image";
+                       cfg-path = "u-boot-container.cfgout";
+                       args;
+
+                       cntr-version = <2>;
+                       boot-from = "sd";
+                       soc-type = "IMX9";
+                       container;
+                       image = "a55", "image.bin", "0x90200000";
+               };
+       };
+};

-- 
2.43.0

Reply via email to