summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/binman/binman.rst15
-rw-r--r--tools/binman/elf.py7
-rw-r--r--tools/binman/entry.py8
-rw-r--r--tools/binman/etype/blob_phase.py5
-rw-r--r--tools/binman/ftest.py35
-rw-r--r--tools/binman/test/336_symbols_base.dts23
-rw-r--r--tools/binman/test/337_symbols_base_expand.dts24
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";
+ };
+ };
+};