[PATCH v4 19/20] binman: Support writing symbols inside a mkimage image

Simon Glass sjg at chromium.org
Tue Jul 11 16:59:21 CEST 2023


Add support for writing symbols and determining the assumed position of
binaries inside a mkimage image. This is useful as an example for other
entry types which might want to do the same thing.

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

(no changes since v3)

Changes in v3:
- Add new patch to support writing symbols inside a mkimage image

 tools/binman/entry.py                 |  2 -
 tools/binman/etype/mkimage.py         | 36 +++++++++++++++
 tools/binman/ftest.py                 | 64 +++++++++++++++++++++++++++
 tools/binman/test/290_mkimage_sym.dts | 27 +++++++++++
 4 files changed, 127 insertions(+), 2 deletions(-)
 create mode 100644 tools/binman/test/290_mkimage_sym.dts

diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 0d4cb94f7002..42e0b7b91450 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -1314,8 +1314,6 @@ features to produce new behaviours.
         """
         data = b''
         for entry in entries:
-            # First get the input data and put it in a file
-            entry.ObtainContents(fake_size=fake_size)
             data += entry.GetData()
         uniq = self.GetUniqueName()
         fname = tools.get_output_filename(f'{prefix}.{uniq}')
diff --git a/tools/binman/etype/mkimage.py b/tools/binman/etype/mkimage.py
index 493761da59f5..9d60c85722b3 100644
--- a/tools/binman/etype/mkimage.py
+++ b/tools/binman/etype/mkimage.py
@@ -268,3 +268,39 @@ class Entry_mkimage(Entry_section):
 
     def CheckEntries(self):
         pass
+
+    def ProcessContents(self):
+        # The blob may have changed due to WriteSymbols()
+        ok = super().ProcessContents()
+        data = self.BuildSectionData(True)
+        ok2 = self.ProcessContentsUpdate(data)
+        return ok and ok2
+
+    def SetImagePos(self, image_pos):
+        """Set the position in the image
+
+        This sets each subentry's offsets, sizes and positions-in-image
+        according to where they ended up in the packed mkimage file.
+
+        NOTE: This assumes a legacy mkimage and assumes that the images are
+        written to the output in order. SoC-specific mkimage handling may not
+        conform to this, in which case these values may be wrong.
+
+        Args:
+            image_pos (int): Position of this entry in the image
+        """
+        # The mkimage header consists of 0x40 bytes, following by a table of
+        # offsets for each file
+        upto = 0x40
+
+        # Skip the 0-terminated list of offsets (assume a single image)
+        upto += 4 + 4
+        for entry in self.GetEntries().values():
+            entry.SetOffsetSize(upto, None)
+
+            # Give up if any entries lack a size
+            if entry.size is None:
+                return
+            upto += entry.size
+
+        super().SetImagePos(image_pos)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index e96223cbd892..e53181afb78a 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -6820,6 +6820,70 @@ fdt         fdtmap                Extract the devicetree blob from the fdtmap
         second = U_BOOT_DATA + b'#' + VGA_DATA + U_BOOT_DTB_DATA
         self.assertEqual(U_BOOT_IMG_DATA + first + second + first, data)
 
+    def testMkimageSymbols(self):
+        """Test using mkimage to build an image with symbols in it"""
+        self._SetupSplElf('u_boot_binman_syms')
+        data = self._DoReadFile('290_mkimage_sym.dts')
+
+        image = control.images['image']
+        entries = image.GetEntries()
+        self.assertIn('u-boot', entries)
+        u_boot = entries['u-boot']
+
+        mkim = entries['mkimage']
+        mkim_entries = mkim.GetEntries()
+        self.assertIn('u-boot-spl', mkim_entries)
+        spl = mkim_entries['u-boot-spl']
+        self.assertIn('u-boot-spl2', mkim_entries)
+        spl2 = mkim_entries['u-boot-spl2']
+
+        # skip the mkimage header and the area sizes
+        mk_data = data[mkim.offset + 0x40:]
+        size, term = struct.unpack('>LL', mk_data[:8])
+
+        # There should be only one image, so check that the zero terminator is
+        # present
+        self.assertEqual(0, term)
+
+        content = mk_data[8:8 + size]
+
+        # The image should contain the symbols from u_boot_binman_syms.c
+        # Note that image_pos is adjusted by the base address of the image,
+        # which is 0x10 in our test image
+        spl_data = content[:0x18]
+        content = content[0x1b:]
+
+        # After the header is a table of offsets for each image. There should
+        # only be one image, then a 0 terminator, so figure out the real start
+        # of the image data
+        base = 0x40 + 8
+
+        # Check symbols in both u-boot-spl and u-boot-spl2
+        for i in range(2):
+            vals = struct.unpack('<LLQLL', spl_data)
+
+            # The image should contain the symbols from u_boot_binman_syms.c
+            # Note that image_pos is adjusted by the base address of the image,
+            # which is 0x10 in our 'u_boot_binman_syms' test image
+            self.assertEqual(elf.BINMAN_SYM_MAGIC_VALUE, vals[0])
+            self.assertEqual(base, vals[1])
+            self.assertEqual(spl2.offset, vals[2])
+            # figure out the internal positions of its components
+            self.assertEqual(0x10 + u_boot.image_pos, vals[3])
+
+            # Check that spl and spl2 are actually at the indicated positions
+            self.assertEqual(
+                elf.BINMAN_SYM_MAGIC_VALUE,
+                struct.unpack('<I', data[spl.image_pos:spl.image_pos + 4])[0])
+            self.assertEqual(
+                elf.BINMAN_SYM_MAGIC_VALUE,
+                struct.unpack('<I', data[spl2.image_pos:spl2.image_pos + 4])[0])
+
+            self.assertEqual(len(U_BOOT_DATA), vals[4])
+
+            # Move to next
+            spl_data = content[:0x18]
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/tools/binman/test/290_mkimage_sym.dts b/tools/binman/test/290_mkimage_sym.dts
new file mode 100644
index 000000000000..2dfd286ad44f
--- /dev/null
+++ b/tools/binman/test/290_mkimage_sym.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	binman {
+		u-boot-dtb {
+		};
+
+		mkimage {
+			args = "-n test -T script";
+
+			u-boot-spl {
+			};
+
+			u-boot-spl2 {
+				type = "u-boot-spl";
+			};
+		};
+
+		u-boot {
+		};
+	};
+};
-- 
2.41.0.390.g38632f3daf-goog



More information about the U-Boot mailing list