summaryrefslogtreecommitdiff
path: root/tools/binman
diff options
context:
space:
mode:
Diffstat (limited to 'tools/binman')
-rw-r--r--tools/binman/README56
-rwxr-xr-xtools/binman/binman.py49
-rw-r--r--tools/binman/control.py3
-rw-r--r--tools/binman/elf.py129
-rw-r--r--tools/binman/elf_test.py122
-rw-r--r--tools/binman/entry_test.py36
-rw-r--r--tools/binman/etype/entry.py8
-rw-r--r--tools/binman/etype/u_boot_spl.py6
-rw-r--r--tools/binman/etype/u_boot_spl_bss_pad.py7
-rw-r--r--tools/binman/etype/u_boot_spl_dtb.py17
-rw-r--r--tools/binman/etype/u_boot_spl_nodtb.py17
-rw-r--r--tools/binman/etype/u_boot_spl_with_ucode_ptr.py2
-rw-r--r--tools/binman/etype/u_boot_ucode.py11
-rw-r--r--tools/binman/etype/u_boot_with_ucode_ptr.py9
-rw-r--r--tools/binman/ftest.py (renamed from tools/binman/func_test.py)174
-rw-r--r--tools/binman/image.py86
-rw-r--r--tools/binman/image_test.py46
-rw-r--r--tools/binman/test/21_image_pad.dts2
-rw-r--r--tools/binman/test/24_sorted.dts4
-rw-r--r--tools/binman/test/28_pack_4gb_outside.dts4
-rw-r--r--tools/binman/test/29_x86-rom.dts6
-rw-r--r--tools/binman/test/47_spl_bss_pad.dts17
-rw-r--r--tools/binman/test/48_x86-start16-spl.dts13
-rw-r--r--tools/binman/test/49_x86_ucode_spl.dts29
-rw-r--r--tools/binman/test/50_intel_mrc.dts13
-rw-r--r--tools/binman/test/51_u_boot_spl_dtb.dts13
-rw-r--r--tools/binman/test/52_u_boot_spl_nodtb.dts11
-rw-r--r--tools/binman/test/53_symbols.dts20
-rw-r--r--tools/binman/test/Makefile55
-rwxr-xr-xtools/binman/test/bss_databin0 -> 5020 bytes
-rw-r--r--tools/binman/test/bss_data.c18
-rw-r--r--tools/binman/test/bss_data.lds16
-rwxr-xr-xtools/binman/test/u_boot_binman_symsbin0 -> 4921 bytes
-rw-r--r--tools/binman/test/u_boot_binman_syms.c14
-rw-r--r--tools/binman/test/u_boot_binman_syms.lds30
-rwxr-xr-xtools/binman/test/u_boot_binman_syms_badbin0 -> 4890 bytes
l---------tools/binman/test/u_boot_binman_syms_bad.c1
-rw-r--r--tools/binman/test/u_boot_binman_syms_bad.lds29
-rwxr-xr-xtools/binman/test/u_boot_binman_syms_sizebin0 -> 4825 bytes
-rw-r--r--tools/binman/test/u_boot_binman_syms_size.c12
-rw-r--r--tools/binman/test/u_boot_no_ucode_ptr.c4
-rw-r--r--tools/binman/test/u_boot_ucode_ptr.c6
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
new file mode 100755
index 0000000000..afa28282aa
--- /dev/null
+++ b/tools/binman/test/bss_data
Binary files differ
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
new file mode 100755
index 0000000000..2e02dc0ca9
--- /dev/null
+++ b/tools/binman/test/u_boot_binman_syms
Binary files differ
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
new file mode 100755
index 0000000000..8da3d9d48f
--- /dev/null
+++ b/tools/binman/test/u_boot_binman_syms_bad
Binary files differ
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
new file mode 100755
index 0000000000..d691e897c0
--- /dev/null
+++ b/tools/binman/test/u_boot_binman_syms_size
Binary files differ
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]