diff options
Diffstat (limited to 'tools/binman')
42 files changed, 1007 insertions, 88 deletions
diff --git a/tools/binman/README b/tools/binman/README index cb47e73599..08c3e56bde 100644 --- a/tools/binman/README +++ b/tools/binman/README @@ -206,6 +206,27 @@ for its instructions in the 'binman' node. Binman has a few other options which you can see by running 'binman -h'. +Enabling binman for a board +--------------------------- + +At present binman is invoked from a rule in the main Makefile. Typically you +will have a rule like: + +ifneq ($(CONFIG_ARCH_<something>),) +u-boot-<your_suffix>.bin: <input_file_1> <input_file_2> checkbinman FORCE + $(call if_changed,binman) +endif + +This assumes that u-boot-<your_suffix>.bin is a target, and is the final file +that you need to produce. You can make it a target by adding it to ALL-y +either in the main Makefile or in a config.mk file in your arch subdirectory. + +Once binman is executed it will pick up its instructions from a device-tree +file, typically <soc>-u-boot.dtsi, where <soc> is your CONFIG_SYS_SOC value. +You can use other, more specific CONFIG options - see 'Automatic .dtsi +inclusion' below. + + Image description format ------------------------ @@ -418,6 +439,8 @@ contents of an entry in some way. For example, it would be possible to create an entry containing a hash of the contents of some other entries. At this stage the position and size of entries should not be adjusted. +6. WriteEntryInfo() + 7. BuildImage() - builds the image and writes it to a file. This is the final step. @@ -446,7 +469,35 @@ If you are having trouble figuring out what is going on, you can uncomment the 'warning' line in scripts/Makefile.lib to see what it has found: # Uncomment for debugging - # $(warning binman_dtsi_options: $(binman_dtsi_options)) + # This shows all the files that were considered and the one that we chose. + # u_boot_dtsi_options_debug = $(u_boot_dtsi_options_raw) + + +Access to binman entry positions at run time +-------------------------------------------- + +Binman assembles images and determines where each entry is placed in the image. +This information may be useful to U-Boot at run time. For example, in SPL it +is useful to be able to find the location of U-Boot so that it can be executed +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, pos); + +declares a ulong value which will be assigned to the position 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_pos = binman_sym(ulong, u_boot_any, pos); + +Thus u_boot_pos will be set to the position 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. Code coverage @@ -521,7 +572,8 @@ To do Some ideas: - Fill out the device tree to include the final position and size of each - entry (since the input file may not always specify these) + entry (since the input file may not always specify these). See also + 'Access to binman entry positions at run time' above - Use of-platdata to make the information available to code that is unable to use device tree (such as a very small SPL image) - Write an image map to a text file diff --git a/tools/binman/binman.py b/tools/binman/binman.py index e75a59d951..1c8e8dbff6 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -10,6 +10,7 @@ """See README for more information""" +import glob import os import sys import traceback @@ -30,11 +31,13 @@ import cmdline import command import control -def RunTests(): +def RunTests(debug): """Run the functional tests and any embedded doctests""" + import elf_test import entry_test import fdt_test - import func_test + import ftest + import image_test import test import doctest @@ -44,8 +47,15 @@ def RunTests(): suite.run(result) sys.argv = [sys.argv[0]] - for module in (func_test.TestFunctional, fdt_test.TestFdt, - entry_test.TestEntry): + if debug: + sys.argv.append('-D') + + # Run the entry tests first ,since these need to be the first to import the + # 'entry' module. + suite = unittest.TestLoader().loadTestsFromTestCase(entry_test.TestEntry) + suite.run(result) + for module in (ftest.TestFunctional, fdt_test.TestFdt, elf_test.TestElf, + image_test.TestImage): suite = unittest.TestLoader().loadTestsFromTestCase(module) suite.run(result) @@ -53,22 +63,41 @@ def RunTests(): for test, err in result.errors: print test.id(), err for test, err in result.failures: - print err + print err, result.failures + if result.errors or result.failures: + print 'binman tests FAILED' + return 1 + return 0 def RunTestCoverage(): """Run the tests and check that we get 100% coverage""" # This uses the build output from sandbox_spl to get _libfdt.so - cmd = ('PYTHONPATH=%s/sandbox_spl/tools coverage run ' + cmd = ('PYTHONPATH=$PYTHONPATH:%s/sandbox_spl/tools coverage run ' '--include "tools/binman/*.py" --omit "*test*,*binman.py" ' 'tools/binman/binman.py -t' % options.build_dir) os.system(cmd) stdout = command.Output('coverage', 'report') - coverage = stdout.splitlines()[-1].split(' ')[-1] + lines = stdout.splitlines() + + test_set= set([os.path.basename(line.split()[0]) + for line in lines if '/etype/' in line]) + glob_list = glob.glob(os.path.join(our_path, 'etype/*.py')) + all_set = set([os.path.basename(item) for item in glob_list]) + missing_list = all_set + missing_list.difference_update(test_set) + missing_list.remove('_testing.py') + coverage = lines[-1].split(' ')[-1] + ok = True + if missing_list: + print 'Missing tests for %s' % (', '.join(missing_list)) + ok = False if coverage != '100%': print stdout print "Type 'coverage html' to get a report in htmlcov/index.html" - raise ValueError('Coverage error: %s, but should be 100%%' % coverage) - + print 'Coverage error: %s, but should be 100%%' % coverage + ok = False + if not ok: + raise ValueError('Test coverage failure') def RunBinman(options, args): """Main entry point to binman once arguments are parsed @@ -86,7 +115,7 @@ def RunBinman(options, args): sys.tracebacklimit = 0 if options.test: - RunTests() + ret_code = RunTests(options.debug) elif options.test_coverage: RunTestCoverage() diff --git a/tools/binman/control.py b/tools/binman/control.py index e9d48df030..ffa2bbd80f 100644 --- a/tools/binman/control.py +++ b/tools/binman/control.py @@ -12,6 +12,7 @@ import sys import tools import command +import elf import fdt import fdt_util from image import Image @@ -89,6 +90,7 @@ def Binman(options, args): try: tout.Init(options.verbosity) + elf.debug = options.debug try: tools.SetInputDirs(options.indir) tools.PrepareOutputDir(options.outdir, options.preserve) @@ -109,6 +111,7 @@ def Binman(options, args): image.CheckSize() image.CheckEntries() image.ProcessEntryContents() + image.WriteSymbols() image.BuildImage() finally: tools.FinaliseOutputDir() diff --git a/tools/binman/elf.py b/tools/binman/elf.py new file mode 100644 index 0000000000..80ff2253f0 --- /dev/null +++ b/tools/binman/elf.py @@ -0,0 +1,129 @@ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Handle various things related to ELF images +# + +from collections import namedtuple, OrderedDict +import command +import os +import re +import struct + +import tools + +# This is enabled from control.py +debug = False + +Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak']) + + +def GetSymbols(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 + """ + stdout = command.Output('objdump', '-t', fname, raise_on_error=False) + lines = stdout.splitlines() + if patterns: + re_syms = re.compile('|'.join(patterns)) + else: + re_syms = None + syms = {} + syms_started = False + for line in lines: + if not line or not syms_started: + if 'SYMBOL TABLE' in line: + syms_started = True + line = None # Otherwise code coverage complains about 'continue' + continue + if re_syms and not re_syms.search(line): + continue + + space_pos = line.find(' ') + value, rest = line[:space_pos], line[space_pos + 1:] + flags = rest[:7] + parts = rest[7:].split() + section, size = parts[:2] + if len(parts) > 2: + name = parts[2] + syms[name] = Symbol(section, int(value, 16), int(size,16), + flags[1] == 'w') + return syms + +def GetSymbolAddress(fname, sym_name): + """Get a value of a symbol 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: + Symbol value (as an integer) or None if not found + """ + syms = GetSymbols(fname, [sym_name]) + sym = syms.get(sym_name) + if not sym: + return None + return sym.address + +def LookupAndWriteSymbols(elf_fname, entry, image): + """Replace all symbols in an entry with their correct values + + The entry contents is updated so that values for referenced symbols will be + visible at run time. This is done by finding out the symbols positions in + the entry (using the ELF file) and replacing them with values from binman's + data structures. + + Args: + elf_fname: Filename of ELF image containing the symbol information for + entry + entry: Entry to process + image: Image which can be used to lookup symbol values + """ + fname = tools.GetInputFilename(elf_fname) + syms = GetSymbols(fname, ['image', 'binman']) + if not syms: + return + base = syms.get('__image_copy_start') + if not base: + return + for name, sym in syms.iteritems(): + if name.startswith('_binman'): + msg = ("Image '%s': Symbol '%s'\n in entry '%s'" % + (image.GetPath(), name, entry.GetPath())) + offset = sym.address - base.address + if offset < 0 or offset + sym.size > entry.contents_size: + raise ValueError('%s has offset %x (size %x) but the contents ' + 'size is %x' % (entry.GetPath(), offset, + sym.size, entry.contents_size)) + if sym.size == 4: + pack_string = '<I' + elif sym.size == 8: + pack_string = '<Q' + else: + raise ValueError('%s has size %d: only 4 and 8 are supported' % + (msg, sym.size)) + + # Look up the symbol in our entry tables. + value = image.LookupSymbol(name, sym.weak, msg) + if value is not None: + value += base.address + else: + value = -1 + pack_string = pack_string.lower() + value_bytes = struct.pack(pack_string, value) + if debug: + print('%s:\n insert %s, offset %x, value %x, length %d' % + (msg, name, offset, value, len(value_bytes))) + entry.data = (entry.data[:offset] + value_bytes + + entry.data[offset + sym.size:]) diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py new file mode 100644 index 0000000000..e5fc28258d --- /dev/null +++ b/tools/binman/elf_test.py @@ -0,0 +1,122 @@ +# +# Copyright (c) 2017 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Test for the elf module + +from contextlib import contextmanager +import os +import sys +import unittest + +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + +import elf + +binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) + +# Use this to suppress stdout/stderr output: +# with capture_sys_output() as (stdout, stderr) +# ...do something... +@contextmanager +def capture_sys_output(): + capture_out, capture_err = StringIO(), StringIO() + old_out, old_err = sys.stdout, sys.stderr + try: + sys.stdout, sys.stderr = capture_out, capture_err + yield capture_out, capture_err + finally: + sys.stdout, sys.stderr = old_out, old_err + + +class FakeEntry: + def __init__(self, contents_size): + self.contents_size = contents_size + self.data = 'a' * contents_size + + def GetPath(self): + return 'entry_path' + +class FakeImage: + def __init__(self, sym_value=1): + self.sym_value = sym_value + + def GetPath(self): + return 'image_path' + + def LookupSymbol(self, name, weak, msg): + return self.sym_value + +class TestElf(unittest.TestCase): + def testAllSymbols(self): + fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr') + syms = elf.GetSymbols(fname, []) + self.assertIn('.ucode', syms) + + def testRegexSymbols(self): + fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr') + syms = elf.GetSymbols(fname, ['ucode']) + self.assertIn('.ucode', syms) + syms = elf.GetSymbols(fname, ['missing']) + self.assertNotIn('.ucode', syms) + syms = elf.GetSymbols(fname, ['missing', 'ucode']) + self.assertIn('.ucode', syms) + + def testMissingFile(self): + entry = FakeEntry(10) + image = FakeImage() + with self.assertRaises(ValueError) as e: + syms = elf.LookupAndWriteSymbols('missing-file', entry, image) + self.assertIn("Filename 'missing-file' not found in input path", + str(e.exception)) + + def testOutsideFile(self): + entry = FakeEntry(10) + image = FakeImage() + elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') + with self.assertRaises(ValueError) as e: + syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) + self.assertIn('entry_path has offset 4 (size 8) but the contents size ' + 'is a', str(e.exception)) + + def testMissingImageStart(self): + entry = FakeEntry(10) + image = FakeImage() + elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_bad') + self.assertEqual(elf.LookupAndWriteSymbols(elf_fname, entry, image), + None) + + def testBadSymbolSize(self): + entry = FakeEntry(10) + image = FakeImage() + elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_size') + with self.assertRaises(ValueError) as e: + syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) + self.assertIn('has size 1: only 4 and 8 are supported', + str(e.exception)) + + def testNoValue(self): + entry = FakeEntry(20) + image = FakeImage(sym_value=None) + elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') + syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) + self.assertEqual(chr(255) * 16 + 'a' * 4, entry.data) + + def testDebug(self): + elf.debug = True + entry = FakeEntry(20) + image = FakeImage() + elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms') + with capture_sys_output() as (stdout, stderr): + syms = elf.LookupAndWriteSymbols(elf_fname, entry, image) + elf.debug = False + self.assertTrue(len(stdout.getvalue()) > 0) + + +if __name__ == '__main__': + unittest.main() diff --git a/tools/binman/entry_test.py b/tools/binman/entry_test.py index 8a9ae017f0..caa523ebf8 100644 --- a/tools/binman/entry_test.py +++ b/tools/binman/entry_test.py @@ -7,21 +7,55 @@ # Test for the Entry class import collections +import os +import sys import unittest -import entry +import fdt +import fdt_util +import tools class TestEntry(unittest.TestCase): + def GetNode(self): + binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) + tools.PrepareOutputDir(None) + fname = fdt_util.EnsureCompiled( + os.path.join(binman_dir,('test/05_simple.dts'))) + dtb = fdt.FdtScan(fname) + return dtb.GetNode('/binman/u-boot') + + def test1EntryNoImportLib(self): + """Test that we can import Entry subclassess successfully""" + + sys.modules['importlib'] = None + global entry + import entry + entry.Entry.Create(None, self.GetNode(), 'u-boot') + + def test2EntryImportLib(self): + del sys.modules['importlib'] + global entry + reload(entry) + entry.Entry.Create(None, self.GetNode(), 'u-boot-spl') + tools._RemoveOutputDir() + del entry + def testEntryContents(self): """Test the Entry bass class""" + import entry base_entry = entry.Entry(None, None, None, read_node=False) self.assertEqual(True, base_entry.ObtainContents()) def testUnknownEntry(self): """Test that unknown entry types are detected""" + import entry Node = collections.namedtuple('Node', ['name', 'path']) node = Node('invalid-name', 'invalid-path') with self.assertRaises(ValueError) as e: entry.Entry.Create(None, node, node.name) self.assertIn("Unknown entry type 'invalid-name' in node " "'invalid-path'", str(e.exception)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/binman/etype/entry.py b/tools/binman/etype/entry.py index 67c57341ca..5541887d47 100644 --- a/tools/binman/etype/entry.py +++ b/tools/binman/etype/entry.py @@ -198,3 +198,11 @@ class Entry(object): def ProcessContents(self): pass + + def WriteSymbols(self, image): + """Write symbol values into binary files for access at run time + + Args: + image: Image containing the entry + """ + pass diff --git a/tools/binman/etype/u_boot_spl.py b/tools/binman/etype/u_boot_spl.py index 68b0148427..3720b47fef 100644 --- a/tools/binman/etype/u_boot_spl.py +++ b/tools/binman/etype/u_boot_spl.py @@ -6,12 +6,18 @@ # Entry-type module for spl/u-boot-spl.bin # +import elf + from entry import Entry from blob import Entry_blob class Entry_u_boot_spl(Entry_blob): def __init__(self, image, etype, node): Entry_blob.__init__(self, image, etype, node) + self.elf_fname = 'spl/u-boot-spl' def GetDefaultFilename(self): return 'spl/u-boot-spl.bin' + + def WriteSymbols(self, image): + elf.LookupAndWriteSymbols(self.elf_fname, self, image) diff --git a/tools/binman/etype/u_boot_spl_bss_pad.py b/tools/binman/etype/u_boot_spl_bss_pad.py index c005f28191..c37f61db23 100644 --- a/tools/binman/etype/u_boot_spl_bss_pad.py +++ b/tools/binman/etype/u_boot_spl_bss_pad.py @@ -9,6 +9,7 @@ # import command +import elf from entry import Entry from blob import Entry_blob import tools @@ -19,8 +20,8 @@ class Entry_u_boot_spl_bss_pad(Entry_blob): def ObtainContents(self): fname = tools.GetInputFilename('spl/u-boot-spl') - args = [['nm', fname], ['grep', '__bss_size']] - out = command.RunPipe(args, capture=True).stdout.splitlines() - bss_size = int(out[0].split()[0], 16) + bss_size = elf.GetSymbolAddress(fname, '__bss_size') + if not bss_size: + self.Raise('Expected __bss_size symbol in spl/u-boot-spl') self.data = chr(0) * bss_size self.contents_size = bss_size diff --git a/tools/binman/etype/u_boot_spl_dtb.py b/tools/binman/etype/u_boot_spl_dtb.py new file mode 100644 index 0000000000..6c5ce1e996 --- /dev/null +++ b/tools/binman/etype/u_boot_spl_dtb.py @@ -0,0 +1,17 @@ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Entry-type module for U-Boot device tree +# + +from entry import Entry +from blob import Entry_blob + +class Entry_u_boot_spl_dtb(Entry_blob): + def __init__(self, image, etype, node): + Entry_blob.__init__(self, image, etype, node) + + def GetDefaultFilename(self): + return 'spl/u-boot-spl.dtb' diff --git a/tools/binman/etype/u_boot_spl_nodtb.py b/tools/binman/etype/u_boot_spl_nodtb.py new file mode 100644 index 0000000000..880e0c78fb --- /dev/null +++ b/tools/binman/etype/u_boot_spl_nodtb.py @@ -0,0 +1,17 @@ +# Copyright (c) 2016 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Entry-type module for 'u-boot-nodtb.bin' +# + +from entry import Entry +from blob import Entry_blob + +class Entry_u_boot_spl_nodtb(Entry_blob): + def __init__(self, image, etype, node): + Entry_blob.__init__(self, image, etype, node) + + def GetDefaultFilename(self): + return 'spl/u-boot-spl-nodtb.bin' diff --git a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py index 1c6706df6d..7b25ccb048 100644 --- a/tools/binman/etype/u_boot_spl_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_spl_with_ucode_ptr.py @@ -25,4 +25,4 @@ class Entry_u_boot_spl_with_ucode_ptr(Entry_u_boot_with_ucode_ptr): self.elf_fname = 'spl/u-boot-spl' def GetDefaultFilename(self): - return 'spl/u-boot-spl.bin' + return 'spl/u-boot-spl-nodtb.bin' diff --git a/tools/binman/etype/u_boot_ucode.py b/tools/binman/etype/u_boot_ucode.py index 8e51e99a11..f9f434d2cc 100644 --- a/tools/binman/etype/u_boot_ucode.py +++ b/tools/binman/etype/u_boot_ucode.py @@ -58,13 +58,10 @@ class Entry_u_boot_ucode(Entry_blob): def ObtainContents(self): # If the image does not need microcode, there is nothing to do ucode_dest_entry = self.image.FindEntryType('u-boot-with-ucode-ptr') - if ucode_dest_entry and not ucode_dest_entry.target_pos: - self.data = '' - return True - - # Handle microcode in SPL image as well - ucode_dest_entry = self.image.FindEntryType('u-boot-spl-with-ucode-ptr') - if ucode_dest_entry and not ucode_dest_entry.target_pos: + ucode_dest_entry_spl = self.image.FindEntryType( + 'u-boot-spl-with-ucode-ptr') + if ((not ucode_dest_entry or not ucode_dest_entry.target_pos) and + (not ucode_dest_entry_spl or not ucode_dest_entry_spl.target_pos)): self.data = '' return True diff --git a/tools/binman/etype/u_boot_with_ucode_ptr.py b/tools/binman/etype/u_boot_with_ucode_ptr.py index 6f01adb970..99b437130d 100644 --- a/tools/binman/etype/u_boot_with_ucode_ptr.py +++ b/tools/binman/etype/u_boot_with_ucode_ptr.py @@ -9,6 +9,7 @@ import struct import command +import elf from entry import Entry from blob import Entry_blob import fdt_util @@ -31,11 +32,9 @@ class Entry_u_boot_with_ucode_ptr(Entry_blob): def ObtainContents(self): # Figure out where to put the microcode pointer fname = tools.GetInputFilename(self.elf_fname) - args = [['nm', fname], ['grep', '-w', '_dt_ucode_base_size']] - out = (command.RunPipe(args, capture=True, raise_on_error=False). - stdout.splitlines()) - if len(out) == 1: - self.target_pos = int(out[0].split()[0], 16) + sym = elf.GetSymbolAddress(fname, '_dt_ucode_base_size') + if sym: + self.target_pos = sym elif not fdt_util.GetBool(self._node, 'optional-ucode'): self.Raise('Cannot locate _dt_ucode_base_size symbol in u-boot') diff --git a/tools/binman/func_test.py b/tools/binman/ftest.py index c4207ce5d2..5812ab397c 100644 --- a/tools/binman/func_test.py +++ b/tools/binman/ftest.py @@ -20,25 +20,29 @@ import binman import cmdline import command import control -import entry +import elf import fdt import fdt_util import tools import tout # Contents of test files, corresponding to different entry types -U_BOOT_DATA = '1234' -U_BOOT_IMG_DATA = 'img' -U_BOOT_SPL_DATA = '567' -BLOB_DATA = '89' -ME_DATA = '0abcd' -VGA_DATA = 'vga' -U_BOOT_DTB_DATA = 'udtb' -X86_START16_DATA = 'start16' -U_BOOT_NODTB_DATA = 'nodtb with microcode pointer somewhere in here' -FSP_DATA = 'fsp' -CMC_DATA = 'cmc' -VBT_DATA = 'vbt' +U_BOOT_DATA = '1234' +U_BOOT_IMG_DATA = 'img' +U_BOOT_SPL_DATA = '56780123456789abcde' +BLOB_DATA = '89' +ME_DATA = '0abcd' +VGA_DATA = 'vga' +U_BOOT_DTB_DATA = 'udtb' +U_BOOT_SPL_DTB_DATA = 'spldtb' +X86_START16_DATA = 'start16' +X86_START16_SPL_DATA = 'start16spl' +U_BOOT_NODTB_DATA = 'nodtb with microcode pointer somewhere in here' +U_BOOT_SPL_NODTB_DATA = 'splnodtb with microcode pointer somewhere in here' +FSP_DATA = 'fsp' +CMC_DATA = 'cmc' +VBT_DATA = 'vbt' +MRC_DATA = 'mrc' class TestFunctional(unittest.TestCase): """Functional tests for binman @@ -56,6 +60,9 @@ class TestFunctional(unittest.TestCase): """ @classmethod def setUpClass(self): + global entry + import entry + # Handle the case where argv[0] is 'python' self._binman_dir = os.path.dirname(os.path.realpath(sys.argv[0])) self._binman_pathname = os.path.join(self._binman_dir, 'binman') @@ -71,11 +78,17 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('me.bin', ME_DATA) TestFunctional._MakeInputFile('vga.bin', VGA_DATA) TestFunctional._MakeInputFile('u-boot.dtb', U_BOOT_DTB_DATA) + TestFunctional._MakeInputFile('spl/u-boot-spl.dtb', U_BOOT_SPL_DTB_DATA) TestFunctional._MakeInputFile('u-boot-x86-16bit.bin', X86_START16_DATA) + TestFunctional._MakeInputFile('spl/u-boot-x86-16bit-spl.bin', + X86_START16_SPL_DATA) TestFunctional._MakeInputFile('u-boot-nodtb.bin', U_BOOT_NODTB_DATA) + TestFunctional._MakeInputFile('spl/u-boot-spl-nodtb.bin', + U_BOOT_SPL_NODTB_DATA) TestFunctional._MakeInputFile('fsp.bin', FSP_DATA) TestFunctional._MakeInputFile('cmc.bin', CMC_DATA) TestFunctional._MakeInputFile('vbt.bin', VBT_DATA) + TestFunctional._MakeInputFile('mrc.bin', MRC_DATA) self._output_setup = False # ELF file with a '_dt_ucode_base_size' symbol @@ -124,7 +137,10 @@ class TestFunctional(unittest.TestCase): Returns: Return value (0 for success) """ - (options, args) = cmdline.ParseArgs(list(args)) + args = list(args) + if '-D' in sys.argv: + args = args + ['-D'] + (options, args) = cmdline.ParseArgs(args) options.pager = 'binman-invalid-pager' options.build_dir = self._indir @@ -132,14 +148,16 @@ class TestFunctional(unittest.TestCase): # options.verbosity = tout.DEBUG return control.Binman(options, args) - def _DoTestFile(self, fname): + def _DoTestFile(self, fname, debug=False): """Run binman with a given test file Args: fname: Device tree source filename to use (e.g. 05_simple.dts) """ - return self._DoBinman('-p', '-I', self._indir, - '-d', self.TestFile(fname)) + args = ['-p', '-I', self._indir, '-d', self.TestFile(fname)] + if debug: + args.append('-D') + return self._DoBinman(*args) def _SetupDtb(self, fname, outfile='u-boot.dtb'): """Set up a new test device-tree file @@ -292,7 +310,6 @@ class TestFunctional(unittest.TestCase): self.assertEqual(0, len(result.stderr)) self.assertEqual(0, result.return_code) - # Not yet available. def testBoard(self): """Test that we can run it with a specific board""" self._SetupDtb('05_simple.dts', 'sandbox/u-boot.dtb') @@ -352,6 +369,10 @@ class TestFunctional(unittest.TestCase): data = self._DoReadFile('05_simple.dts') self.assertEqual(U_BOOT_DATA, data) + def testSimpleDebug(self): + """Test a simple binman run with debugging enabled""" + data = self._DoTestFile('05_simple.dts', debug=True) + def testDual(self): """Test that we can handle creating two images @@ -553,8 +574,10 @@ class TestFunctional(unittest.TestCase): def testImagePadByte(self): """Test that the image pad byte can be specified""" + with open(self.TestFile('bss_data')) as fd: + TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) data = self._DoReadFile('21_image_pad.dts') - self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 9) + U_BOOT_DATA, data) + self.assertEqual(U_BOOT_SPL_DATA + (chr(0xff) * 1) + U_BOOT_DATA, data) def testImageName(self): """Test that image files can be named""" @@ -576,7 +599,7 @@ class TestFunctional(unittest.TestCase): def testPackSorted(self): """Test that entries can be sorted""" data = self._DoReadFile('24_sorted.dts') - self.assertEqual(chr(0) * 5 + U_BOOT_SPL_DATA + chr(0) * 2 + + self.assertEqual(chr(0) * 1 + U_BOOT_SPL_DATA + chr(0) * 2 + U_BOOT_DATA, data) def testPackZeroPosition(self): @@ -604,14 +627,14 @@ class TestFunctional(unittest.TestCase): with self.assertRaises(ValueError) as e: self._DoTestFile('28_pack_4gb_outside.dts') self.assertIn("Node '/binman/u-boot': Position 0x0 (0) is outside " - "the image starting at 0xfffffff0 (4294967280)", + "the image starting at 0xffffffe0 (4294967264)", str(e.exception)) def testPackX86Rom(self): """Test that a basic x86 ROM can be created""" data = self._DoReadFile('29_x86-rom.dts') - self.assertEqual(U_BOOT_DATA + chr(0) * 3 + U_BOOT_SPL_DATA + - chr(0) * 6, data) + self.assertEqual(U_BOOT_DATA + chr(0) * 7 + U_BOOT_SPL_DATA + + chr(0) * 2, data) def testPackX86RomMeNoDesc(self): """Test that an invalid Intel descriptor entry is detected""" @@ -644,19 +667,11 @@ class TestFunctional(unittest.TestCase): data = self._DoReadFile('33_x86-start16.dts') self.assertEqual(X86_START16_DATA, data[:len(X86_START16_DATA)]) - def testPackUbootMicrocode(self): - """Test that x86 microcode can be handled correctly - - We expect to see the following in the image, in order: - u-boot-nodtb.bin with a microcode pointer inserted at the correct - place - u-boot.dtb with the microcode removed - the microcode - """ - data = self._DoReadFile('34_x86_ucode.dts', True) + def _RunMicrocodeTest(self, dts_fname, nodtb_data): + data = self._DoReadFile(dts_fname, True) # Now check the device tree has no microcode - second = data[len(U_BOOT_NODTB_DATA):] + second = data[len(nodtb_data):] fname = tools.GetOutputFilename('test.dtb') with open(fname, 'wb') as fd: fd.write(second) @@ -671,17 +686,30 @@ class TestFunctional(unittest.TestCase): # Check that the microcode appears immediately after the Fdt # This matches the concatenation of the data properties in - # the /microcode/update@xxx nodes in x86_ucode.dts. + # the /microcode/update@xxx nodes in 34_x86_ucode.dts. ucode_data = struct.pack('>4L', 0x12345678, 0x12345679, 0xabcd0000, 0x78235609) self.assertEqual(ucode_data, third[:len(ucode_data)]) - ucode_pos = len(U_BOOT_NODTB_DATA) + fdt_len + ucode_pos = len(nodtb_data) + fdt_len # Check that the microcode pointer was inserted. It should match the # expected position and size pos_and_size = struct.pack('<2L', 0xfffffe00 + ucode_pos, len(ucode_data)) - first = data[:len(U_BOOT_NODTB_DATA)] + first = data[:len(nodtb_data)] + return first, pos_and_size + + def testPackUbootMicrocode(self): + """Test that x86 microcode can be handled correctly + + We expect to see the following in the image, in order: + u-boot-nodtb.bin with a microcode pointer inserted at the correct + place + u-boot.dtb with the microcode removed + the microcode + """ + first, pos_and_size = self._RunMicrocodeTest('34_x86_ucode.dts', + U_BOOT_NODTB_DATA) self.assertEqual('nodtb with microcode' + pos_and_size + ' somewhere in here', first) @@ -811,3 +839,75 @@ class TestFunctional(unittest.TestCase): """Test that an image with a VBT binary can be created""" data = self._DoReadFile('46_intel-vbt.dts') self.assertEqual(VBT_DATA, data[:len(VBT_DATA)]) + + def testSplBssPad(self): + """Test that we can pad SPL's BSS with zeros""" + # ELF file with a '__bss_size' symbol + with open(self.TestFile('bss_data')) as fd: + TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) + data = self._DoReadFile('47_spl_bss_pad.dts') + self.assertEqual(U_BOOT_SPL_DATA + (chr(0) * 10) + U_BOOT_DATA, data) + + with open(self.TestFile('u_boot_ucode_ptr')) as fd: + TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) + with self.assertRaises(ValueError) as e: + data = self._DoReadFile('47_spl_bss_pad.dts') + self.assertIn('Expected __bss_size symbol in spl/u-boot-spl', + str(e.exception)) + + def testPackStart16Spl(self): + """Test that an image with an x86 start16 region can be created""" + data = self._DoReadFile('48_x86-start16-spl.dts') + self.assertEqual(X86_START16_SPL_DATA, data[:len(X86_START16_SPL_DATA)]) + + def testPackUbootSplMicrocode(self): + """Test that x86 microcode can be handled correctly in SPL + + We expect to see the following in the image, in order: + u-boot-spl-nodtb.bin with a microcode pointer inserted at the + correct place + u-boot.dtb with the microcode removed + the microcode + """ + # ELF file with a '_dt_ucode_base_size' symbol + with open(self.TestFile('u_boot_ucode_ptr')) as fd: + TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) + first, pos_and_size = self._RunMicrocodeTest('49_x86_ucode_spl.dts', + U_BOOT_SPL_NODTB_DATA) + self.assertEqual('splnodtb with microc' + pos_and_size + + 'ter somewhere in here', first) + + def testPackMrc(self): + """Test that an image with an MRC binary can be created""" + data = self._DoReadFile('50_intel_mrc.dts') + self.assertEqual(MRC_DATA, data[:len(MRC_DATA)]) + + def testSplDtb(self): + """Test that an image with spl/u-boot-spl.dtb can be created""" + data = self._DoReadFile('51_u_boot_spl_dtb.dts') + self.assertEqual(U_BOOT_SPL_DTB_DATA, data[:len(U_BOOT_SPL_DTB_DATA)]) + + def testSplNoDtb(self): + """Test that an image with spl/u-boot-spl-nodtb.bin can be created""" + data = self._DoReadFile('52_u_boot_spl_nodtb.dts') + self.assertEqual(U_BOOT_SPL_NODTB_DATA, data[:len(U_BOOT_SPL_NODTB_DATA)]) + + def testSymbols(self): + """Test binman can assign symbols embedded in U-Boot""" + elf_fname = self.TestFile('u_boot_binman_syms') + syms = elf.GetSymbols(elf_fname, ['binman', 'image']) + addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start') + self.assertEqual(syms['_binman_u_boot_spl_prop_pos'].address, addr) + + with open(self.TestFile('u_boot_binman_syms')) as fd: + TestFunctional._MakeInputFile('spl/u-boot-spl', fd.read()) + data = self._DoReadFile('53_symbols.dts') + sym_values = struct.pack('<LQL', 0x24 + 0, 0x24 + 24, 0x24 + 20) + expected = (sym_values + U_BOOT_SPL_DATA[16:] + chr(0xff) + + U_BOOT_DATA + + sym_values + U_BOOT_SPL_DATA[16:]) + self.assertEqual(expected, data) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/binman/image.py b/tools/binman/image.py index 07fc930665..741630f091 100644 --- a/tools/binman/image.py +++ b/tools/binman/image.py @@ -6,11 +6,13 @@ # Class for an image, the output of binman # +from __future__ import print_function + from collections import OrderedDict from operator import attrgetter +import re +import sys -import entry -from entry import Entry import fdt_util import tools @@ -47,7 +49,12 @@ class Image: address. _entries: OrderedDict() of entries """ - def __init__(self, name, node): + def __init__(self, name, node, test=False): + global entry + global Entry + import entry + from entry import Entry + self._node = node self._name = name self._size = None @@ -61,8 +68,9 @@ class Image: self._end_4gb = False self._entries = OrderedDict() - self._ReadNode() - self._ReadEntries() + if not test: + self._ReadNode() + self._ReadEntries() def _ReadNode(self): """Read properties from the image node""" @@ -116,6 +124,14 @@ class Image: """ raise ValueError("Image '%s': %s" % (self._node.path, msg)) + def GetPath(self): + """Get the path of an image (in the FDT) + + Returns: + Full path of the node for this image + """ + return self._node.path + def _ReadEntries(self): for node in self._node.subnodes: self._entries[node.name] = Entry.Create(self, node) @@ -217,6 +233,11 @@ class Image: for entry in self._entries.values(): entry.ProcessContents() + def WriteSymbols(self): + """Write symbol values into binary files for access at run time""" + for entry in self._entries.values(): + entry.WriteSymbols(self) + def BuildImage(self): """Write the image to a file""" fname = tools.GetOutputFilename(self._filename) @@ -227,3 +248,58 @@ class Image: data = entry.GetData() fd.seek(self._pad_before + entry.pos - self._skip_at_start) fd.write(data) + + def LookupSymbol(self, sym_name, optional, msg): + """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 pos. + + Args: + sym_name: Symbol name in the ELF file to look up in the format + _binman_<entry>_prop_<property> where <entry> is the name of + the entry and <property> is the property to find (e.g. + _binman_u_boot_prop_pos). As a special case, you can append + _any to <entry> to have it search for any matching entry. E.g. + _binman_u_boot_any_prop_pos will match entries called u-boot, + u-boot-img and u-boot-nodtb) + 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 + + Returns: + Value that should be assigned to that symbol, or None if it was + optional and not found + + Raises: + ValueError if the symbol is invalid or not found, or references a + property which is not supported + """ + m = re.match(r'^_binman_(\w+)_prop_(\w+)$', sym_name) + if not m: + raise ValueError("%s: Symbol '%s' has invalid format" % + (msg, sym_name)) + entry_name, prop_name = m.groups() + entry_name = entry_name.replace('_', '-') + entry = self._entries.get(entry_name) + if not entry: + if entry_name.endswith('-any'): + root = entry_name[:-4] + for name in self._entries: + if name.startswith(root): + rest = name[len(root):] + if rest in ['', '-img', '-nodtb']: + entry = self._entries[name] + if not entry: + err = ("%s: Entry '%s' not found in list (%s)" % + (msg, entry_name, ','.join(self._entries.keys()))) + if optional: + print('Warning: %s' % err, file=sys.stderr) + return None + raise ValueError(err) + if prop_name == 'pos': + return entry.pos + else: + raise ValueError("%s: No such property '%s'" % (msg, prop_name)) diff --git a/tools/binman/image_test.py b/tools/binman/image_test.py new file mode 100644 index 0000000000..1b50dda4dc --- /dev/null +++ b/tools/binman/image_test.py @@ -0,0 +1,46 @@ +# +# Copyright (c) 2017 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# SPDX-License-Identifier: GPL-2.0+ +# +# Test for the image module + +import unittest + +from image import Image +from elf_test import capture_sys_output + +class TestImage(unittest.TestCase): + def testInvalidFormat(self): + image = Image('name', 'node', test=True) + with self.assertRaises(ValueError) as e: + image.LookupSymbol('_binman_something_prop_', False, 'msg') + self.assertIn( + "msg: Symbol '_binman_something_prop_' has invalid format", + str(e.exception)) + + def testMissingSymbol(self): + image = Image('name', 'node', test=True) + image._entries = {} + with self.assertRaises(ValueError) as e: + image.LookupSymbol('_binman_type_prop_pname', False, 'msg') + self.assertIn("msg: Entry 'type' not found in list ()", + str(e.exception)) + + def testMissingSymbolOptional(self): + image = Image('name', 'node', test=True) + image._entries = {} + with capture_sys_output() as (stdout, stderr): + val = image.LookupSymbol('_binman_type_prop_pname', True, 'msg') + self.assertEqual(val, None) + self.assertEqual("Warning: msg: Entry 'type' not found in list ()\n", + stderr.getvalue()) + self.assertEqual('', stdout.getvalue()) + + def testBadProperty(self): + image = Image('name', 'node', test=True) + image._entries = {'u-boot': 1} + with self.assertRaises(ValueError) as e: + image.LookupSymbol('_binman_u_boot_prop_bad', False, 'msg') + self.assertIn("msg: No such property 'bad", str(e.exception)) diff --git a/tools/binman/test/21_image_pad.dts b/tools/binman/test/21_image_pad.dts index daf8385f6d..bf39dc1b6f 100644 --- a/tools/binman/test/21_image_pad.dts +++ b/tools/binman/test/21_image_pad.dts @@ -10,7 +10,7 @@ }; u-boot { - pos = <12>; + pos = <20>; }; }; }; diff --git a/tools/binman/test/24_sorted.dts b/tools/binman/test/24_sorted.dts index 9f4151c932..43a7831341 100644 --- a/tools/binman/test/24_sorted.dts +++ b/tools/binman/test/24_sorted.dts @@ -7,11 +7,11 @@ binman { sort-by-pos; u-boot { - pos = <10>; + pos = <22>; }; u-boot-spl { - pos = <5>; + pos = <1>; }; }; }; diff --git a/tools/binman/test/28_pack_4gb_outside.dts b/tools/binman/test/28_pack_4gb_outside.dts index ff468c7d41..18d6bb5b8a 100644 --- a/tools/binman/test/28_pack_4gb_outside.dts +++ b/tools/binman/test/28_pack_4gb_outside.dts @@ -7,13 +7,13 @@ binman { sort-by-pos; end-at-4gb; - size = <16>; + size = <32>; u-boot { pos = <0>; }; u-boot-spl { - pos = <0xfffffff7>; + pos = <0xffffffeb>; }; }; }; diff --git a/tools/binman/test/29_x86-rom.dts b/tools/binman/test/29_x86-rom.dts index 075ede36ab..d49078e19e 100644 --- a/tools/binman/test/29_x86-rom.dts +++ b/tools/binman/test/29_x86-rom.dts @@ -7,13 +7,13 @@ binman { sort-by-pos; end-at-4gb; - size = <16>; + size = <32>; u-boot { - pos = <0xfffffff0>; + pos = <0xffffffe0>; }; u-boot-spl { - pos = <0xfffffff7>; + pos = <0xffffffeb>; }; }; }; diff --git a/tools/binman/test/47_spl_bss_pad.dts b/tools/binman/test/47_spl_bss_pad.dts new file mode 100644 index 0000000000..6bd88b83f9 --- /dev/null +++ b/tools/binman/test/47_spl_bss_pad.dts @@ -0,0 +1,17 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + u-boot-spl { + }; + + u-boot-spl-bss-pad { + }; + + u-boot { + }; + }; +}; diff --git a/tools/binman/test/48_x86-start16-spl.dts b/tools/binman/test/48_x86-start16-spl.dts new file mode 100644 index 0000000000..e2009f15f0 --- /dev/null +++ b/tools/binman/test/48_x86-start16-spl.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + x86-start16-spl { + }; + }; +}; diff --git a/tools/binman/test/49_x86_ucode_spl.dts b/tools/binman/test/49_x86_ucode_spl.dts new file mode 100644 index 0000000000..67db93ad50 --- /dev/null +++ b/tools/binman/test/49_x86_ucode_spl.dts @@ -0,0 +1,29 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + sort-by-pos; + end-at-4gb; + size = <0x200>; + u-boot-spl-with-ucode-ptr { + }; + + u-boot-dtb-with-ucode { + }; + + u-boot-ucode { + }; + }; + + microcode { + update@0 { + data = <0x12345678 0x12345679>; + }; + update@1 { + data = <0xabcd0000 0x78235609>; + }; + }; +}; diff --git a/tools/binman/test/50_intel_mrc.dts b/tools/binman/test/50_intel_mrc.dts new file mode 100644 index 0000000000..54cd52a2b7 --- /dev/null +++ b/tools/binman/test/50_intel_mrc.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-mrc { + }; + }; +}; diff --git a/tools/binman/test/51_u_boot_spl_dtb.dts b/tools/binman/test/51_u_boot_spl_dtb.dts new file mode 100644 index 0000000000..3912f86b4c --- /dev/null +++ b/tools/binman/test/51_u_boot_spl_dtb.dts @@ -0,0 +1,13 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + u-boot-spl-dtb { + }; + }; +}; diff --git a/tools/binman/test/52_u_boot_spl_nodtb.dts b/tools/binman/test/52_u_boot_spl_nodtb.dts new file mode 100644 index 0000000000..7f4e27780f --- /dev/null +++ b/tools/binman/test/52_u_boot_spl_nodtb.dts @@ -0,0 +1,11 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + u-boot-spl-nodtb { + }; + }; +}; diff --git a/tools/binman/test/53_symbols.dts b/tools/binman/test/53_symbols.dts new file mode 100644 index 0000000000..980b066eb2 --- /dev/null +++ b/tools/binman/test/53_symbols.dts @@ -0,0 +1,20 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + pad-byte = <0xff>; + u-boot-spl { + }; + + u-boot { + pos = <20>; + }; + + u-boot-spl2 { + type = "u-boot-spl"; + }; + }; +}; diff --git a/tools/binman/test/Makefile b/tools/binman/test/Makefile new file mode 100644 index 0000000000..e58fc80775 --- /dev/null +++ b/tools/binman/test/Makefile @@ -0,0 +1,55 @@ +# +# Builds test programs +# +# Copyright (C) 2017 Google, Inc +# Written by Simon Glass <sjg@chromium.org> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +CFLAGS := -march=i386 -m32 -nostdlib -I ../../../include + +LDS_UCODE := -T u_boot_ucode_ptr.lds +LDS_BINMAN := -T u_boot_binman_syms.lds +LDS_BINMAN_BAD := -T u_boot_binman_syms_bad.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 + +all: $(TARGETS) + +u_boot_no_ucode_ptr: CFLAGS += $(LDS_UCODE) +u_boot_no_ucode_ptr: u_boot_no_ucode_ptr.c + +u_boot_ucode_ptr: CFLAGS += $(LDS_UCODE) +u_boot_ucode_ptr: u_boot_ucode_ptr.c + +bss_data: CFLAGS += bss_data.lds +bss_data: bss_data.c + +u_boot_binman_syms.bin: u_boot_binman_syms + objcopy -O binary $< -R .note.gnu.build-id $@ + +u_boot_binman_syms: CFLAGS += $(LDS_BINMAN) +u_boot_binman_syms: u_boot_binman_syms.c + +u_boot_binman_syms_bad: CFLAGS += $(LDS_BINMAN_BAD) +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 + +clean: + rm -f $(TARGETS) + +help: + @echo "Makefile for binman test programs" + @echo + @echo "Intended for use on x86 hosts" + @echo + @echo "Targets:" + @echo + @echo -e "\thelp - Print help (this is it!)" + @echo -e "\tall - Builds test programs (default targget)" + @echo -e "\tclean - Delete output files" diff --git a/tools/binman/test/bss_data b/tools/binman/test/bss_data Binary files differnew file mode 100755 index 0000000000..afa28282aa --- /dev/null +++ b/tools/binman/test/bss_data diff --git a/tools/binman/test/bss_data.c b/tools/binman/test/bss_data.c new file mode 100644 index 0000000000..e0305c382c --- /dev/null +++ b/tools/binman/test/bss_data.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Simple program to create a _dt_ucode_base_size symbol which can be read + * by binutils. This is used by binman tests. + */ + +int bss_data[10]; +int __bss_size = sizeof(bss_data); + +int main() +{ + bss_data[2] = 2; + + return 0; +} diff --git a/tools/binman/test/bss_data.lds b/tools/binman/test/bss_data.lds new file mode 100644 index 0000000000..6b2fe09d35 --- /dev/null +++ b/tools/binman/test/bss_data.lds @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + . = 0xfffffdf0; + _start = .; + __bss_size = 10; +} diff --git a/tools/binman/test/u_boot_binman_syms b/tools/binman/test/u_boot_binman_syms Binary files differnew file mode 100755 index 0000000000..2e02dc0ca9 --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms diff --git a/tools/binman/test/u_boot_binman_syms.c b/tools/binman/test/u_boot_binman_syms.c new file mode 100644 index 0000000000..a975476944 --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Simple program to create some binman symbols. This is used by binman tests. + */ + +#define CONFIG_BINMAN +#include <binman_sym.h> + +binman_sym_declare(unsigned long, u_boot_spl, pos); +binman_sym_declare(unsigned long long, u_boot_spl2, pos); +binman_sym_declare(unsigned long, u_boot_any, pos); diff --git a/tools/binman/test/u_boot_binman_syms.lds b/tools/binman/test/u_boot_binman_syms.lds new file mode 100644 index 0000000000..d3130cdeb3 --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms.lds @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + . = 0x00000000; + _start = .; + + . = ALIGN(4); + .text : + { + __image_copy_start = .; + *(.text*) + } + + . = ALIGN(4); + .binman_sym_table : { + __binman_sym_start = .; + KEEP(*(SORT(.binman_sym*))); + __binman_sym_end = .; + } + +} diff --git a/tools/binman/test/u_boot_binman_syms_bad b/tools/binman/test/u_boot_binman_syms_bad Binary files differnew file mode 100755 index 0000000000..8da3d9d48f --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms_bad diff --git a/tools/binman/test/u_boot_binman_syms_bad.c b/tools/binman/test/u_boot_binman_syms_bad.c new file mode 120000 index 0000000000..939b2e965f --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms_bad.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_bad.lds b/tools/binman/test/u_boot_binman_syms_bad.lds new file mode 100644 index 0000000000..0b474b5374 --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms_bad.lds @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +SECTIONS +{ + . = 0x00000000; + _start = .; + + . = ALIGN(4); + .text : + { + *(.text*) + } + + . = ALIGN(4); + .binman_sym_table : { + __binman_sym_start = .; + KEEP(*(SORT(.binman_sym*))); + __binman_sym_end = .; + } + +} diff --git a/tools/binman/test/u_boot_binman_syms_size b/tools/binman/test/u_boot_binman_syms_size Binary files differnew file mode 100755 index 0000000000..d691e897c0 --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms_size diff --git a/tools/binman/test/u_boot_binman_syms_size.c b/tools/binman/test/u_boot_binman_syms_size.c new file mode 100644 index 0000000000..ee4c048b28 --- /dev/null +++ b/tools/binman/test/u_boot_binman_syms_size.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2017 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Simple program to create some binman symbols. This is used by binman tests. + */ + +#define CONFIG_BINMAN +#include <binman_sym.h> + +binman_sym_declare(char, u_boot_spl, pos); diff --git a/tools/binman/test/u_boot_no_ucode_ptr.c b/tools/binman/test/u_boot_no_ucode_ptr.c index a17bb4c6c2..c4a2b85fc9 100644 --- a/tools/binman/test/u_boot_no_ucode_ptr.c +++ b/tools/binman/test/u_boot_no_ucode_ptr.c @@ -5,10 +5,6 @@ * * Simple program to create a bad _dt_ucode_base_size symbol to create an * error when it is used. This is used by binman tests. - * - * Build with: - * cc -march=i386 -m32 -o u_boot_no_ucode_ptr -T u_boot_ucode_ptr.lds \ - -nostdlib u_boot_no_ucode_ptr.c */ static unsigned long not__dt_ucode_base_size[2] diff --git a/tools/binman/test/u_boot_ucode_ptr.c b/tools/binman/test/u_boot_ucode_ptr.c index 434c9f4400..734d54f0d4 100644 --- a/tools/binman/test/u_boot_ucode_ptr.c +++ b/tools/binman/test/u_boot_ucode_ptr.c @@ -4,11 +4,7 @@ * SPDX-License-Identifier: GPL-2.0+ * * Simple program to create a _dt_ucode_base_size symbol which can be read - * by 'nm'. This is used by binman tests. - * - * Build with: - * cc -march=i386 -m32 -o u_boot_ucode_ptr -T u_boot_ucode_ptr.lds -nostdlib \ - u_boot_ucode_ptr.c + * by binutils. This is used by binman tests. */ static unsigned long _dt_ucode_base_size[2] |