diff --git a/tools/binman/README b/tools/binman/README index c96a564226..20a80944e2 100644 --- a/tools/binman/README +++ b/tools/binman/README @@ -766,20 +766,38 @@ when SPL is finished. Binman allows you to declare symbols in the SPL image which are filled in with their correct values during the build. For example: - binman_sym_declare(ulong, u_boot_any, offset); + binman_sym_declare(ulong, u_boot_any, image_pos); -declares a ulong value which will be assigned to the offset of any U-Boot +declares a ulong value which will be assigned to the image-pos of any U-Boot image (u-boot.bin, u-boot.img, u-boot-nodtb.bin) that is present in the image. You can access this value with something like: - ulong u_boot_offset = binman_sym(ulong, u_boot_any, offset); + ulong u_boot_offset = binman_sym(ulong, u_boot_any, image_pos); -Thus u_boot_offset will be set to the offset of U-Boot in memory, assuming that -the whole image has been loaded, or is available in flash. You can then jump to -that address to start U-Boot. +Thus u_boot_offset will be set to the image-pos of U-Boot in memory, assuming +that the whole image has been loaded, or is available in flash. You can then +jump to that address to start U-Boot. -At present this feature is only supported in SPL. In principle it is possible -to fill in such symbols in U-Boot proper, as well. +At present this feature is only supported in SPL and TPL. In principle it is +possible to fill in such symbols in U-Boot proper, as well, but a future C +library is planned for this instead, to read from the device tree. + +As well as image-pos, it is possible to read the size of an entry and its +offset (which is the start position of the entry within its parent). + +A small technical note: Binman automatically adds the base address of the image +(i.e. __image_copy_start) to the value of the image-pos symbol, so that when the +image is loaded to its linked address, the value will be correct and actually +point into the image. + +For example, say SPL is at the start of the image and linked to start at address +80108000. If U-Boot's image-pos is 0x8000 then binman will write an image-pos +for U-Boot of 80110000 into the SPL binary, since it assumes the image is loaded +to 80108000, with SPL at 80108000 and U-Boot at 80110000. + +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. Access to binman entry offsets at run time (fdt) diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 0c1a5b44b6..de1ce73f2a 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -134,7 +134,7 @@ def LookupAndWriteSymbols(elf_fname, entry, section): (msg, sym.size)) # Look up the symbol in our entry tables. - value = section.LookupSymbol(name, sym.weak, msg) + value = section.LookupSymbol(name, sym.weak, msg, base.address) if value is None: value = -1 pack_string = pack_string.lower() diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index c0c11cb340..ac26fd51e4 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -45,7 +45,7 @@ class FakeSection: def GetPath(self): return 'section_path' - def LookupSymbol(self, name, weak, msg): + def LookupSymbol(self, name, weak, msg, base_addr): """Fake implementation which returns the same value for all symbols""" return self.sym_value diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py index ab0c42cee0..89b7bf67fa 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -290,13 +290,16 @@ class Entry_section(Entry): return entry.GetData() source_entry.Raise("Cannot find entry for node '%s'" % node.name) - def LookupSymbol(self, sym_name, optional, msg): + def LookupSymbol(self, sym_name, optional, msg, base_addr): """Look up a symbol in an ELF file Looks up a symbol in an ELF file. Only entry types which come from an ELF image can be used by this function. - At present the only entry property supported is offset. + At present the only entry properties supported are: + offset + image_pos - 'base_addr' is added if this is not an end-at-4gb image + size Args: sym_name: Symbol name in the ELF file to look up in the format @@ -309,6 +312,12 @@ class Entry_section(Entry): optional: True if the symbol is optional. If False this function will raise if the symbol is not found msg: Message to display if an error occurs + base_addr: Base address of image. This is added to the returned + image_pos in most cases so that the returned position indicates + where the targetted entry/binary has actually been loaded. But + if end-at-4gb is used, this is not done, since the binary is + already assumed to be linked to the ROM position and using + execute-in-place (XIP). Returns: Value that should be assigned to that symbol, or None if it was @@ -343,7 +352,10 @@ class Entry_section(Entry): if prop_name == 'offset': return entry.offset elif prop_name == 'image_pos': - return entry.image_pos + value = entry.image_pos + if not self.GetImage()._end_4gb: + value += base_addr + return value if prop_name == 'size': return entry.size else: diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 80df0e3ca9..872b855444 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -1242,7 +1242,7 @@ class TestFunctional(unittest.TestCase): self._SetupSplElf('u_boot_binman_syms') data = self._DoReadFile('053_symbols.dts') - sym_values = struct.pack('; + #size-cells = <1>; + + binman { + pad-byte = <0xff>; + end-at-4gb; + size = <0x100>; + u-boot-spl { + offset = <0xffffff04>; + }; + + u-boot-spl2 { + offset = <0xffffff1c>; + type = "u-boot-spl"; + }; + + u-boot { + offset = <0xffffff34>; + }; + + section { + u-boot-tpl { + type = "u-boot-tpl"; + }; + }; + }; +}; diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile index bdbb009874..e4fd97bb2e 100644 --- a/tools/binman/test/Makefile +++ b/tools/binman/test/Makefile @@ -14,10 +14,11 @@ CFLAGS := -march=i386 -m32 -nostdlib -I $(SRC)../../../include \ LDS_UCODE := -T $(SRC)u_boot_ucode_ptr.lds LDS_BINMAN := -T $(SRC)u_boot_binman_syms.lds LDS_BINMAN_BAD := -T $(SRC)u_boot_binman_syms_bad.lds +LDS_BINMAN_X86 := -T $(SRC)u_boot_binman_syms_x86.lds TARGETS = u_boot_ucode_ptr u_boot_no_ucode_ptr bss_data \ u_boot_binman_syms u_boot_binman_syms.bin u_boot_binman_syms_bad \ - u_boot_binman_syms_size + u_boot_binman_syms_size u_boot_binman_syms_x86 all: $(TARGETS) @@ -36,6 +37,9 @@ u_boot_binman_syms.bin: u_boot_binman_syms u_boot_binman_syms: CFLAGS += $(LDS_BINMAN) u_boot_binman_syms: u_boot_binman_syms.c +u_boot_binman_syms_x86: CFLAGS += $(LDS_BINMAN_X86) +u_boot_binman_syms_x86: u_boot_binman_syms_x86.c + u_boot_binman_syms_bad: CFLAGS += $(LDS_BINMAN_BAD) u_boot_binman_syms_bad: u_boot_binman_syms_bad.c diff --git a/tools/binman/test/u_boot_binman_syms_x86.c b/tools/binman/test/u_boot_binman_syms_x86.c new file mode 120000 index 0000000000..939b2e965f --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms_x86.c @@ -0,0 +1 @@ +u_boot_binman_syms.c \ No newline at end of file diff --git a/tools/binman/test/u_boot_binman_syms_x86.lds b/tools/binman/test/u_boot_binman_syms_x86.lds new file mode 100644 index 0000000000..9daf86f833 --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms_x86.lds @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2016 Google, Inc + */ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + . = 0xffffff00; + _start = .; + + . = ALIGN(4); + .text : + { + __image_copy_start = .; + *(.text*) + } + + . = ALIGN(4); + .binman_sym_table : { + __binman_sym_start = .; + KEEP(*(SORT(.binman_sym*))); + __binman_sym_end = .; + } + .interp : { *(.interp*) } + +}