summaryrefslogtreecommitdiff
path: root/tools/binman/ftest.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/binman/ftest.py')
-rw-r--r--tools/binman/ftest.py152
1 files changed, 133 insertions, 19 deletions
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 2577c0016c0..e3f231e4bcc 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -403,8 +403,10 @@ class TestFunctional(unittest.TestCase):
test_section_timeout: True to force the first time to timeout, as
used in testThreadTimeout()
update_fdt_in_elf: Value to pass with --update-fdt-in-elf=xxx
- force_missing_tools (str): comma-separated list of bintools to
+ force_missing_bintools (str): comma-separated list of bintools to
regard as missing
+ ignore_missing (bool): True to return success even if there are
+ missing blobs or bintools
output_dir: Specific output directory to use for image using -O
Returns:
@@ -503,8 +505,9 @@ class TestFunctional(unittest.TestCase):
return dtb.GetContents()
def _DoReadFileDtb(self, fname, use_real_dtb=False, use_expanded=False,
- map=False, update_dtb=False, entry_args=None,
- reset_dtbs=True, extra_indirs=None, threads=None):
+ verbosity=None, map=False, update_dtb=False,
+ entry_args=None, reset_dtbs=True, extra_indirs=None,
+ threads=None):
"""Run binman and return the resulting image
This runs binman with a given test file and then reads the resulting
@@ -521,6 +524,7 @@ class TestFunctional(unittest.TestCase):
But in some test we need the real contents.
use_expanded: True to use expanded entries where available, e.g.
'u-boot-expanded' instead of 'u-boot'
+ verbosity: Verbosity level to use (0-3, None=don't set it)
map: True to output map files for the images
update_dtb: Update the offset and size of each entry in the device
tree before packing it into the image
@@ -557,7 +561,8 @@ class TestFunctional(unittest.TestCase):
try:
retcode = self._DoTestFile(fname, map=map, update_dtb=update_dtb,
entry_args=entry_args, use_real_dtb=use_real_dtb,
- use_expanded=use_expanded, extra_indirs=extra_indirs,
+ use_expanded=use_expanded, verbosity=verbosity,
+ extra_indirs=extra_indirs,
threads=threads)
self.assertEqual(0, retcode)
out_dtb_fname = tools.get_output_filename('u-boot.dtb.out')
@@ -1498,18 +1503,22 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(U_BOOT_SPL_NODTB_DATA, data[:len(U_BOOT_SPL_NODTB_DATA)])
def checkSymbols(self, dts, base_data, u_boot_offset, entry_args=None,
- use_expanded=False, no_write_symbols=False):
+ use_expanded=False, no_write_symbols=False,
+ symbols_base=None):
"""Check the image contains the expected symbol values
Args:
dts: Device tree file to use for test
base_data: Data before and after 'u-boot' section
- u_boot_offset: Offset of 'u-boot' section in image
+ u_boot_offset (int): Offset of 'u-boot' section in image, or None if
+ the offset not available due to it being in a compressed section
entry_args: Dict of entry args to supply to binman
key: arg name
value: value of that arg
use_expanded: True to use expanded entries where available, e.g.
'u-boot-expanded' instead of 'u-boot'
+ symbols_base (int): Value to expect for symbols-base in u-boot-spl,
+ None if none
"""
elf_fname = self.ElfTestFile('u_boot_binman_syms')
syms = elf.GetSymbols(elf_fname, ['binman', 'image'])
@@ -1520,22 +1529,64 @@ class TestFunctional(unittest.TestCase):
self._SetupSplElf('u_boot_binman_syms')
data = self._DoReadFileDtb(dts, entry_args=entry_args,
- use_expanded=use_expanded)[0]
+ use_expanded=use_expanded,
+ verbosity=None if u_boot_offset else 3)[0]
+
+ # The lz4-compressed version of the U-Boot data is 19 bytes long
+ comp_uboot_len = 19
+
# 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
- sym_values = struct.pack('<LLQLL', elf.BINMAN_SYM_MAGIC_VALUE,
- 0x00, u_boot_offset + len(U_BOOT_DATA),
- 0x10 + u_boot_offset, 0x04)
+ # If u_boot_offset is None, Binman should write -1U into the image
+ vals2 = (elf.BINMAN_SYM_MAGIC_VALUE, 0x00,
+ u_boot_offset + len(U_BOOT_DATA) if u_boot_offset else
+ len(U_BOOT_SPL_DATA) + 1 + comp_uboot_len,
+ 0x10 + u_boot_offset if u_boot_offset else 0xffffffff, 0x04)
+
+ # u-boot-spl has a symbols-base property, so take that into account if
+ # required. The caller must supply the value
+ vals = list(vals2)
+ if symbols_base is not None:
+ vals[3] = symbols_base + u_boot_offset
+ vals = tuple(vals)
+
+ sym_values = struct.pack('<LLQLL', *vals)
+ sym_values2 = struct.pack('<LLQLL', *vals2)
if no_write_symbols:
- expected = (base_data +
- tools.get_bytes(0xff, 0x38 - len(base_data)) +
- U_BOOT_DATA + base_data)
+ self.assertEqual(
+ base_data +
+ tools.get_bytes(0xff, 0x38 - len(base_data)) +
+ U_BOOT_DATA + base_data, data)
else:
- expected = (sym_values + base_data[24:] +
- tools.get_bytes(0xff, 1) + U_BOOT_DATA + sym_values +
- base_data[24:])
- self.assertEqual(expected, data)
+ got_vals = struct.unpack('<LLQLL', data[:24])
+
+ # For debugging:
+ #print('expect:', list(f'{v:x}' for v in vals))
+ #print(' got:', list(f'{v:x}' for v in got_vals))
+
+ self.assertEqual(vals, got_vals)
+ self.assertEqual(sym_values, data[:24])
+
+ blen = len(base_data)
+ self.assertEqual(base_data[24:], data[24:blen])
+ self.assertEqual(0xff, data[blen])
+
+ if u_boot_offset:
+ ofs = blen + 1 + len(U_BOOT_DATA)
+ self.assertEqual(U_BOOT_DATA, data[blen + 1:ofs])
+ else:
+ ofs = blen + 1 + comp_uboot_len
+
+ self.assertEqual(sym_values2, data[ofs:ofs + 24])
+ self.assertEqual(base_data[24:], data[ofs + 24:])
+
+ # Just repeating the above asserts all at once, for clarity
+ if u_boot_offset:
+ expected = (sym_values + base_data[24:] +
+ tools.get_bytes(0xff, 1) + U_BOOT_DATA +
+ sym_values2 + base_data[24:])
+ self.assertEqual(expected, data)
def testSymbols(self):
"""Test binman can assign symbols embedded in U-Boot"""
@@ -4181,7 +4232,8 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('172_scp.dts')
self.assertEqual(SCP_DATA, data[:len(SCP_DATA)])
- def CheckFitFdt(self, dts='170_fit_fdt.dts', use_fdt_list=True):
+ def CheckFitFdt(self, dts='170_fit_fdt.dts', use_fdt_list=True,
+ default_dt=None):
"""Check an image with an FIT with multiple FDT images"""
def _CheckFdt(seq, expected_data):
"""Check the FDT nodes
@@ -4225,6 +4277,8 @@ class TestFunctional(unittest.TestCase):
}
if use_fdt_list:
entry_args['of-list'] = 'test-fdt1 test-fdt2'
+ if default_dt:
+ entry_args['default-dt'] = default_dt
data = self._DoReadFileDtb(
dts,
entry_args=entry_args,
@@ -7624,7 +7678,22 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
def testFitFdtListDir(self):
"""Test an image with an FIT with FDT images using fit,fdt-list-dir"""
- self.CheckFitFdt('333_fit_fdt_dir.dts', False)
+ old_dir = os.getcwd()
+ try:
+ os.chdir(self._indir)
+ self.CheckFitFdt('333_fit_fdt_dir.dts', False)
+ finally:
+ os.chdir(old_dir)
+
+ def testFitFdtListDirDefault(self):
+ """Test an FIT fit,fdt-list-dir where the default DT in is a subdir"""
+ old_dir = os.getcwd()
+ try:
+ os.chdir(self._indir)
+ self.CheckFitFdt('333_fit_fdt_dir.dts', False,
+ default_dt='rockchip/test-fdt2')
+ finally:
+ os.chdir(old_dir)
def testFitFdtCompat(self):
"""Test an image with an FIT with compatible in the config nodes"""
@@ -7690,6 +7759,51 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
# Make sure the other node is gone
self.assertIsNone(dtb.GetNode('/node/other-node'))
+ def testMkeficapsuleMissing(self):
+ """Test that binman complains if mkeficapsule is missing"""
+ with self.assertRaises(ValueError) as e:
+ self._DoTestFile('311_capsule.dts',
+ force_missing_bintools='mkeficapsule')
+ self.assertIn("Node '/binman/efi-capsule': Missing tool: 'mkeficapsule'",
+ str(e.exception))
+
+ def testMkeficapsuleMissingOk(self):
+ """Test that binman deals with mkeficapsule being missing"""
+ with test_util.capture_sys_output() as (stdout, stderr):
+ ret = self._DoTestFile('311_capsule.dts',
+ force_missing_bintools='mkeficapsule',
+ allow_missing=True)
+ self.assertEqual(103, ret)
+ err = stderr.getvalue()
+ self.assertRegex(err, "Image 'image'.*missing bintools.*: mkeficapsule")
+
+ def testSymbolsBase(self):
+ """Test handling of symbols-base"""
+ self.checkSymbols('336_symbols_base.dts', U_BOOT_SPL_DATA, 0x1c,
+ symbols_base=0)
+
+ def testSymbolsBaseExpanded(self):
+ """Test handling of symbols-base with expanded entries"""
+ entry_args = {
+ 'spl-dtb': '1',
+ }
+ self.checkSymbols('337_symbols_base_expand.dts', U_BOOT_SPL_NODTB_DATA +
+ U_BOOT_SPL_DTB_DATA, 0x38,
+ entry_args=entry_args, use_expanded=True,
+ symbols_base=0)
+
+ def testSymbolsCompressed(self):
+ """Test binman complains about symbols from a compressed section"""
+ with test_util.capture_sys_output() as (stdout, stderr):
+ self.checkSymbols('338_symbols_comp.dts', U_BOOT_SPL_DATA, None)
+ out = stdout.getvalue()
+ self.assertIn('Symbol-writing: no value for /binman/section/u-boot',
+ out)
+
+ def testNxpImx8Image(self):
+ """Test that binman can produce an iMX8 image"""
+ self._DoTestFile('339_nxp_imx8.dts')
+
if __name__ == "__main__":
unittest.main()