binman: Automatically expand phase binaries into sections
When creating an entry, check for an expanded version of that entry, then
use it instead. This allows, for example use of:
u-boot {
};
instead of having to write out in full:
u-boot {
type = "section";
u-boot-nodtb {
};
u-boot-dtb {
};
};
Add an implementaion of this and associated documentation.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 9182584..432c463 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -4285,6 +4285,180 @@
self.assertIn('Expected __bss_size symbol in tpl/u-boot-tpl',
str(e.exception))
+ def checkDtbSizes(self, data, pad_len, start):
+ """Check the size arguments in a dtb embedded in an image
+
+ Args:
+ data: The image data
+ pad_len: Length of the pad section in the image, in bytes
+ start: Start offset of the devicetree to examine, within the image
+
+ Returns:
+ Size of the devicetree in bytes
+ """
+ dtb_data = data[start:]
+ dtb = fdt.Fdt.FromData(dtb_data)
+ fdt_size = dtb.GetFdtObj().totalsize()
+ dtb.Scan()
+ props = self._GetPropTree(dtb, 'size')
+ self.assertEqual({
+ 'size': len(data),
+ 'u-boot-spl/u-boot-spl-bss-pad:size': pad_len,
+ 'u-boot-spl/u-boot-spl-dtb:size': 801,
+ 'u-boot-spl/u-boot-spl-nodtb:size': len(U_BOOT_SPL_NODTB_DATA),
+ 'u-boot-spl:size': 860,
+ 'u-boot-tpl:size': len(U_BOOT_TPL_DATA),
+ 'u-boot/u-boot-dtb:size': 781,
+ 'u-boot/u-boot-nodtb:size': len(U_BOOT_NODTB_DATA),
+ 'u-boot:size': 827,
+ }, props)
+ return fdt_size
+
+ def testExpanded(self):
+ """Test that an expanded entry type is selected when needed"""
+ self._SetupSplElf()
+ self._SetupTplElf()
+
+ # SPL has a devicetree, TPL does not
+ entry_args = {
+ 'spl-dtb': '1',
+ 'spl-bss-pad': 'y',
+ 'tpl-dtb': '',
+ }
+ self._DoReadFileDtb('194_fdt_incl.dts', use_expanded=True,
+ entry_args=entry_args)
+ image = control.images['image']
+ entries = image.GetEntries()
+ self.assertEqual(3, len(entries))
+
+ # First, u-boot, which should be expanded into u-boot-nodtb and dtb
+ self.assertIn('u-boot', entries)
+ entry = entries['u-boot']
+ self.assertEqual('u-boot-expanded', entry.etype)
+ subent = entry.GetEntries()
+ self.assertEqual(2, len(subent))
+ self.assertIn('u-boot-nodtb', subent)
+ self.assertIn('u-boot-dtb', subent)
+
+ # Second, u-boot-spl, which should be expanded into three parts
+ self.assertIn('u-boot-spl', entries)
+ entry = entries['u-boot-spl']
+ self.assertEqual('u-boot-spl-expanded', entry.etype)
+ subent = entry.GetEntries()
+ self.assertEqual(3, len(subent))
+ self.assertIn('u-boot-spl-nodtb', subent)
+ self.assertIn('u-boot-spl-bss-pad', subent)
+ self.assertIn('u-boot-spl-dtb', subent)
+
+ # Third, u-boot-tpl, which should be not be expanded, since TPL has no
+ # devicetree
+ self.assertIn('u-boot-tpl', entries)
+ entry = entries['u-boot-tpl']
+ self.assertEqual('u-boot-tpl', entry.etype)
+ self.assertEqual(None, entry.GetEntries())
+
+ def testExpandedTpl(self):
+ """Test that an expanded entry type is selected for TPL when needed"""
+ self._SetupTplElf()
+
+ entry_args = {
+ 'tpl-bss-pad': 'y',
+ 'tpl-dtb': 'y',
+ }
+ self._DoReadFileDtb('195_fdt_incl_tpl.dts', use_expanded=True,
+ entry_args=entry_args)
+ image = control.images['image']
+ entries = image.GetEntries()
+ self.assertEqual(1, len(entries))
+
+ # We only have u-boot-tpl, which be expanded
+ self.assertIn('u-boot-tpl', entries)
+ entry = entries['u-boot-tpl']
+ self.assertEqual('u-boot-tpl-expanded', entry.etype)
+ subent = entry.GetEntries()
+ self.assertEqual(3, len(subent))
+ self.assertIn('u-boot-tpl-nodtb', subent)
+ self.assertIn('u-boot-tpl-bss-pad', subent)
+ self.assertIn('u-boot-tpl-dtb', subent)
+
+ def testExpandedNoPad(self):
+ """Test an expanded entry without BSS pad enabled"""
+ self._SetupSplElf()
+ self._SetupTplElf()
+
+ # SPL has a devicetree, TPL does not
+ entry_args = {
+ 'spl-dtb': 'something',
+ 'spl-bss-pad': 'n',
+ 'tpl-dtb': '',
+ }
+ self._DoReadFileDtb('194_fdt_incl.dts', use_expanded=True,
+ entry_args=entry_args)
+ image = control.images['image']
+ entries = image.GetEntries()
+
+ # Just check u-boot-spl, which should be expanded into two parts
+ self.assertIn('u-boot-spl', entries)
+ entry = entries['u-boot-spl']
+ self.assertEqual('u-boot-spl-expanded', entry.etype)
+ subent = entry.GetEntries()
+ self.assertEqual(2, len(subent))
+ self.assertIn('u-boot-spl-nodtb', subent)
+ self.assertIn('u-boot-spl-dtb', subent)
+
+ def testExpandedTplNoPad(self):
+ """Test that an expanded entry type with padding disabled in TPL"""
+ self._SetupTplElf()
+
+ entry_args = {
+ 'tpl-bss-pad': '',
+ 'tpl-dtb': 'y',
+ }
+ self._DoReadFileDtb('195_fdt_incl_tpl.dts', use_expanded=True,
+ entry_args=entry_args)
+ image = control.images['image']
+ entries = image.GetEntries()
+ self.assertEqual(1, len(entries))
+
+ # We only have u-boot-tpl, which be expanded
+ self.assertIn('u-boot-tpl', entries)
+ entry = entries['u-boot-tpl']
+ self.assertEqual('u-boot-tpl-expanded', entry.etype)
+ subent = entry.GetEntries()
+ self.assertEqual(2, len(subent))
+ self.assertIn('u-boot-tpl-nodtb', subent)
+ self.assertIn('u-boot-tpl-dtb', subent)
+
+ def testFdtInclude(self):
+ """Test that an Fdt is update within all binaries"""
+ self._SetupSplElf()
+ self._SetupTplElf()
+
+ # SPL has a devicetree, TPL does not
+ self.maxDiff = None
+ entry_args = {
+ 'spl-dtb': '1',
+ 'spl-bss-pad': 'y',
+ 'tpl-dtb': '',
+ }
+ # Build the image. It includes two separate devicetree binaries, each
+ # with their own contents, but all contain the binman definition.
+ data = self._DoReadFileDtb(
+ '194_fdt_incl.dts', use_real_dtb=True, use_expanded=True,
+ update_dtb=True, entry_args=entry_args)[0]
+ pad_len = 10
+
+ # Check the U-Boot dtb
+ start = len(U_BOOT_NODTB_DATA)
+ fdt_size = self.checkDtbSizes(data, pad_len, start)
+
+ # Now check SPL
+ start += fdt_size + len(U_BOOT_SPL_NODTB_DATA) + pad_len
+ fdt_size = self.checkDtbSizes(data, pad_len, start)
+
+ # TPL has no devicetree
+ start += fdt_size + len(U_BOOT_TPL_DATA)
+ self.assertEqual(len(data), start)
if __name__ == "__main__":
unittest.main()