From e5eaf810f94d9fe3d091b3591552def2e4bf4bae Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Nov 2021 21:09:14 -0600 Subject: [PATCH 01/13] patman: Use a ValueError exception if tools.Run() fails The Exception base class is a very vague and could be confusing to the test system. Use the more specific ValueError exception instead. Signed-off-by: Simon Glass --- tools/patman/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 710f1fdcd36..86c4f616206 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -349,7 +349,7 @@ def Run(name, *args, **kwargs): result = command.RunPipe([all_args], capture=True, capture_stderr=True, env=env, raise_on_error=False, binary=binary) if result.return_code: - raise Exception("Error %d running '%s': %s" % + raise ValueError("Error %d running '%s': %s" % (result.return_code,' '.join(all_args), result.stderr)) return result.stdout From 2fb2cd75f3c2d8bdd8fc19f7a4291879ff89d840 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Nov 2021 21:09:15 -0600 Subject: [PATCH 02/13] binman: Report an error if test files fail to compile At present any error from the 'make' command is silently swallowed by the test system. Fix this by showing it when detected. Signed-off-by: Simon Glass --- tools/binman/elf_test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index 7a128018d9f..bcccd78c0a1 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -70,8 +70,12 @@ def BuildElfTestFiles(target_dir): # correctly. So drop any make flags here. if 'MAKEFLAGS' in os.environ: del os.environ['MAKEFLAGS'] - tools.Run('make', '-C', target_dir, '-f', - os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir) + try: + tools.Run('make', '-C', target_dir, '-f', + os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir) + except ValueError as e: + # The test system seems to suppress this in a strange way + print(e) class TestElf(unittest.TestCase): From 056f0efd8ba20f382f120262c632545e6f06b4a5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Nov 2021 21:09:16 -0600 Subject: [PATCH 03/13] binman: Support reading the offset of an ELF-file symbol Binman needs to be able to update the contents of an ELF file after it has been build. To support this, add a function to locate the position of a symbol's contents within the file. Fix the comments on bss_data.c and Symbol while we are here. Signed-off-by: Simon Glass --- tools/binman/elf.py | 53 ++++++++++++++++++++++++++++++-- tools/binman/elf_test.py | 37 ++++++++++++++++++++++ tools/binman/test/Makefile | 5 ++- tools/binman/test/bss_data.c | 2 +- tools/binman/test/embed_data.c | 16 ++++++++++ tools/binman/test/embed_data.lds | 23 ++++++++++++++ 6 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 tools/binman/test/embed_data.c create mode 100644 tools/binman/test/embed_data.lds diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 03b49d7163c..4aca4f847ce 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -24,7 +24,14 @@ try: except: # pragma: no cover ELF_TOOLS = False -Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak']) +# Information about an EFL symbol: +# section (str): Name of the section containing this symbol +# address (int): Address of the symbol (its value) +# size (int): Size of the symbol in bytes +# weak (bool): True if the symbol is weak +# offset (int or None): Offset of the symbol's data in the ELF file, or None if +# not known +Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak', 'offset']) # Information about an ELF file: # data: Extracted program contents of ELF file (this would be loaded by an @@ -71,8 +78,48 @@ def GetSymbols(fname, patterns): section, size = parts[:2] if len(parts) > 2: name = parts[2] if parts[2] != '.hidden' else parts[3] - syms[name] = Symbol(section, int(value, 16), int(size,16), - flags[1] == 'w') + syms[name] = Symbol(section, int(value, 16), int(size, 16), + flags[1] == 'w', None) + + # Sort dict by address + return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address)) + +def GetSymbolFileOffset(fname, patterns): + """Get the symbols from an ELF file + + Args: + fname: Filename of the ELF file to read + patterns: List of regex patterns to search for, each a string + + Returns: + None, if the file does not exist, or Dict: + key: Name of symbol + value: Hex value of symbol + """ + def _GetFileOffset(elf, addr): + for seg in elf.iter_segments(): + seg_end = seg['p_vaddr'] + seg['p_filesz'] + if seg.header['p_type'] == 'PT_LOAD': + if addr >= seg['p_vaddr'] and addr < seg_end: + return addr - seg['p_vaddr'] + seg['p_offset'] + + if not ELF_TOOLS: + raise ValueError('Python elftools package is not available') + + syms = {} + with open(fname, 'rb') as fd: + elf = ELFFile(fd) + + re_syms = re.compile('|'.join(patterns)) + for section in elf.iter_sections(): + if isinstance(section, SymbolTableSection): + for symbol in section.iter_symbols(): + if not re_syms or re_syms.search(symbol.name): + addr = symbol.entry['st_value'] + syms[symbol.name] = Symbol( + section.name, addr, symbol.entry['st_size'], + symbol.entry['st_info']['bind'] == 'STB_WEAK', + _GetFileOffset(elf, addr)) # Sort dict by address return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address)) diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index bcccd78c0a1..ac69a95b654 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -6,6 +6,7 @@ import os import shutil +import struct import sys import tempfile import unittest @@ -221,6 +222,42 @@ class TestElf(unittest.TestCase): elf.DecodeElf(data, load + 2)) shutil.rmtree(outdir) + def testEmbedData(self): + """Test for the GetSymbolFileOffset() function""" + if not elf.ELF_TOOLS: + self.skipTest('Python elftools not available') + + fname = self.ElfTestFile('embed_data') + offset = elf.GetSymbolFileOffset(fname, ['embed_start', 'embed_end']) + start = offset['embed_start'].offset + end = offset['embed_end'].offset + data = tools.ReadFile(fname) + embed_data = data[start:end] + expect = struct.pack(' Date: Wed, 3 Nov 2021 21:09:17 -0600 Subject: [PATCH 04/13] binman: Tidy up comments on _DoTestFile() The comment for this function is missing an argument and the return value. Fix it. Signed-off-by: Simon Glass --- tools/binman/ftest.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 8199a4fc7e0..39a4b94cd0b 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -334,6 +334,11 @@ class TestFunctional(unittest.TestCase): extra_indirs: Extra input directories to add using -I threads: Number of threads to use (None for default, 0 for single-threaded) + test_section_timeout: True to force the first time to timeout, as + used in testThreadTimeout() + + Returns: + int return code, 0 on success """ args = [] if debug: From 0427bed63bece3caeb8153548903146b73b56677 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Nov 2021 21:09:18 -0600 Subject: [PATCH 05/13] binman: Support updating the dtb in an ELF file WIth EFI we must embed the devicetree in an ELF image so that it is loaded as part of the executable file. We want it to include the binman definition in there also, which in some cases cannot be created until the ELF (u-boot) is built. Add an option to binman to support writing the updated dtb to the ELF file u-boot.out This is useful with the EFI app, which is always packaged as an ELF file. Signed-off-by: Simon Glass --- tools/binman/binman.rst | 36 ++++++++++ tools/binman/cmdline.py | 2 + tools/binman/control.py | 11 +++ tools/binman/elf.py | 21 ++++++ tools/binman/ftest.py | 83 +++++++++++++++++++++- tools/binman/test/Makefile | 10 ++- tools/binman/test/u_boot_binman_embed.c | 13 ++++ tools/binman/test/u_boot_binman_embed.lds | 29 ++++++++ tools/binman/test/u_boot_binman_embed_sm.c | 13 ++++ 9 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 tools/binman/test/u_boot_binman_embed.c create mode 100644 tools/binman/test/u_boot_binman_embed.lds create mode 100644 tools/binman/test/u_boot_binman_embed_sm.c diff --git a/tools/binman/binman.rst b/tools/binman/binman.rst index 614df541c5a..35de93bd898 100644 --- a/tools/binman/binman.rst +++ b/tools/binman/binman.rst @@ -818,6 +818,42 @@ the 'warning' line in scripts/Makefile.lib to see what it has found:: # u_boot_dtsi_options_debug = $(u_boot_dtsi_options_raw) +Updating an ELF file +==================== + +For the EFI app, where U-Boot is loaded from UEFI and runs as an app, there is +no way to update the devicetree after U-Boot is built. Normally this works by +creating a new u-boot.dtb.out with he updated devicetree, which is automatically +built into the output image. With ELF this is not possible since the ELF is +not part of an image, just a stand-along file. We must create an updated ELF +file with the new devicetree. + +This is handled by the --update-fdt-in-elf option. It takes four arguments, +separated by comma: + + infile - filename of input ELF file, e.g. 'u-boot's + outfile - filename of output ELF file, e.g. 'u-boot.out' + begin_sym - symbol at the start of the embedded devicetree, e.g. + '__dtb_dt_begin' + end_sym - symbol at the start of the embedded devicetree, e.g. + '__dtb_dt_end' + +When this flag is used, U-Boot does all the normal packaging, but as an +additional step, it creates a new ELF file with the new devicetree embedded in +it. + +If logging is enabled you will see a message like this:: + + Updating file 'u-boot' with data length 0x400a (16394) between symbols + '__dtb_dt_begin' and '__dtb_dt_end' + +There must be enough space for the updated devicetree. If not, an error like +the following is produced:: + + ValueError: Not enough space in 'u-boot' for data length 0x400a (16394); + size is 0x1744 (5956) + + Entry Documentation =================== diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index d6156df408b..23729f16dcc 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -71,6 +71,8 @@ controlled by a description in the board device tree.''' 'given') build_parser.add_argument('-u', '--update-fdt', action='store_true', default=False, help='Update the binman node with offset/size info') + build_parser.add_argument('--update-fdt-in-elf', type=str, + help='Update an ELF file with the output dtb: infile,outfile,begin_sym,end_sym') entry_parser = subparsers.add_parser('entry-docs', help='Write out entry documentation (see entries.rst)') diff --git a/tools/binman/control.py b/tools/binman/control.py index 0dbcbc28e99..a56e65ace64 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -595,6 +595,13 @@ def Binman(args): tools.FinaliseOutputDir() return 0 + elf_params = None + if args.update_fdt_in_elf: + elf_params = args.update_fdt_in_elf.split(',') + if len(elf_params) != 4: + raise ValueError('Invalid args %s to --update-fdt-in-elf: expected infile,outfile,begin_sym,end_sym' % + elf_params) + # Try to figure out which device tree contains our image description if args.dt: dtb_fname = args.dt @@ -641,6 +648,10 @@ def Binman(args): for dtb_item in state.GetAllFdts(): tools.WriteFile(dtb_item._fname, dtb_item.GetContents()) + if elf_params: + data = state.GetFdtForEtype('u-boot-dtb').GetContents() + elf.UpdateFile(*elf_params, data) + if missing: tout.Warning("\nSome images are invalid") diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 4aca4f847ce..de2bb4651fa 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -348,3 +348,24 @@ def DecodeElf(data, location): segment.data()[offset:]) return ElfInfo(output, data_start, elf.header['e_entry'] + virt_to_phys, mem_end - data_start) + +def UpdateFile(infile, outfile, start_sym, end_sym, insert): + tout.Notice("Creating file '%s' with data length %#x (%d) between symbols '%s' and '%s'" % + (outfile, len(insert), len(insert), start_sym, end_sym)) + syms = GetSymbolFileOffset(infile, [start_sym, end_sym]) + if len(syms) != 2: + raise ValueError("Expected two symbols '%s' and '%s': got %d: %s" % + (start_sym, end_sym, len(syms), + ','.join(syms.keys()))) + + size = syms[end_sym].offset - syms[start_sym].offset + if len(insert) > size: + raise ValueError("Not enough space in '%s' for data length %#x (%d); size is %#x (%d)" % + (infile, len(insert), len(insert), size, size)) + + data = tools.ReadFile(infile) + newdata = data[:syms[start_sym].offset] + newdata += insert + tools.GetBytes(0, size - len(insert)) + newdata += data[syms[end_sym].offset:] + tools.WriteFile(outfile, newdata) + tout.Info('Written to offset %#x' % syms[start_sym].offset) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 39a4b94cd0b..6be003786e8 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -309,7 +309,7 @@ class TestFunctional(unittest.TestCase): entry_args=None, images=None, use_real_dtb=False, use_expanded=False, verbosity=None, allow_missing=False, extra_indirs=None, threads=None, - test_section_timeout=False): + test_section_timeout=False, update_fdt_in_elf=None): """Run binman with a given test file Args: @@ -336,6 +336,7 @@ class TestFunctional(unittest.TestCase): single-threaded) 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 Returns: int return code, 0 on success @@ -368,6 +369,8 @@ class TestFunctional(unittest.TestCase): args.append('-a%s=%s' % (arg, value)) if allow_missing: args.append('-M') + if update_fdt_in_elf: + args += ['--update-fdt-in-elf', update_fdt_in_elf] if images: for image in images: args += ['-i', image] @@ -4580,6 +4583,84 @@ class TestFunctional(unittest.TestCase): self.assertIn('read:', stdout.getvalue()) self.assertIn('compress:', stdout.getvalue()) + def testUpdateFdtInElf(self): + """Test that we can update the devicetree in an ELF file""" + infile = elf_fname = self.ElfTestFile('u_boot_binman_embed') + outfile = os.path.join(self._indir, 'u-boot.out') + begin_sym = 'dtb_embed_begin' + end_sym = 'dtb_embed_end' + retcode = self._DoTestFile( + '060_fdt_update.dts', update_dtb=True, + update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym])) + self.assertEqual(0, retcode) + + # Check that the output file does in fact contact a dtb with the binman + # definition in the correct place + syms = elf.GetSymbolFileOffset(infile, + ['dtb_embed_begin', 'dtb_embed_end']) + data = tools.ReadFile(outfile) + dtb_data = data[syms['dtb_embed_begin'].offset: + syms['dtb_embed_end'].offset] + + dtb = fdt.Fdt.FromData(dtb_data) + dtb.Scan() + props = self._GetPropTree(dtb, BASE_DTB_PROPS + REPACK_DTB_PROPS) + self.assertEqual({ + 'image-pos': 0, + 'offset': 0, + '_testing:offset': 32, + '_testing:size': 2, + '_testing:image-pos': 32, + 'section@0/u-boot:offset': 0, + 'section@0/u-boot:size': len(U_BOOT_DATA), + 'section@0/u-boot:image-pos': 0, + 'section@0:offset': 0, + 'section@0:size': 16, + 'section@0:image-pos': 0, + + 'section@1/u-boot:offset': 0, + 'section@1/u-boot:size': len(U_BOOT_DATA), + 'section@1/u-boot:image-pos': 16, + 'section@1:offset': 16, + 'section@1:size': 16, + 'section@1:image-pos': 16, + 'size': 40 + }, props) + + def testUpdateFdtInElfInvalid(self): + """Test that invalid args are detected with --update-fdt-in-elf""" + with self.assertRaises(ValueError) as e: + self._DoTestFile('060_fdt_update.dts', update_fdt_in_elf='fred') + self.assertIn("Invalid args ['fred'] to --update-fdt-in-elf", + str(e.exception)) + + def testUpdateFdtInElfNoSyms(self): + """Test that missing symbols are detected with --update-fdt-in-elf""" + infile = elf_fname = self.ElfTestFile('u_boot_binman_embed') + outfile = '' + begin_sym = 'wrong_begin' + end_sym = 'wrong_end' + with self.assertRaises(ValueError) as e: + self._DoTestFile( + '060_fdt_update.dts', + update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym])) + self.assertIn("Expected two symbols 'wrong_begin' and 'wrong_end': got 0:", + str(e.exception)) + + def testUpdateFdtInElfTooSmall(self): + """Test that an over-large dtb is detected with --update-fdt-in-elf""" + infile = elf_fname = self.ElfTestFile('u_boot_binman_embed_sm') + outfile = os.path.join(self._indir, 'u-boot.out') + begin_sym = 'dtb_embed_begin' + end_sym = 'dtb_embed_end' + with self.assertRaises(ValueError) as e: + self._DoTestFile( + '060_fdt_update.dts', update_dtb=True, + update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym])) + self.assertRegex( + str(e.exception), + "Not enough space in '.*u_boot_binman_embed_sm' for data length.*") + if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile index 6e6cc6de491..387ba163353 100644 --- a/tools/binman/test/Makefile +++ b/tools/binman/test/Makefile @@ -28,10 +28,12 @@ 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 +LDS_BINMAN_EMBED := -T $(SRC)u_boot_binman_embed.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_x86 embed_data + u_boot_binman_syms_size u_boot_binman_syms_x86 embed_data \ + u_boot_binman_embed u_boot_binman_embed_sm all: $(TARGETS) @@ -62,6 +64,12 @@ u_boot_binman_syms_bad: u_boot_binman_syms_bad.c u_boot_binman_syms_size: CFLAGS += $(LDS_BINMAN) u_boot_binman_syms_size: u_boot_binman_syms_size.c +u_boot_binman_embed: CFLAGS += $(LDS_BINMAN_EMBED) +u_boot_binman_embed: u_boot_binman_embed.c + +u_boot_binman_embed_sm: CFLAGS += $(LDS_BINMAN_EMBED) +u_boot_binman_embed_sm: u_boot_binman_embed_sm.c + clean: rm -f $(TARGETS) diff --git a/tools/binman/test/u_boot_binman_embed.c b/tools/binman/test/u_boot_binman_embed.c new file mode 100644 index 00000000000..75874bb6e23 --- /dev/null +++ b/tools/binman/test/u_boot_binman_embed.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google LLC + * + * Simple program to embed a devicetree. This is used by binman tests. + */ + +int __attribute__((section(".mydtb"))) dtb_data[4096]; + +int main(void) +{ + return 0; +} diff --git a/tools/binman/test/u_boot_binman_embed.lds b/tools/binman/test/u_boot_binman_embed.lds new file mode 100644 index 00000000000..e213fa8a84c --- /dev/null +++ b/tools/binman/test/u_boot_binman_embed.lds @@ -0,0 +1,29 @@ +/* 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 +{ + . = 0x00000000; + _start = .; + + . = ALIGN(4); + .text : + { + *(.text*) + } + + . = ALIGN(4); + .data : { + dtb_embed_begin = .; + KEEP(*(.mydtb)); + dtb_embed_end = .; + } + .interp : { *(.interp*) } + +} diff --git a/tools/binman/test/u_boot_binman_embed_sm.c b/tools/binman/test/u_boot_binman_embed_sm.c new file mode 100644 index 00000000000..ae245d78a6a --- /dev/null +++ b/tools/binman/test/u_boot_binman_embed_sm.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2021 Google LLC + * + * Simple program to embed a devicetree. This is used by binman tests. + */ + +int __attribute__((section(".mydtb"))) dtb_data[16]; + +int main(void) +{ + return 0; +} From c9db4c5440d760eedf80448d42559125ee1d0626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 4 Nov 2021 00:23:21 +0100 Subject: [PATCH 06/13] env: Don't set ready flag if import failed in env_set_default() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not set GD_FLG_ENV_READY nor GD_FLG_ENV_DEFAULT if failed importing in env_set_default(). Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- env/common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/env/common.c b/env/common.c index 99729ca002c..2aa23545ba3 100644 --- a/env/common.c +++ b/env/common.c @@ -261,9 +261,11 @@ void env_set_default(const char *s, int flags) flags |= H_DEFAULT; if (himport_r(&env_htab, default_environment, sizeof(default_environment), '\0', flags, 0, - 0, NULL) == 0) + 0, NULL) == 0) { pr_err("## Error: Environment import failed: errno = %d\n", errno); + return; + } gd->flags |= GD_FLG_ENV_READY; gd->flags |= GD_FLG_ENV_DEFAULT; From e8459c12fd2e9b4068041a931ce6da62ac648000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 4 Nov 2021 00:23:22 +0100 Subject: [PATCH 07/13] env: Fix env_get() when returning empty string using env_get_f() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The env_get_f() function returns -1 on failure. Returning 0 means that the variable exists, and is empty string. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- env/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/env/common.c b/env/common.c index 2aa23545ba3..757c5f9ecdb 100644 --- a/env/common.c +++ b/env/common.c @@ -125,7 +125,7 @@ char *env_get(const char *name) } /* restricted capabilities before import */ - if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0) + if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) >= 0) return (char *)(gd->env_buf); return NULL; From 4e7c8b2a1cc77ed7267f21c383d3280496750791 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Thu, 4 Nov 2021 00:23:23 +0100 Subject: [PATCH 08/13] env: Simplify env_get_default() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of pretending that we don't have environment to force searching default environment in env_get_default(), get the data from the default_environment[] buffer directly. Signed-off-by: Marek Behún Reviewed-by: Simon Glass --- env/common.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/env/common.c b/env/common.c index 757c5f9ecdb..208e2adaa01 100644 --- a/env/common.c +++ b/env/common.c @@ -148,12 +148,10 @@ char *from_env(const char *envvar) return ret; } -/* - * Look up variable from environment for restricted C runtime env. - */ -int env_get_f(const char *name, char *buf, unsigned len) +static int env_get_from_linear(const char *env, const char *name, char *buf, + unsigned len) { - const char *env, *p, *end; + const char *p, *end; size_t name_len; if (name == NULL || *name == '\0') @@ -161,11 +159,6 @@ int env_get_f(const char *name, char *buf, unsigned len) name_len = strlen(name); - if (gd->env_valid == ENV_INVALID) - env = default_environment; - else - env = (const char *)gd->env_addr; - for (p = env; *p != '\0'; p = end + 1) { const char *value; unsigned res; @@ -193,6 +186,21 @@ int env_get_f(const char *name, char *buf, unsigned len) return -1; } +/* + * Look up variable from environment for restricted C runtime env. + */ +int env_get_f(const char *name, char *buf, unsigned len) +{ + const char *env; + + if (gd->env_valid == ENV_INVALID) + env = default_environment; + else + env = (const char *)gd->env_addr; + + return env_get_from_linear(env, name, buf, len); +} + /** * Decode the integer value of an environment variable and return it. * @@ -232,17 +240,12 @@ int env_get_yesno(const char *var) */ char *env_get_default(const char *name) { - char *ret_val; - unsigned long really_valid = gd->env_valid; - unsigned long real_gd_flags = gd->flags; + if (env_get_from_linear(default_environment, name, + (char *)(gd->env_buf), + sizeof(gd->env_buf)) >= 0) + return (char *)(gd->env_buf); - /* Pretend that the image is bad. */ - gd->flags &= ~GD_FLG_ENV_READY; - gd->env_valid = ENV_INVALID; - ret_val = env_get(name); - gd->env_valid = really_valid; - gd->flags = real_gd_flags; - return ret_val; + return NULL; } void env_set_default(const char *s, int flags) From ebee206ad987773cb3b0d649ec0ce97fa1d104ca Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 31 Oct 2021 19:17:03 -0600 Subject: [PATCH 09/13] Makefile: Correct TPL rule for OF_REAL Correct an error in the tpl-dtb parameter to binman. At present the TPL rule follows SPL but this is not correct, if TPL uses of-platdata, for example. Fixes: f99cbe4e867 ("fdt: Update Makefile rules with the new OF_REAL Kconfig") Signed-off-by: Simon Glass Reviewed-by: Ilias Apalodimas --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 299cd3ffac9..194f93b3553 100644 --- a/Makefile +++ b/Makefile @@ -1314,7 +1314,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \ -a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \ -a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \ -a spl-dtb=$(CONFIG_SPL_OF_REAL) \ - -a tpl-dtb=$(CONFIG_SPL_OF_REAL) \ + -a tpl-dtb=$(CONFIG_TPL_OF_REAL) \ $(BINMAN_$(@F)) OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex From ace5bb3eca73ae54a28f67cde97bcd9a089cbb06 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 2 Nov 2021 19:44:29 +0100 Subject: [PATCH 10/13] test/dm: fix watchdog test For successful execution of the watchdog test we need both the GPIO as well as the SANDBOX watchdog. Avoid a build failure for CONFIG_WDT_GPIO=n. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- test/dm/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/dm/Makefile b/test/dm/Makefile index 7de013f6368..548649f8e82 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -106,6 +106,8 @@ obj-$(CONFIG_TIMER) += timer.o obj-$(CONFIG_DM_USB) += usb.o obj-$(CONFIG_DM_VIDEO) += video.o obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o -obj-$(CONFIG_WDT) += wdt.o +ifeq ($(CONFIG_WDT_GPIO)$(CONFIG_WDT_SANDBOX),yy) +obj-y += wdt.o +endif endif endif # !SPL From 592e2e592964f76eda4fc797b296742556ecdf62 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 2 Nov 2021 19:44:30 +0100 Subject: [PATCH 11/13] sandbox: fix sandbox_wdt_expire_now() With CONFIG_SYSRESET_WATCHDOG=y the sandbox can use a watchdog based system reset. To make this work calling sandbox_wdt_expire_now() must lead to a reset. With this change we can test the development suggested in [PATCH 0/4] Improved sysreset/watchdog uclass integration https://lists.denx.de/pipermail/u-boot/2021-August/458656.html Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- drivers/watchdog/sandbox_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/sandbox_wdt.c b/drivers/watchdog/sandbox_wdt.c index e05d82789f6..535614f04d6 100644 --- a/drivers/watchdog/sandbox_wdt.c +++ b/drivers/watchdog/sandbox_wdt.c @@ -39,6 +39,7 @@ static int sandbox_wdt_reset(struct udevice *dev) static int sandbox_wdt_expire_now(struct udevice *dev, ulong flags) { sandbox_wdt_start(dev, 1, flags); + sandbox_reset(); return 0; } From c1df3d54d6e5d79626c2f796b03668047316a802 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 3 Nov 2021 15:09:36 +0100 Subject: [PATCH 12/13] bootstage: Differentiate boot progress kconfig entries Both U-Boot proper and SPL entries were using the same description. Fixes: b55881dd ("bootstage: Add SPL support") Signed-off-by: Jan Kiszka Reviewed-by: Simon Glass --- boot/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/Kconfig b/boot/Kconfig index a8d4be23a97..d3a12be2281 100644 --- a/boot/Kconfig +++ b/boot/Kconfig @@ -704,7 +704,7 @@ config SHOW_BOOT_PROGRESS 151 common/cmd_nand.c FIT image format OK config SPL_SHOW_BOOT_PROGRESS - bool "Show boot progress in a board-specific manner" + bool "Show boot progress in a board-specific manner in SPL" depends on SPL help Defining this option allows to add some board-specific code (calling From 89cc0520d7962358ca85464836112217c5b8eca2 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Thu, 11 Nov 2021 08:13:30 +0100 Subject: [PATCH 13/13] binman: Fix replace subcommand help and comments Fix some copy&paste artifacts. Signed-off-by: Jan Kiszka --- tools/binman/cmdline.py | 4 ++-- tools/binman/control.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py index 23729f16dcc..e73ff780956 100644 --- a/tools/binman/cmdline.py +++ b/tools/binman/cmdline.py @@ -101,7 +101,7 @@ controlled by a description in the board device tree.''' replace_parser.add_argument('-C', '--compressed', action='store_true', help='Input data is already compressed if needed for the entry') replace_parser.add_argument('-i', '--image', type=str, required=True, - help='Image filename to extract') + help='Image filename to update') replace_parser.add_argument('-f', '--filename', type=str, help='Input filename to read from') replace_parser.add_argument('-F', '--fix-size', action='store_true', @@ -111,7 +111,7 @@ controlled by a description in the board device tree.''' replace_parser.add_argument('-m', '--map', action='store_true', default=False, help='Output a map file for the updated image') replace_parser.add_argument('paths', type=str, nargs='*', - help='Paths within file to extract (wildcard)') + help='Paths within file to replace (wildcard)') test_parser = subparsers.add_parser('test', help='Run tests') test_parser.add_argument('-P', '--processes', type=int, diff --git a/tools/binman/control.py b/tools/binman/control.py index a56e65ace64..304fc70f56f 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -343,10 +343,10 @@ def ReplaceEntries(image_fname, input_fname, indir, entry_paths, Args: image_fname: Image filename to process - input_fname: Single input ilename to use if replacing one file, None + input_fname: Single input filename to use if replacing one file, None otherwise indir: Input directory to use (for any number of files), else None - entry_paths: List of entry paths to extract + entry_paths: List of entry paths to replace do_compress: True if the input data is uncompressed and may need to be compressed if the entry requires it, False if the data is already compressed.