diff options
-rw-r--r-- | tools/binman/binman.rst | 15 | ||||
-rw-r--r-- | tools/binman/elf.py | 7 | ||||
-rw-r--r-- | tools/binman/entry.py | 8 | ||||
-rw-r--r-- | tools/binman/etype/blob_phase.py | 5 | ||||
-rw-r--r-- | tools/binman/ftest.py | 35 | ||||
-rw-r--r-- | tools/binman/test/336_symbols_base.dts | 23 | ||||
-rw-r--r-- | tools/binman/test/337_symbols_base_expand.dts | 24 |
7 files changed, 110 insertions, 7 deletions
diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 04564f4f66f..f9a3a42183b 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -502,6 +502,10 @@ For x86 devices (with the end-at-4gb property) this base address is not added since it is assumed that images are XIP and the offsets already include the address. +For non-x86 cases where the symbol is used as a flash offset, the symbols-base +property can be set to that offset (e.g. 0), so that the unadjusted image-pos +is written into the image. + While U-Boot's symbol updating is handled automatically by the u-boot-spl entry type (and others), it is possible to use this feature with any blob. To do this, add a `write-symbols` (boolean) property to the node, set the ELF @@ -743,6 +747,17 @@ insert-template: properties are brought into the target node. See Templates_ below for more information. +symbols-base: + When writing symbols into a binary, the value of that symbol is assumed to + be relative to the base address of the binary. This allow the binary to be + loaded in memory at its base address, so that symbols point into the binary + correctly. In some cases the binary is in fact not yet in memory, but must + be read from storage. In this case there is no base address for the symbols. + This property can be set to 0 to indicate this. Other values for + symbols-base are allowed, but care must be taken that the code which uses + the symbol is aware of the base being used. If omitted, the binary's base + address is used. + The attributes supported for images and sections are described below. Several are similar to those for entries. diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 73394830ebe..c75f4478813 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -234,7 +234,7 @@ def GetSymbolOffset(elf_fname, sym_name, base_sym=None): return val - base def LookupAndWriteSymbols(elf_fname, entry, section, is_elf=False, - base_sym=None): + base_sym=None, base_addr=None): """Replace all symbols in an entry with their correct values The entry contents is updated so that values for referenced symbols will be @@ -249,6 +249,8 @@ def LookupAndWriteSymbols(elf_fname, entry, section, is_elf=False, section: Section which can be used to lookup symbol values base_sym: Base symbol marking the start of the image (__image_copy_start by default) + base_addr (int): Base address to use for the entry being written. If + None then the value of base_sym is used Returns: int: Number of symbols written @@ -278,7 +280,8 @@ def LookupAndWriteSymbols(elf_fname, entry, section, is_elf=False, if not base and not is_elf: tout.debug(f'LookupAndWriteSymbols: no base: elf_fname={elf_fname}, base_sym={base_sym}, is_elf={is_elf}') return 0 - base_addr = 0 if is_elf else base.address + if base_addr is None: + base_addr = 0 if is_elf else base.address count = 0 for name, sym in syms.items(): if name.startswith('_binman'): diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 7d4d4692776..8ad9fe89e0c 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -108,6 +108,9 @@ class Entry(object): not need to be done again. This is only used with 'binman replace', to stop sections from being rebuilt if their entries have not been replaced + symbols_base (int): Use this value as the assumed load address of the + target entry, when calculating the symbol value. If None, this is + 0 for blobs and the image-start address for ELF files """ fake_dir = None @@ -159,6 +162,7 @@ class Entry(object): self.preserve = False self.build_done = False self.no_write_symbols = False + self.symbols_base = None @staticmethod def FindEntryClass(etype, expanded): @@ -324,6 +328,7 @@ class Entry(object): self.preserve = fdt_util.GetBool(self._node, 'preserve') self.no_write_symbols = fdt_util.GetBool(self._node, 'no-write-symbols') + self.symbols_base = fdt_util.GetInt(self._node, 'symbols-base') def GetDefaultFilename(self): return None @@ -713,7 +718,8 @@ class Entry(object): # Check if we are writing symbols into an ELF file is_elf = self.GetDefaultFilename() == self.elf_fname elf.LookupAndWriteSymbols(self.elf_fname, self, section.GetImage(), - is_elf, self.elf_base_sym) + is_elf, self.elf_base_sym, + self.symbols_base) def CheckEntries(self): """Check that the entry offsets are correct diff --git a/tools/binman/etype/blob_phase.py b/tools/binman/etype/blob_phase.py index 951d9934050..09bb89b3b78 100644 --- a/tools/binman/etype/blob_phase.py +++ b/tools/binman/etype/blob_phase.py @@ -57,3 +57,8 @@ class Entry_blob_phase(Entry_section): if self.no_write_symbols: for entry in self._entries.values(): entry.no_write_symbols = True + + # Propagate the symbols-base property + if self.symbols_base is not None: + for entry in self._entries.values(): + entry.symbols_base = self.symbols_base diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 7b4454bd342..ecfcd6bd915 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -1500,7 +1500,8 @@ 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: @@ -1512,6 +1513,8 @@ class TestFunctional(unittest.TestCase): 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']) @@ -1526,10 +1529,19 @@ class TestFunctional(unittest.TestCase): # 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 - vals = (elf.BINMAN_SYM_MAGIC_VALUE, 0x00, + vals2 = (elf.BINMAN_SYM_MAGIC_VALUE, 0x00, u_boot_offset + len(U_BOOT_DATA), 0x10 + u_boot_offset, 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: self.assertEqual( base_data + @@ -1552,12 +1564,12 @@ class TestFunctional(unittest.TestCase): ofs = blen + 1 + len(U_BOOT_DATA) self.assertEqual(U_BOOT_DATA, data[blen + 1:ofs]) - self.assertEqual(sym_values, data[ofs:ofs + 24]) + 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 expected = (sym_values + base_data[24:] + - tools.get_bytes(0xff, 1) + U_BOOT_DATA + sym_values + + tools.get_bytes(0xff, 1) + U_BOOT_DATA + sym_values2 + base_data[24:]) self.assertEqual(expected, data) @@ -7750,6 +7762,21 @@ fdt fdtmap Extract the devicetree blob from the fdtmap 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) + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/336_symbols_base.dts b/tools/binman/test/336_symbols_base.dts new file mode 100644 index 00000000000..e4dccd38c22 --- /dev/null +++ b/tools/binman/test/336_symbols_base.dts @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + pad-byte = <0xff>; + u-boot-spl { + symbols-base = <0>; + }; + + u-boot { + offset = <0x1c>; + }; + + u-boot-spl2 { + type = "u-boot-spl"; + }; + }; +}; diff --git a/tools/binman/test/337_symbols_base_expand.dts b/tools/binman/test/337_symbols_base_expand.dts new file mode 100644 index 00000000000..5a777ae63b8 --- /dev/null +++ b/tools/binman/test/337_symbols_base_expand.dts @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + pad-byte = <0xff>; + u-boot-spl { + symbols-base = <0>; + }; + + u-boot { + offset = <0x38>; + no-expanded; + }; + + u-boot-spl2 { + type = "u-boot-spl"; + }; + }; +}; |