[PATCH v8 06/13] binman: Support new op-tee binary format
Jerome Forissier
jerome.forissier at linaro.org
Thu Dec 22 23:20:04 CET 2022
On 12/22/22 21:23, Simon Glass wrote:
> (dropping the two bounces from cc)
>
> On Thu, 22 Dec 2022 at 13:18, Simon Glass <sjg at chromium.org> wrote:
>>
>> Hi Jerome,
>>
>> On Thu, 22 Dec 2022 at 08:36, Jerome Forissier
>> <jerome.forissier at linaro.org> wrote:
>>>
>>>
>>>
>>> On 12/22/22 00:07, Simon Glass wrote:
>>>> OP-TEE has a format with a binary header that can be used instead of the
>>>> ELF file. With newer versions of OP-TEE this may be required on some
>>>> platforms.
>>>>
>>>> Add support for this in binman. First, add a method to obtain the ELF
>>>> sections from an entry, then use that in the FIT support. We then end up
>>>> with the ability to support both types of OP-TEE files, depending on which
>>>> one is passed in with the entry argument (TEE=xxx in the U-Boot build).
>>>
>>> So, with:
>>>
>>> BL31=/path/to/bl31.elf TEE=/path/to/tee.bin make -C u-boot \
>>> CROSS_COMPILE=aarch64-linux-gnu- CC=aarch64-linux-gnu-gcc \
>>> HOSTCC=gcc BINMAN_DEBUG=1 BINMAN_VERBOSE=4
>>>
>>>
>>> ...I get:
>>>
>>> Entry '/binman/simple-bin/fit/images/@tee-SEQ/tee-os' marked absent: uses v1 format which must be in a FIT
>>>
>>>
>>> More complete log at https://pastebin.com/UZzZeicQ
>>
>> Thanks.
>>
>> Is this file in the v1 binary format (with the custom header),
Yes
>> or is
>> is a plain binary file? At present only the former is supported, as I
>> thought that it can only be the elf or the v1 binary format these
>> days?
Correct
>> Actually can you please send me the tee.bin ?
Sure, here you go: https://ufile.io/f/ex5oy
I have added bl31.elf too, although I suppose it is handled properly
being an ELF file.
Thanks,
--
Jerome
>> Regards,
>> Simon
>>
>>
>>>
>>> Thanks,
>>> --
>>> Jerome
>>>
>>>> Signed-off-by: Simon Glass <sjg at chromium.org>
>>>> ---
>>>>
>>>> (no changes since v7)
>>>>
>>>> Changes in v7:
>>>> - Correct missing test coverage
>>>>
>>>> Changes in v6:
>>>> - Update op-tee to support new v1 binary header
>>>>
>>>> tools/binman/entries.rst | 35 ++++++++-
>>>> tools/binman/entry.py | 13 +++
>>>> tools/binman/etype/fit.py | 69 +++++++++-------
>>>> tools/binman/etype/section.py | 9 +++
>>>> tools/binman/etype/tee_os.py | 68 +++++++++++++++-
>>>> tools/binman/ftest.py | 83 ++++++++++++++++++++
>>>> tools/binman/test/263_tee_os_opt.dts | 22 ++++++
>>>> tools/binman/test/264_tee_os_opt_fit.dts | 33 ++++++++
>>>> tools/binman/test/265_tee_os_opt_fit_bad.dts | 40 ++++++++++
>>>> 9 files changed, 340 insertions(+), 32 deletions(-)
>>>> create mode 100644 tools/binman/test/263_tee_os_opt.dts
>>>> create mode 100644 tools/binman/test/264_tee_os_opt_fit.dts
>>>> create mode 100644 tools/binman/test/265_tee_os_opt_fit_bad.dts
>>>>
>>>> diff --git a/tools/binman/entries.rst b/tools/binman/entries.rst
>>>> index b2ce7960d3b..a3e4493a44f 100644
>>>> --- a/tools/binman/entries.rst
>>>> +++ b/tools/binman/entries.rst
>>>> @@ -1508,12 +1508,45 @@ Entry: tee-os: Entry containing an OP-TEE Trusted OS (TEE) blob
>>>>
>>>> Properties / Entry arguments:
>>>> - tee-os-path: Filename of file to read into entry. This is typically
>>>> - called tee-pager.bin
>>>> + called tee.bin or tee.elf
>>>>
>>>> This entry holds the run-time firmware, typically started by U-Boot SPL.
>>>> See the U-Boot README for your architecture or board for how to use it. See
>>>> https://github.com/OP-TEE/optee_os for more information about OP-TEE.
>>>>
>>>> +Note that if the file is in ELF format, it must go in a FIT. In that case,
>>>> +this entry will mark itself as absent, providing the data only through the
>>>> +read_elf_segments() method.
>>>> +
>>>> +Marking this entry as absent means that it if is used in the wrong context
>>>> +it can be automatically dropped. Thus it is possible to add anb OP-TEE entry
>>>> +like this::
>>>> +
>>>> + binman {
>>>> + tee-os {
>>>> + };
>>>> + };
>>>> +
>>>> +and pass either an ELF or plain binary in with -a tee-os-path <filename>
>>>> +and have binman do the right thing:
>>>> +
>>>> + - include the entry if tee.bin is provided and it doesn't have the v1
>>>> + header
>>>> + - drop it otherwise
>>>> +
>>>> +When used within a FIT, we can do::
>>>> +
>>>> + binman {
>>>> + fit {
>>>> + tee-os {
>>>> + };
>>>> + };
>>>> + };
>>>> +
>>>> +which will split the ELF into separate nodes for each segment, if an ELF
>>>> +file is provide (see Flat Image Tree / FIT), or produce a single node if
>>>> +the binary v1 format is provided.
>>>> +
>>>>
>>>>
>>>> .. _etype_text:
>>>> diff --git a/tools/binman/entry.py b/tools/binman/entry.py
>>>> index 637aece3705..de51d295891 100644
>>>> --- a/tools/binman/entry.py
>>>> +++ b/tools/binman/entry.py
>>>> @@ -1290,3 +1290,16 @@ features to produce new behaviours.
>>>> def mark_absent(self, msg):
>>>> tout.info("Entry '%s' marked absent: %s" % (self._node.path, msg))
>>>> self.absent = True
>>>> +
>>>> + def read_elf_segments(self):
>>>> + """Read segments from an entry that can generate an ELF file
>>>> +
>>>> + Returns:
>>>> + tuple:
>>>> + list of segments, each:
>>>> + int: Segment number (0 = first)
>>>> + int: Start address of segment in memory
>>>> + bytes: Contents of segment
>>>> + int: entry address of ELF file
>>>> + """
>>>> + return None
>>>> diff --git a/tools/binman/etype/fit.py b/tools/binman/etype/fit.py
>>>> index 8ad4f3a8a83..21c769a1cbe 100644
>>>> --- a/tools/binman/etype/fit.py
>>>> +++ b/tools/binman/etype/fit.py
>>>> @@ -540,41 +540,34 @@ class Entry_fit(Entry_section):
>>>> else:
>>>> self.Raise("Generator node requires 'fit,fdt-list' property")
>>>>
>>>> - def _gen_split_elf(base_node, node, elf_data, missing):
>>>> + def _gen_split_elf(base_node, node, segments, entry_addr):
>>>> """Add nodes for the ELF file, one per group of contiguous segments
>>>>
>>>> Args:
>>>> base_node (Node): Template node from the binman definition
>>>> node (Node): Node to replace (in the FIT being built)
>>>> - data (bytes): ELF-format data to process (may be empty)
>>>> - missing (bool): True if any of the data is missing
>>>>
>>>> + segments, entry_addr
>>>> +
>>>> + data (bytes): ELF-format data to process (may be empty)
>>>> """
>>>> - # If any pieces are missing, skip this. The missing entries will
>>>> - # show an error
>>>> - if not missing:
>>>> - try:
>>>> - segments, entry = elf.read_loadable_segments(elf_data)
>>>> - except ValueError as exc:
>>>> - self._raise_subnode(node,
>>>> - f'Failed to read ELF file: {str(exc)}')
>>>> - for (seq, start, data) in segments:
>>>> - node_name = node.name[1:].replace('SEQ', str(seq + 1))
>>>> - with fsw.add_node(node_name):
>>>> - loadables.append(node_name)
>>>> - for pname, prop in node.props.items():
>>>> - if not pname.startswith('fit,'):
>>>> - fsw.property(pname, prop.bytes)
>>>> - elif pname == 'fit,load':
>>>> - fsw.property_u32('load', start)
>>>> - elif pname == 'fit,entry':
>>>> - if seq == 0:
>>>> - fsw.property_u32('entry', entry)
>>>> - elif pname == 'fit,data':
>>>> - fsw.property('data', bytes(data))
>>>> - elif pname != 'fit,operation':
>>>> - self._raise_subnode(
>>>> - node, f"Unknown directive '{pname}'")
>>>> + for (seq, start, data) in segments:
>>>> + node_name = node.name[1:].replace('SEQ', str(seq + 1))
>>>> + with fsw.add_node(node_name):
>>>> + loadables.append(node_name)
>>>> + for pname, prop in node.props.items():
>>>> + if not pname.startswith('fit,'):
>>>> + fsw.property(pname, prop.bytes)
>>>> + elif pname == 'fit,load':
>>>> + fsw.property_u32('load', start)
>>>> + elif pname == 'fit,entry':
>>>> + if seq == 0:
>>>> + fsw.property_u32('entry', entry_addr)
>>>> + elif pname == 'fit,data':
>>>> + fsw.property('data', bytes(data))
>>>> + elif pname != 'fit,operation':
>>>> + self._raise_subnode(
>>>> + node, f"Unknown directive '{pname}'")
>>>>
>>>> def _gen_node(base_node, node, depth, in_images, entry):
>>>> """Generate nodes from a template
>>>> @@ -598,6 +591,8 @@ class Entry_fit(Entry_section):
>>>> depth (int): Current node depth (0 is the base 'fit' node)
>>>> in_images (bool): True if this is inside the 'images' node, so
>>>> that 'data' properties should be generated
>>>> + entry (entry_Section): Entry for the second containing the
>>>> + contents of this node
>>>> """
>>>> oper = self._get_operation(base_node, node)
>>>> if oper == OP_GEN_FDT_NODES:
>>>> @@ -609,10 +604,24 @@ class Entry_fit(Entry_section):
>>>> missing_list = []
>>>> entry.ObtainContents()
>>>> entry.Pack(0)
>>>> - data = entry.GetData()
>>>> entry.CheckMissing(missing_list)
>>>>
>>>> - _gen_split_elf(base_node, node, data, bool(missing_list))
>>>> + # If any pieces are missing, skip this. The missing entries will
>>>> + # show an error
>>>> + if not missing_list:
>>>> + segs = entry.read_elf_segments()
>>>> + if segs:
>>>> + segments, entry_addr = segs
>>>> + else:
>>>> + elf_data = entry.GetData()
>>>> + try:
>>>> + segments, entry_addr = (
>>>> + elf.read_loadable_segments(elf_data))
>>>> + except ValueError as exc:
>>>> + self._raise_subnode(
>>>> + node, f'Failed to read ELF file: {str(exc)}')
>>>> +
>>>> + _gen_split_elf(base_node, node, segments, entry_addr)
>>>>
>>>> def _add_node(base_node, depth, node):
>>>> """Add nodes to the output FIT
>>>> diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
>>>> index dcb7a062047..57bfee0b286 100644
>>>> --- a/tools/binman/etype/section.py
>>>> +++ b/tools/binman/etype/section.py
>>>> @@ -948,3 +948,12 @@ class Entry_section(Entry):
>>>> super().AddBintools(btools)
>>>> for entry in self._entries.values():
>>>> entry.AddBintools(btools)
>>>> +
>>>> + def read_elf_segments(self):
>>>> + entries = self.GetEntries()
>>>> +
>>>> + # If the section only has one entry, see if it can provide ELF segments
>>>> + if len(entries) == 1:
>>>> + for entry in entries.values():
>>>> + return entry.read_elf_segments()
>>>> + return None
>>>> diff --git a/tools/binman/etype/tee_os.py b/tools/binman/etype/tee_os.py
>>>> index 6ce4b672de4..687acd4689f 100644
>>>> --- a/tools/binman/etype/tee_os.py
>>>> +++ b/tools/binman/etype/tee_os.py
>>>> @@ -4,19 +4,85 @@
>>>> # Entry-type module for OP-TEE Trusted OS firmware blob
>>>> #
>>>>
>>>> +import struct
>>>> +
>>>> from binman.etype.blob_named_by_arg import Entry_blob_named_by_arg
>>>> +from binman import elf
>>>>
>>>> class Entry_tee_os(Entry_blob_named_by_arg):
>>>> """Entry containing an OP-TEE Trusted OS (TEE) blob
>>>>
>>>> Properties / Entry arguments:
>>>> - tee-os-path: Filename of file to read into entry. This is typically
>>>> - called tee-pager.bin
>>>> + called tee.bin or tee.elf
>>>>
>>>> This entry holds the run-time firmware, typically started by U-Boot SPL.
>>>> See the U-Boot README for your architecture or board for how to use it. See
>>>> https://github.com/OP-TEE/optee_os for more information about OP-TEE.
>>>> +
>>>> + Note that if the file is in ELF format, it must go in a FIT. In that case,
>>>> + this entry will mark itself as absent, providing the data only through the
>>>> + read_elf_segments() method.
>>>> +
>>>> + Marking this entry as absent means that it if is used in the wrong context
>>>> + it can be automatically dropped. Thus it is possible to add anb OP-TEE entry
>>>> + like this::
>>>> +
>>>> + binman {
>>>> + tee-os {
>>>> + };
>>>> + };
>>>> +
>>>> + and pass either an ELF or plain binary in with -a tee-os-path <filename>
>>>> + and have binman do the right thing:
>>>> +
>>>> + - include the entry if tee.bin is provided and it doesn't have the v1
>>>> + header
>>>> + - drop it otherwise
>>>> +
>>>> + When used within a FIT, we can do::
>>>> +
>>>> + binman {
>>>> + fit {
>>>> + tee-os {
>>>> + };
>>>> + };
>>>> + };
>>>> +
>>>> + which will split the ELF into separate nodes for each segment, if an ELF
>>>> + file is provide (see Flat Image Tree / FIT), or produce a single node if
>>>> + the binary v1 format is provided.
>>>> """
>>>> def __init__(self, section, etype, node):
>>>> super().__init__(section, etype, node, 'tee-os')
>>>> self.external = True
>>>> +
>>>> + @staticmethod
>>>> + def is_optee_bin(data):
>>>> + return len(data) >= 8 and data[0:5] == b'OPTE\x01'
>>>> +
>>>> + def ObtainContents(self, fake_size=0):
>>>> + super().ObtainContents(fake_size)
>>>> + if not self.missing:
>>>> + if elf.is_valid(self.data):
>>>> + self.mark_absent('uses Elf format which must be in a FIT')
>>>> + elif self.is_optee_bin(self.data):
>>>> + self.mark_absent('uses v1 format which must be in a FIT')
>>>> + return True
>>>> +
>>>> + def read_elf_segments(self):
>>>> + data = self.GetData()
>>>> + if self.is_optee_bin(data):
>>>> + # OP-TEE v1 format (tee.bin)
>>>> + init_sz, start_hi, start_lo, _, paged_sz = (
>>>> + struct.unpack_from('<5I', data, 0x8))
>>>> + if paged_sz != 0:
>>>> + self.Raise("OP-TEE paged mode not supported")
>>>> + e_entry = (start_hi << 32) + start_lo
>>>> + p_addr = e_entry
>>>> + p_data = data[0x1c:]
>>>> + if len(p_data) != init_sz:
>>>> + self.Raise("Invalid OP-TEE file: size mismatch (expected %#x, have %#x)" %
>>>> + (init_sz, len(p_data)))
>>>> + return [[0, p_addr, p_data]], e_entry
>>>> + return None
>>>> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
>>>> index f47a745f1e1..f893050e706 100644
>>>> --- a/tools/binman/ftest.py
>>>> +++ b/tools/binman/ftest.py
>>>> @@ -112,6 +112,8 @@ REPACK_DTB_PROPS = ['orig-offset', 'orig-size']
>>>> # Supported compression bintools
>>>> COMP_BINTOOLS = ['bzip2', 'gzip', 'lz4', 'lzma_alone', 'lzop', 'xz', 'zstd']
>>>>
>>>> +TEE_ADDR = 0x5678
>>>> +
>>>> class TestFunctional(unittest.TestCase):
>>>> """Functional tests for binman
>>>>
>>>> @@ -219,6 +221,9 @@ class TestFunctional(unittest.TestCase):
>>>> TestFunctional._MakeInputFile('tee.elf',
>>>> tools.read_file(cls.ElfTestFile('elf_sections')))
>>>>
>>>> + # Newer OP_TEE file in v1 binary format
>>>> + cls.make_tee_bin('tee.bin')
>>>> +
>>>> cls.comp_bintools = {}
>>>> for name in COMP_BINTOOLS:
>>>> cls.comp_bintools[name] = bintool.Bintool.create(name)
>>>> @@ -644,6 +649,14 @@ class TestFunctional(unittest.TestCase):
>>>> def ElfTestFile(cls, fname):
>>>> return os.path.join(cls._elf_testdir, fname)
>>>>
>>>> + @classmethod
>>>> + def make_tee_bin(cls, fname, paged_sz=0, extra_data=b''):
>>>> + init_sz, start_hi, start_lo, dummy = (len(U_BOOT_DATA), 0, TEE_ADDR, 0)
>>>> + data = b'OPTE\x01xxx' + struct.pack('<5I', init_sz, start_hi, start_lo,
>>>> + dummy, paged_sz) + U_BOOT_DATA
>>>> + data += extra_data
>>>> + TestFunctional._MakeInputFile(fname, data)
>>>> +
>>>> def AssertInList(self, grep_list, target):
>>>> """Assert that at least one of a list of things is in a target
>>>>
>>>> @@ -6095,6 +6108,76 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
>>>> data = self._DoReadFile('262_absent.dts')
>>>> self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data)
>>>>
>>>> + def testPackTeeOsOptional(self):
>>>> + """Test that an image with an optional TEE binary can be created"""
>>>> + entry_args = {
>>>> + 'tee-os-path': 'tee.elf',
>>>> + }
>>>> + data = self._DoReadFileDtb('263_tee_os_opt.dts',
>>>> + entry_args=entry_args)[0]
>>>> + self.assertEqual(U_BOOT_DATA + U_BOOT_IMG_DATA, data)
>>>> +
>>>> + def checkFitTee(self, dts, tee_fname):
>>>> + """Check that a tee-os entry works and returns data
>>>> +
>>>> + Args:
>>>> + dts (str): Device tree filename to use
>>>> + tee_fname (str): filename containing tee-os
>>>> +
>>>> + Returns:
>>>> + bytes: Image contents
>>>> + """
>>>> + if not elf.ELF_TOOLS:
>>>> + self.skipTest('Python elftools not available')
>>>> + entry_args = {
>>>> + 'of-list': 'test-fdt1 test-fdt2',
>>>> + 'default-dt': 'test-fdt2',
>>>> + 'tee-os-path': tee_fname,
>>>> + }
>>>> + test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
>>>> + data = self._DoReadFileDtb(dts, entry_args=entry_args,
>>>> + extra_indirs=[test_subdir])[0]
>>>> + return data
>>>> +
>>>> + def testFitTeeOsOptionalFit(self):
>>>> + """Test an image with a FIT with an optional OP-TEE binary"""
>>>> + data = self.checkFitTee('264_tee_os_opt_fit.dts', 'tee.bin')
>>>> +
>>>> + # There should be only one node, holding the data set up in SetUpClass()
>>>> + # for tee.bin
>>>> + dtb = fdt.Fdt.FromData(data)
>>>> + dtb.Scan()
>>>> + node = dtb.GetNode('/images/tee-1')
>>>> + self.assertEqual(TEE_ADDR,
>>>> + fdt_util.fdt32_to_cpu(node.props['load'].value))
>>>> + self.assertEqual(TEE_ADDR,
>>>> + fdt_util.fdt32_to_cpu(node.props['entry'].value))
>>>> + self.assertEqual(U_BOOT_DATA, node.props['data'].bytes)
>>>> +
>>>> + def testFitTeeOsOptionalFitBad(self):
>>>> + """Test an image with a FIT with an optional OP-TEE binary"""
>>>> + with self.assertRaises(ValueError) as exc:
>>>> + self.checkFitTee('265_tee_os_opt_fit_bad.dts', 'tee.bin')
>>>> + self.assertIn(
>>>> + "Node '/binman/fit': subnode 'images/@tee-SEQ': Failed to read ELF file: Magic number does not match",
>>>> + str(exc.exception))
>>>> +
>>>> + def testFitTeeOsBad(self):
>>>> + """Test an OP-TEE binary with wrong formats"""
>>>> + self.make_tee_bin('tee.bad1', 123)
>>>> + with self.assertRaises(ValueError) as exc:
>>>> + self.checkFitTee('264_tee_os_opt_fit.dts', 'tee.bad1')
>>>> + self.assertIn(
>>>> + "Node '/binman/fit/images/@tee-SEQ/tee-os': OP-TEE paged mode not supported",
>>>> + str(exc.exception))
>>>> +
>>>> + self.make_tee_bin('tee.bad2', 0, b'extra data')
>>>> + with self.assertRaises(ValueError) as exc:
>>>> + self.checkFitTee('264_tee_os_opt_fit.dts', 'tee.bad2')
>>>> + self.assertIn(
>>>> + "Node '/binman/fit/images/@tee-SEQ/tee-os': Invalid OP-TEE file: size mismatch (expected 0x4, have 0xe)",
>>>> + str(exc.exception))
>>>> +
>>>>
>>>> if __name__ == "__main__":
>>>> unittest.main()
>>>> diff --git a/tools/binman/test/263_tee_os_opt.dts b/tools/binman/test/263_tee_os_opt.dts
>>>> new file mode 100644
>>>> index 00000000000..2e4ec24ac2c
>>>> --- /dev/null
>>>> +++ b/tools/binman/test/263_tee_os_opt.dts
>>>> @@ -0,0 +1,22 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +
>>>> +/dts-v1/;
>>>> +
>>>> +/ {
>>>> + #address-cells = <1>;
>>>> + #size-cells = <1>;
>>>> +
>>>> + binman {
>>>> + u-boot {
>>>> + };
>>>> + tee-os {
>>>> + /*
>>>> + * this results in nothing being added since only the
>>>> + * .bin format is supported by this etype, unless it is
>>>> + * part of a FIT
>>>> + */
>>>> + };
>>>> + u-boot-img {
>>>> + };
>>>> + };
>>>> +};
>>>> diff --git a/tools/binman/test/264_tee_os_opt_fit.dts b/tools/binman/test/264_tee_os_opt_fit.dts
>>>> new file mode 100644
>>>> index 00000000000..ae44b433edf
>>>> --- /dev/null
>>>> +++ b/tools/binman/test/264_tee_os_opt_fit.dts
>>>> @@ -0,0 +1,33 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +
>>>> +/dts-v1/;
>>>> +
>>>> +/ {
>>>> + #address-cells = <1>;
>>>> + #size-cells = <1>;
>>>> +
>>>> + binman {
>>>> + fit {
>>>> + description = "test-desc";
>>>> + #address-cells = <1>;
>>>> + fit,fdt-list = "of-list";
>>>> +
>>>> + images {
>>>> + @tee-SEQ {
>>>> + fit,operation = "split-elf";
>>>> + description = "TEE";
>>>> + type = "tee";
>>>> + arch = "arm64";
>>>> + os = "tee";
>>>> + compression = "none";
>>>> + fit,load;
>>>> + fit,entry;
>>>> + fit,data;
>>>> +
>>>> + tee-os {
>>>> + };
>>>> + };
>>>> + };
>>>> + };
>>>> + };
>>>> +};
>>>> diff --git a/tools/binman/test/265_tee_os_opt_fit_bad.dts b/tools/binman/test/265_tee_os_opt_fit_bad.dts
>>>> new file mode 100644
>>>> index 00000000000..7fa363cc199
>>>> --- /dev/null
>>>> +++ b/tools/binman/test/265_tee_os_opt_fit_bad.dts
>>>> @@ -0,0 +1,40 @@
>>>> +// SPDX-License-Identifier: GPL-2.0+
>>>> +
>>>> +/dts-v1/;
>>>> +
>>>> +/ {
>>>> + #address-cells = <1>;
>>>> + #size-cells = <1>;
>>>> +
>>>> + binman {
>>>> + fit {
>>>> + description = "test-desc";
>>>> + #address-cells = <1>;
>>>> + fit,fdt-list = "of-list";
>>>> +
>>>> + images {
>>>> + @tee-SEQ {
>>>> + fit,operation = "split-elf";
>>>> + description = "TEE";
>>>> + type = "tee";
>>>> + arch = "arm64";
>>>> + os = "tee";
>>>> + compression = "none";
>>>> + fit,load;
>>>> + fit,entry;
>>>> + fit,data;
>>>> +
>>>> + tee-os {
>>>> + };
>>>> +
>>>> + /*
>>>> + * mess up the ELF data by adding
>>>> + * another bit of data at the end
>>>> + */
>>>> + u-boot {
>>>> + };
>>>> + };
>>>> + };
>>>> + };
>>>> + };
>>>> +};
More information about the U-Boot
mailing list