[PATCH v2 6/6] binman: Support templates containing phandles

Simon Glass sjg at chromium.org
Sun Jul 23 05:43:57 CEST 2023


This provides support for phandles to be copied over from templates. This
is not quite safe, since if the template is instantiated twice (i.e. in
two different nodes), then duplicate phandles will be found. This will
result in an error.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Refine support for phandles to deal with duplicates
- Add a test that deals with duplicate phandles

 tools/binman/binman.rst                       | 18 +++++
 tools/binman/control.py                       |  4 ++
 tools/binman/ftest.py                         | 27 ++++++++
 tools/binman/test/291_template_phandle.dts    | 51 +++++++++++++++
 .../binman/test/292_template_phandle_dup.dts  | 65 +++++++++++++++++++
 5 files changed, 165 insertions(+)
 create mode 100644 tools/binman/test/291_template_phandle.dts
 create mode 100644 tools/binman/test/292_template_phandle_dup.dts

diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst
index 147fbc5ff1b9..aeea33fddb95 100644
--- a/tools/binman/binman.rst
+++ b/tools/binman/binman.rst
@@ -1264,6 +1264,24 @@ The initial devicetree produced by the templating process is written to the
 a failure before the final `u-boot.dtb.out` file is written. A second
 `u-boot.dtb.tmpl2` file is written when the templates themselves are removed.
 
+Dealing with phandles
+---------------------
+
+Templates can contain phandles and these are copied to the destination node.
+However this should be used with care, since if a template is instantiated twice
+then the phandle will be copied twice, resulting in a devicetree with duplicate
+phandles, i.e. the same phandle used by two different nodes. Binman detects this
+situation and produces an error, for example::
+
+  Duplicate phandle 1 in nodes /binman/image/fit/images/atf/atf-bl31 and
+  /binman/image-2/fit/images/atf/atf-bl31
+
+In this case an atf-bl31 node containing a phandle has been copied into two
+different target nodes, resulting in the same phandle for each. See
+testTemplatePhandleDup() for the test case.
+
+The solution is typically to put the phandles in the corresponding target nodes
+(one for each) and remove the phandle from the template.
 
 Updating an ELF file
 ====================
diff --git a/tools/binman/control.py b/tools/binman/control.py
index 3857f50e6436..6a6d247e6969 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -567,6 +567,10 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded):
 
         _RemoveTemplates(node)
         dtb.Sync(True)
+
+        # Rescan the dtb to pick up the new phandles
+        dtb.Scan()
+        node = _FindBinmanNode(dtb)
         fname = tools.get_output_filename('u-boot.dtb.tmpl2')
         tools.write_file(fname, dtb.GetContents())
 
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 7ea4797ad6ac..5a2cf9baf9cf 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -6900,6 +6900,33 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
             # Move to next
             spl_data = content[:0x18]
 
+    def testTemplatePhandle(self):
+        """Test using a template in a node containing a phandle"""
+        entry_args = {
+            'atf-bl31-path': 'bl31.elf',
+        }
+        data = self._DoReadFileDtb('291_template_phandle.dts',
+                                   entry_args=entry_args)
+        fname = tools.get_output_filename('image.bin')
+        out = tools.run('dumpimage', '-l', fname)
+
+        # We should see the FIT description and one for each of the two images
+        lines = out.splitlines()
+        descs = [line.split()[-1] for line in lines if 'escription' in line]
+        self.assertEqual(['test-desc', 'atf', 'fdt'], descs)
+
+    def testTemplatePhandleDup(self):
+        """Test using a template in a node containing a phandle"""
+        entry_args = {
+            'atf-bl31-path': 'bl31.elf',
+        }
+        with self.assertRaises(ValueError) as e:
+            self._DoReadFileDtb('292_template_phandle_dup.dts',
+                                entry_args=entry_args)
+        self.assertIn(
+            'Duplicate phandle 1 in nodes /binman/image/fit/images/atf/atf-bl31 and /binman/image-2/fit/images/atf/atf-bl31',
+            str(e.exception))
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/291_template_phandle.dts b/tools/binman/test/291_template_phandle.dts
new file mode 100644
index 000000000000..c4ec1dd41bed
--- /dev/null
+++ b/tools/binman/test/291_template_phandle.dts
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		multiple-images;
+
+		ti_spl_template: template-1 {
+			fit {
+				description = "test-desc";
+				#address-cells = <1>;
+				images {
+					atf {
+						description = "atf";
+						ti-secure {
+							type = "collection";
+							content = <&atf>;
+							keyfile = "key.pem";
+						};
+						atf: atf-bl31 {
+							description = "atf";
+						};
+					};
+				};
+			};
+		};
+
+		image {
+			insert-template = <&ti_spl_template>;
+			fit {
+				images {
+					fdt-0 {
+						description = "fdt";
+						ti-secure {
+							type = "collection";
+							content = <&foo_dtb>;
+							keyfile = "key.pem";
+						};
+						foo_dtb: blob-ext {
+							filename = "vga.bin";
+						};
+					};
+				};
+			};
+		};
+	};
+};
diff --git a/tools/binman/test/292_template_phandle_dup.dts b/tools/binman/test/292_template_phandle_dup.dts
new file mode 100644
index 000000000000..dc86f06463b7
--- /dev/null
+++ b/tools/binman/test/292_template_phandle_dup.dts
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		multiple-images;
+
+		ti_spl_template: template-1 {
+			fit {
+				description = "test-desc";
+				#address-cells = <1>;
+				images {
+					atf {
+						description = "atf";
+						ti-secure {
+							type = "collection";
+							content = <&atf>;
+							keyfile = "key.pem";
+						};
+						atf: atf-bl31 {
+							description = "atf";
+						};
+					};
+				};
+			};
+		};
+
+		image {
+			insert-template = <&ti_spl_template>;
+			fit {
+				images {
+					fdt-0 {
+						description = "fdt";
+						ti-secure {
+							type = "collection";
+							content = <&foo_dtb>;
+							keyfile = "key.pem";
+						};
+						foo_dtb: blob-ext {
+							filename = "vga.bin";
+						};
+					};
+				};
+			};
+		};
+
+		image-2 {
+			insert-template = <&ti_spl_template>;
+			fit {
+				images {
+					fdt-0 {
+						description = "fdt";
+						blob-ext {
+							filename = "vga.bin";
+						};
+					};
+				};
+			};
+		};
+	};
+};
-- 
2.41.0.487.g6d72f3e995-goog



More information about the U-Boot mailing list