On 07.07.23 19:35, Simon Glass wrote: > Hi Jan, > > On Fri, 7 Jul 2023 at 17:03, Jan Kiszka <jan.kis...@siemens.com> wrote: >> >> On 07.07.23 17:35, Simon Glass wrote: >>> Hi Jan, >>> >>> On Fri, 7 Jul 2023 at 14:56, Jan Kiszka <jan.kis...@siemens.com> wrote: >>>> >>>> On 07.07.23 14:42, Simon Glass wrote: >>>>> Hi Jan, >>>>> >>>>> On Fri, 7 Jul 2023 at 11:05, Jan Kiszka <jan.kis...@siemens.com> wrote: >>>>>> >>>>>> On 05.07.23 00:14, Simon Glass wrote: >>>>>>> Hi Jan, >>>>>>> >>>>>>> On Mon, 3 Jul 2023 at 20:34, Jan Kiszka <jan.kis...@siemens.com> wrote: >>>>>>>> >>>>>>>> Hi Simon, >>>>>>>> >>>>>>>> On 28.06.23 13:41, Simon Glass wrote: >>>>>>>>> Collections can used to collect the contents of other entries into a >>>>>>>>> single entry, but they result in a single entry, with the original >>>>>>>>> entries >>>>>>>>> 'left behind' in their old place. >>>>>>>>> >>>>>>>>> It is useful to be able to specific a set of entries ones and have it >>>>>>>>> used >>>>>>>>> in multiple images, or parts of an image. >>>>>>>>> >>>>>>>>> Implement this mechanism. >>>>>>>>> >>>>>>>>> Signed-off-by: Simon Glass <s...@chromium.org> >>>>>>>>> --- >>>>>>>>> >>>>>>>>> tools/binman/binman.rst | 80 >>>>>>>>> ++++++++++++++++++++++++ >>>>>>>>> tools/binman/control.py | 9 +++ >>>>>>>>> tools/binman/etype/section.py | 3 +- >>>>>>>>> tools/binman/ftest.py | 8 +++ >>>>>>>>> tools/binman/test/286_entry_template.dts | 42 +++++++++++++ >>>>>>>>> 5 files changed, 141 insertions(+), 1 deletion(-) >>>>>>>>> create mode 100644 tools/binman/test/286_entry_template.dts >>>>>>>>> >>>>>>>>> diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst >>>>>>>>> index a4b31fe5397b..9be979ae1c5b 100644 >>>>>>>>> --- a/tools/binman/binman.rst >>>>>>>>> +++ b/tools/binman/binman.rst >>>>>>>>> @@ -727,6 +727,13 @@ optional: >>>>>>>>> Note that missing, optional blobs do not produce a non-zero exit >>>>>>>>> code from >>>>>>>>> binman, although it does show a warning about the missing >>>>>>>>> external blob. >>>>>>>>> >>>>>>>>> +insert-template: >>>>>>>>> + This is not strictly speaking an entry property, since it is >>>>>>>>> processed early >>>>>>>>> + in Binman before the entries are read. It is a list of phandles >>>>>>>>> of nodes to >>>>>>>>> + include in the current (target) node. For each node, its >>>>>>>>> subnodes and their >>>>>>>>> + properties are brought into the target node. See Templates_ >>>>>>>>> below for >>>>>>>>> + more information. >>>>>>>>> + >>>>>>>>> The attributes supported for images and sections are described >>>>>>>>> below. Several >>>>>>>>> are similar to those for entries. >>>>>>>>> >>>>>>>>> @@ -1172,6 +1179,79 @@ If you are having trouble figuring out what is >>>>>>>>> going on, you can use >>>>>>>>> arch/arm/dts/u-boot.dtsi ... found: >>>>>>>>> "arch/arm/dts/juno-r2-u-boot.dtsi" >>>>>>>>> >>>>>>>>> >>>>>>>>> +Templates >>>>>>>>> +========= >>>>>>>>> + >>>>>>>>> +Sometimes multiple images need to be created which have all have a >>>>>>>>> common >>>>>>>>> +part. For example, a board may generate SPI and eMMC images which >>>>>>>>> both include >>>>>>>>> +a FIT. Since the FIT includes many entries, it is tedious to repeat >>>>>>>>> them twice >>>>>>>>> +in the image description. >>>>>>>>> + >>>>>>>>> +Templates provide a simple way to handle this:: >>>>>>>>> + >>>>>>>>> + binman { >>>>>>>>> + multiple-images; >>>>>>>>> + common_part: template-1 { >>>>>>>>> + fit { >>>>>>>>> + ... lots of entries in here >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + text { >>>>>>>>> + text = "base image"; >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + spi-image { >>>>>>>>> + filename = "image-spi.bin"; >>>>>>>>> + insert-template = <&fit>; >>>>>>>>> + >>>>>>>>> + /* things specific to SPI follow */ >>>>>>>>> + header { >>>>>>>>> + ]; >>>>>>>>> + >>>>>>>>> + text { >>>>>>>>> + text = "SPI image"; >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + mmc-image { >>>>>>>>> + filename = "image-mmc.bin"; >>>>>>>>> + insert-template = <&fit>; >>>>>>>>> + >>>>>>>>> + /* things specific to MMC follow */ >>>>>>>>> + header { >>>>>>>>> + ]; >>>>>>>>> + >>>>>>>>> + text { >>>>>>>>> + text = "MMC image"; >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> +The template node name must start with 'template', so it is not >>>>>>>>> considered to be >>>>>>>>> +an image itself. >>>>>>>>> + >>>>>>>>> +The mechanism is very simple. For each phandle in the >>>>>>>>> 'insert-templates' >>>>>>>>> +property, the source node is looked up. Then the subnodes of that >>>>>>>>> source node >>>>>>>>> +are copied into the target node, i.e. the one containing the >>>>>>>>> `insert-template` >>>>>>>>> +property. >>>>>>>>> + >>>>>>>>> +If the target node has a node with the same name as a template, its >>>>>>>>> properties >>>>>>>>> +override corresponding properties in the template. This allows the >>>>>>>>> template to >>>>>>>>> +be uses as a base, with the node providing updates to the properties >>>>>>>>> as needed. >>>>>>>>> +The overriding happens recursively. >>>>>>>>> + >>>>>>>>> +At present there is an unpleasant limitation on this feature: it >>>>>>>>> works by >>>>>>>>> +appending the template nodes after any existing subnodes to the >>>>>>>>> target node. >>>>>>>>> +This means that if the target node includes any subnodes, these >>>>>>>>> appear in order >>>>>>>>> +before the template node. In the above example, 'header' becomes the >>>>>>>>> first >>>>>>>>> +subnode of each image, followed by `fit` and `text`. If this is not >>>>>>>>> what is >>>>>>>>> +desired, there is no way to adjust it. >>>>>>>>> + >>>>>>>>> +Note: The above limitation will likely be removed in future, so that >>>>>>>>> the >>>>>>>>> +template subnodes appear before the target subnodes. >>>>>>>>> + >>>>>>>>> + >>>>>>>>> Updating an ELF file >>>>>>>>> ==================== >>>>>>>>> >>>>>>>>> diff --git a/tools/binman/control.py b/tools/binman/control.py >>>>>>>>> index 68597c4e7792..e7faca78e9aa 100644 >>>>>>>>> --- a/tools/binman/control.py >>>>>>>>> +++ b/tools/binman/control.py >>>>>>>>> @@ -22,6 +22,7 @@ from binman import bintool >>>>>>>>> from binman import cbfs_util >>>>>>>>> from binman import elf >>>>>>>>> from binman import entry >>>>>>>>> +from dtoc import fdt_util >>>>>>>>> from u_boot_pylib import command >>>>>>>>> from u_boot_pylib import tools >>>>>>>>> from u_boot_pylib import tout >>>>>>>>> @@ -478,6 +479,12 @@ def SignEntries(image_fname, input_fname, >>>>>>>>> privatekey_fname, algo, entry_paths, >>>>>>>>> >>>>>>>>> AfterReplace(image, allow_resize=True, write_map=write_map) >>>>>>>>> >>>>>>>>> +def _ProcessTemplates(parent): >>>>>>>>> + for node in parent.subnodes: >>>>>>>>> + tmpl = fdt_util.GetPhandleList(node, 'insert-template') >>>>>>>>> + if tmpl: >>>>>>>>> + node.copy_subnodes_from_phandles(tmpl) >>>>>>>>> + >>>>>>>>> def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, >>>>>>>>> use_expanded): >>>>>>>>> """Prepare the images to be processed and select the device tree >>>>>>>>> >>>>>>>>> @@ -520,6 +527,8 @@ def PrepareImagesAndDtbs(dtb_fname, >>>>>>>>> select_images, update_fdt, use_expanded): >>>>>>>>> raise ValueError("Device tree '%s' does not have a 'binman' " >>>>>>>>> "node" % dtb_fname) >>>>>>>>> >>>>>>>>> + _ProcessTemplates(node) >>>>>>>>> + >>>>>>>>> images = _ReadImageDesc(node, use_expanded) >>>>>>>>> >>>>>>>>> if select_images: >>>>>>>>> diff --git a/tools/binman/etype/section.py >>>>>>>>> b/tools/binman/etype/section.py >>>>>>>>> index d56cc11d1023..adac2ff7fa87 100644 >>>>>>>>> --- a/tools/binman/etype/section.py >>>>>>>>> +++ b/tools/binman/etype/section.py >>>>>>>>> @@ -179,7 +179,8 @@ class Entry_section(Entry): >>>>>>>>> Returns: >>>>>>>>> bool: True if the node is a special one, else False >>>>>>>>> """ >>>>>>>>> - return node.name.startswith('hash') or >>>>>>>>> node.name.startswith('signature') >>>>>>>>> + start_list = ('hash', 'signature', 'template') >>>>>>>>> + return any(node.name.startswith(name) for name in start_list) >>>>>>>>> >>>>>>>>> def ReadNode(self): >>>>>>>>> """Read properties from the section node""" >>>>>>>>> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py >>>>>>>>> index 4db54c69682c..9d9e47ce26b0 100644 >>>>>>>>> --- a/tools/binman/ftest.py >>>>>>>>> +++ b/tools/binman/ftest.py >>>>>>>>> @@ -6763,6 +6763,14 @@ fdt fdtmap Extract the >>>>>>>>> devicetree blob from the fdtmap >>>>>>>>> data = self._DoReadFileDtb('285_spl_expand.dts', >>>>>>>>> use_expanded=True, >>>>>>>>> entry_args=entry_args)[0] >>>>>>>>> >>>>>>>>> + def testEntryTemplate(self): >>>>>>>>> + """Test using a template""" >>>>>>>>> + TestFunctional._MakeInputFile('vga2.bin', b'#' + VGA_DATA) >>>>>>>>> + data = self._DoReadFile('286_entry_template.dts') >>>>>>>>> + first = U_BOOT_DTB_DATA + U_BOOT_DATA + VGA_DATA >>>>>>>>> + second = U_BOOT_DTB_DATA + b'#' + VGA_DATA + U_BOOT_DATA >>>>>>>>> + self.assertEqual(U_BOOT_IMG_DATA + first + second, data) >>>>>>>>> + >>>>>>>>> >>>>>>>>> if __name__ == "__main__": >>>>>>>>> unittest.main() >>>>>>>>> diff --git a/tools/binman/test/286_entry_template.dts >>>>>>>>> b/tools/binman/test/286_entry_template.dts >>>>>>>>> new file mode 100644 >>>>>>>>> index 000000000000..6980dbfafcc6 >>>>>>>>> --- /dev/null >>>>>>>>> +++ b/tools/binman/test/286_entry_template.dts >>>>>>>>> @@ -0,0 +1,42 @@ >>>>>>>>> +// SPDX-License-Identifier: GPL-2.0+ >>>>>>>>> + >>>>>>>>> +/dts-v1/; >>>>>>>>> + >>>>>>>>> +/ { >>>>>>>>> + #address-cells = <1>; >>>>>>>>> + #size-cells = <1>; >>>>>>>>> + >>>>>>>>> + binman { >>>>>>>>> + u-boot-img { >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + common_part: template { >>>>>>>>> + u-boot { >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + intel-vga { >>>>>>>>> + filename = "vga.bin"; >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + first { >>>>>>>>> + type = "section"; >>>>>>>>> + insert-template = <&common_part>; >>>>>>>>> + >>>>>>>>> + u-boot-dtb { >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + second { >>>>>>>>> + type = "section"; >>>>>>>>> + insert-template = <&common_part>; >>>>>>>>> + >>>>>>>>> + u-boot-dtb { >>>>>>>>> + }; >>>>>>>>> + >>>>>>>>> + intel-vga { >>>>>>>>> + filename = "vga2.bin"; >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> + }; >>>>>>>>> +}; >>>>>>>> >>>>>>>> I tried to apply this on the IOT2050 use case, but it failed in two >>>>>>>> cases: >>>>>>>> >>>>>>>> >>>>>>>> 1. We need a template where nodes can be manipulated afterwards, thus >>>>>>>> we >>>>>>>> need anchors into those nodes. Naturally, those anchors need to get >>>>>>>> unique names so that something like this is possible: >>>>>>>> >>>>>>>> common: template { >>>>>>>> anchor: some-node { >>>>>>>> value-1 = <1>; >>>>>>>> }; >>>>>>>> }; >>>>>>>> >>>>>>>> user-a { >>>>>>>> insert-template = <&common>; >>>>>>>> }; >>>>>>>> >>>>>>>> user-b { >>>>>>>> insert-template = <&common>; >>>>>>>> }; >>>>>>>> >>>>>>>> &anchor-a { >>>>>>>> value-2 = <2>; >>>>>>>> }; >>>>>>>> >>>>>>>> &anchor-b { >>>>>>>> value-2 = <3>; >>>>>>>> }; >>>>>>> >>>>>>> Rather than using a phandle, can you not use the node name in the >>>>>>> template? For example: >>>>>>> >>>>>>> user-a { >>>>>>> insert-template = <&common>; >>>>>>> some-node { >>>>>>> value2 = <2>; >>>>>>> } >>>>>>> >>>>>>> user-b { >>>>>>> insert-template = <&common>; >>>>>>> some-node { >>>>>>> value2 = <3>; >>>>>>> } >>>>>>> >>>>>> >>>>>> I don't think this is working already. This is what I tried: >>>>>> >>>>>> /dts-v1/; >>>>>> / { >>>>>> binman: binman { >>>>>> multiple-images; >>>>>> >>>>>> my_template: template { >>>>>> blob-ext@0 { >>>>>> filename = "my-blob.bin"; >>>>>> offset = <0>; >>>>>> }; >>>>>> blob-ext@100 { >>>>>> filename = "/dev/null"; >>>>>> offset = <0x100>; >>>>>> }; >>>>>> }; >>>>>> >>>>>> my-image { >>>>>> filename = "my-image.bin"; >>>>>> insert-template = <&my_template>; >>>>>> blob-ext@100 { >>>>>> filename = "my-blob2.bin"; >>>>>> }; >>>>>> }; >>>>>> }; >>>>>> }; >>>>>> >>>>>> First, I had to apply that null filename workaround, and the overridden >>>>>> filename is taken for the final image (if I leave out blob-ext@0), but >>>>>> this is at least ugly. >>>>>> >>>>>> However, the file above as-is does not build: >>>>>> >>>>>> binman: Node '/binman/my-image/blob-ext@0': Offset 0x0 (0) overlaps with >>>>>> previous entry '/binman/my-image/blob-ext@100' ending at 0x107 (263) >>>>>> >>>>>> >>>>>> Probably for the same reason, leaving fit,fdt-list-val out in a template >>>>>> also generates an error during build. Putting an empty string there and >>>>>> overriding it later does not work. >>>>> >>>>> I think it is just that it doesn't support templating of >>>>> multiple-images nodes property. I sent a patch for this [1] >>>>> >>>>> There may be other cases too, but if you have a failure, please see if >>>>> you can adjust that test (287) to fail for you. >>>>> >>>> >>>> Hmm, already the test pattern from [1] still gives me >>>> >>>> binman: Node '/binman/image/blob-ext@0': Offset 0x0 (0) overlaps with >>>> previous entry '/binman/image/blob-ext@8' ending at 0xf (15) >>>> >>>> I've applied this series and then [1] on top. >>> >>> Can you please list the commits so I can check it? I have: >>> >>> 88a31cccc20 (HEAD -> mkim2, dm/mkim-working) binman: Support >>> templating with multiple images >>> 71f1ef46d0c (dm-public/mkim-working) binman: Support simple templates >>> 8841829b4c8 dtoc: Allow inserting a list of nodes into another >>> fd2fb91c616 dtoc: Support copying the contents of a node into another >>> 288f9e7c3b6 binman: Correct handling of zero bss size >>> 4725a43d0ef binman: Drop __bss_size variable in bss_data.c >>> c4bfe4917c9 binman: Provide a way to specific the fdt-list directly >>> 6e571e4d260 binman: Convert mkimage to Entry_section >>> 5fd2892283f stm32mp15: Avoid writing symbols in SPL >>> 24c60031f48 binman: Allow disabling symbol writing >>> 5c6a660333c binman: Read _multiple_data_files in the correct place >>> 24a273113bf binman: Use GetEntries() to obtain section contents >>> 1e0659321d8 binman: Init align_default in entry_Section >>> cc3699d1d04 binman: Correct coverage gap in control >>> 67d8b46e6ef (us/WIP/28Jun2023-next) Merge tag >>> 'u-boot-amlogic-next-20230628' of >>> https://source.denx.de/u-boot/custodians/u-boot-amlogic into next >>> >> >> I was using the dtoc patches from this series, not the updated but >> apparently not yet sent ones from your branch. Those seem to make a >> difference. Continuing to test. > > I thought I did send out v2. There are some test fails with large > numbers of CPUs which I need to fix in v3, but anyway, please use the > branch I pushed for testing, and sorry for any discrepancy. >
Doing this now. And here is the next issue - maybe the last: /dts-v1/; / { binman: binman { multiple-images; my_template: template { fit@0 { images { kernel-1 { }; kernel-2 { }; }; }; }; image { filename = "my-image.bin"; insert-template = <&my_template>; fit@0 { images { kernel-3 { }; }; }; }; }; }; Gives binman: pylibfdt error -4: FDT_ERR_BADOFFSET when trying to build it. That subnode kernel-3 can't be added. Jan -- Siemens AG, Technology Competence Center Embedded Linux