[PATCH v3 19/19] binman: Support writing symbols inside a mkimage image
Simon Glass
sjg at chromium.org
Mon Jul 10 04:41:17 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>
---
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