diff options
Diffstat (limited to 'tools/binman')
-rw-r--r-- | tools/binman/entries.rst | 12 | ||||
-rw-r--r-- | tools/binman/etype/nxp_imx9image.py | 89 | ||||
-rw-r--r-- | tools/binman/ftest.py | 11 | ||||
-rw-r--r-- | tools/binman/test/350_nxp_imx95.dts | 25 |
4 files changed, 137 insertions, 0 deletions
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..e0e806f2b7f --- /dev/null +++ b/tools/binman/etype/nxp_imx9image.py @@ -0,0 +1,89 @@ +# 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' + ] + external_files = ['oei-m33-tcm.bin', 'm33_image.bin', 'bl31.bin'] + + 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: + file = value[1] + image_path = os.path.join(tools.get_output_dir(), value[1]) + value[1] = image_path + combined = ' '.join(map(str, value)) + + if file in external_files and not os.path.exists(value[1]): + print(f"file '{image_path}' does not exist. flash.bin may be not-functional.") + else: + f.write(f'image {combined}\n') + elif isinstance(value, str): + if key.startswith('append'): + file_path = os.path.join(tools.get_output_dir(), value) + if os.path.exists(file_path): + f.write(f'append {file_path}\n') + else: + print(f"file '{file_path}' does not exist. flash.bin may be not-functional.") + else: + 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..925c39a530e 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -7906,6 +7906,17 @@ 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 + container_path = os.path.join(testdir, 'mx95b0-ahab-container.img') + with open(container_path, 'w') as f: + f.write(bytes([0x87]).decode('latin1') * 32768) + 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..3fc2de44b4a --- /dev/null +++ b/tools/binman/test/350_nxp_imx95.dts @@ -0,0 +1,25 @@ +// 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"; + append0 = "mx95b0-ahab-container.img"; + append1 = "container.img"; + container; + image0 = "a55", "bl31.bin", "0x8a200000"; + image1 = "a55", "image.bin", "0x90200000"; + }; + }; +}; |