FIT improvements with split-elf, especially for Rockchip

Binman positioning by ELF symbol
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAmPTNLgRHHNqZ0BjaHJv
 bWl1bS5vcmcACgkQfxc6PpAIreagiwgAr1Q+8qPghgomUK9cVjBuNzG2i88YWy7/
 oitshEE73lm92kP4YIQrSm1ZBy6mm0A0wyy4pRLC0fFrovzAWq1o7xfUEkuhxyTV
 pR7BiLPGUsHfL1cP4EuGSNMgrfX0QOddQgZTns4s7k4fbrFBLmTTa/+1jrU3AJNW
 1FVfVSc4eMqHM5gD7mfqSHRsxrbZDHpzbJEKIMS1xkVy/BSQbDWtF1f6Lri3M9VT
 Q7eNxFH5OptRAttcQreVNSNu28z00x0TuJNKLORXJa5AAxGW4yvNWgDFegU10NZc
 ADTKaNDsDz4D//Ar3PSt+10eGWWKqrY9ClQwls4lJmJJTIqldf+QDw==
 =l2A4
 -----END PGP SIGNATURE-----

Merge tag 'dm-pull-26jan23' of https://source.denx.de/u-boot/custodians/u-boot-dm

FIT improvements with split-elf, especially for Rockchip
Binman positioning by ELF symbol
This commit is contained in:
Tom Rini 2023-01-26 21:57:38 -05:00
commit b3b6cc28c2
15 changed files with 441 additions and 23 deletions

View file

@ -37,6 +37,7 @@
fit,fdt-list = "of-list";
filename = "u-boot.itb";
fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
fit,align = <512>;
offset = <CONFIG_SPL_PAD_TO>;
images {
u-boot {
@ -49,6 +50,11 @@
entry = <CONFIG_TEXT_BASE>;
u-boot-nodtb {
};
#ifdef CONFIG_SPL_FIT_SIGNATURE
hash {
algo = "sha256";
};
#endif
};
@atf-SEQ {
@ -64,6 +70,11 @@
atf-bl31 {
};
#ifdef CONFIG_SPL_FIT_SIGNATURE
hash {
algo = "sha256";
};
#endif
};
@tee-SEQ {
fit,operation = "split-elf";
@ -79,12 +90,22 @@
tee-os {
optional;
};
#ifdef CONFIG_SPL_FIT_SIGNATURE
hash {
algo = "sha256";
};
#endif
};
@fdt-SEQ {
description = "fdt-NAME";
compression = "none";
type = "flat_dt";
#ifdef CONFIG_SPL_FIT_SIGNATURE
hash {
algo = "sha256";
};
#endif
};
};
@ -93,7 +114,7 @@
@config-SEQ {
description = "NAME.dtb";
fdt = "fdt-SEQ";
firmware = "u-boot";
fit,firmware = "atf-1", "u-boot";
fit,loadables;
};
};

View file

@ -39,7 +39,7 @@ static void show_devices(struct udevice *dev, int depth, int last_flag,
u32 flags = dev_get_flags(dev);
/* print the first 20 characters to not break the tree-format. */
printf(IS_ENABLED(CONFIG_SPL_BUILD) ? " %s %d [ %c ] %s " :
printf(CONFIG_IS_ENABLED(USE_TINY_PRINTF) ? " %s %d [ %c ] %s " :
" %-10.10s %3d [ %c ] %-20.20s ", dev->uclass->uc_drv->name,
dev_get_uclass_index(dev, NULL),
flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);

View file

@ -615,6 +615,14 @@ size:
this size. If this is not provided, it will be set to the size of the
contents.
min-size:
Sets the minimum size of the entry. This size includes explicit padding
('pad-before' and 'pad-after'), but not padding added to meet alignment
requirements. While this does not affect the contents of the entry within
binman itself (the padding is performed only when its parent section is
assembled), the end result will be that the entry ends with the padding
bytes, so may grow. Defaults to 0.
pad-before:
Padding before the contents of the entry. Normally this is 0, meaning
that the contents start at the beginning of the entry. This can be used

View file

@ -22,7 +22,7 @@ class Bintoolmkimage(bintool.Bintool):
# pylint: disable=R0913
def run(self, reset_timestamp=False, output_fname=None, external=False,
pad=None):
pad=None, align=None):
"""Run mkimage
Args:
@ -33,6 +33,7 @@ class Bintoolmkimage(bintool.Bintool):
pad: Bytes to use for padding the FIT devicetree output. This allows
other things to be easily added later, if required, such as
signatures
align: Bytes to use for alignment of the FIT and its external data
version: True to get the mkimage version
"""
args = []
@ -40,6 +41,8 @@ class Bintoolmkimage(bintool.Bintool):
args.append('-E')
if pad:
args += ['-p', f'{pad:x}']
if align:
args += ['-B', f'{align:x}']
if reset_timestamp:
args.append('-t')
if output_fname:

View file

@ -242,7 +242,7 @@ class TestElf(unittest.TestCase):
end = offset['embed_end'].offset
data = tools.read_file(fname)
embed_data = data[start:end]
expect = struct.pack('<III', 0x1234, 0x5678, 0)
expect = struct.pack('<IIIII', 2, 3, 0x1234, 0x5678, 0)
self.assertEqual(expect, embed_data)
def testEmbedFail(self):
@ -358,6 +358,17 @@ class TestElf(unittest.TestCase):
self.assertEqual(True, elf.is_valid(data))
self.assertEqual(False, elf.is_valid(data[4:]))
def test_get_symbol_offset(self):
fname = self.ElfTestFile('embed_data')
syms = elf.GetSymbols(fname, ['embed_start', 'embed'])
expected = syms['embed'].address - syms['embed_start'].address
val = elf.GetSymbolOffset(fname, 'embed', 'embed_start')
self.assertEqual(expected, val)
with self.assertRaises(KeyError) as e:
elf.GetSymbolOffset(fname, 'embed')
self.assertIn('__image_copy_start', str(e.exception))
if __name__ == '__main__':
unittest.main()

View file

@ -604,6 +604,11 @@ The top-level 'fit' node supports the following special properties:
Indicates that the contents of the FIT are external and provides the
external offset. This is passed to mkimage via the -E and -p flags.
fit,align
Indicates what alignment to use for the FIT and its external data,
and provides the alignment to use. This is passed to mkimage via
the -B flag.
fit,fdt-list
Indicates the entry argument which provides the list of device tree
files for the gen-fdt-nodes operation (as below). This is often
@ -716,6 +721,12 @@ split-elf
fit,data
Generates a `data = <...>` property with the contents of the segment
fit,firmware
Generates a `firmware = <...>` property. Provides a list of possible
nodes to be used as the `firmware` property value. The first valid
node is picked as the firmware. Any remaining valid nodes is
prepended to the `loadable` property generated by `fit,loadables`
fit,loadables
Generates a `loadable = <...>` property with a list of the generated
nodes (including all nodes if this operation is used multiple times)
@ -757,6 +768,9 @@ Here is an example showing ATF, TEE and a device tree all combined::
atf-bl31 {
};
hash {
algo = "sha256";
};
};
@tee-SEQ {
@ -772,6 +786,9 @@ Here is an example showing ATF, TEE and a device tree all combined::
tee-os {
};
hash {
algo = "sha256";
};
};
};
@ -780,7 +797,7 @@ Here is an example showing ATF, TEE and a device tree all combined::
@config-SEQ {
description = "conf-NAME.dtb";
fdt = "fdt-SEQ";
firmware = "u-boot";
fit,firmware = "atf-1", "u-boot";
fit,loadables;
};
};
@ -800,6 +817,10 @@ ELF file, for example::
arch = "arm64";
type = "firmware";
description = "ARM Trusted Firmware";
hash {
algo = "sha256";
value = <...hash of first segment...>;
};
};
atf-2 {
data = <...contents of second segment...>;
@ -809,6 +830,10 @@ ELF file, for example::
arch = "arm64";
type = "firmware";
description = "ARM Trusted Firmware";
hash {
algo = "sha256";
value = <...hash of second segment...>;
};
};
};
@ -827,15 +852,15 @@ is::
configurations {
default = "config-1";
config-1 {
loadables = "atf-1", "atf-2", "atf-3", "tee-1", "tee-2";
loadables = "u-boot", "atf-2", "atf-3", "tee-1", "tee-2";
description = "rk3399-firefly.dtb";
fdt = "fdt-1";
firmware = "u-boot";
firmware = "atf-1";
};
};
U-Boot SPL can then load the firmware (U-Boot proper) and all the loadables
(ATF and TEE), then proceed with the boot.
U-Boot SPL can then load the firmware (ATF) and all the loadables (U-Boot
proper, ATF and TEE), then proceed with the boot.

View file

@ -49,6 +49,7 @@ class Entry(object):
offset: Offset of entry within the section, None if not known yet (in
which case it will be calculated by Pack())
size: Entry size in bytes, None if not known
min_size: Minimum entry size in bytes
pre_reset_size: size as it was before ResetForPack(). This allows us to
keep track of the size we started with and detect size changes
uncomp_size: Size of uncompressed data in bytes, if the entry is
@ -114,6 +115,7 @@ class Entry(object):
self.name = node and (name_prefix + node.name) or 'none'
self.offset = None
self.size = None
self.min_size = 0
self.pre_reset_size = None
self.uncomp_size = None
self.data = None
@ -270,6 +272,7 @@ class Entry(object):
self.Raise("Please use 'extend-size' instead of 'expand-size'")
self.offset = fdt_util.GetInt(self._node, 'offset')
self.size = fdt_util.GetInt(self._node, 'size')
self.min_size = fdt_util.GetInt(self._node, 'min-size', 0)
self.orig_offset = fdt_util.GetInt(self._node, 'orig-offset')
self.orig_size = fdt_util.GetInt(self._node, 'orig-size')
if self.GetImage().copy_to_orig:
@ -507,6 +510,7 @@ class Entry(object):
else:
self.offset = tools.align(offset, self.align)
needed = self.pad_before + self.contents_size + self.pad_after
needed = max(needed, self.min_size)
needed = tools.align(needed, self.align_size)
size = self.size
if not size:

View file

@ -114,6 +114,25 @@ class TestEntry(unittest.TestCase):
self.assertEquals(tools.get_bytes(0, 1024), base.CompressData(b'abc'))
self.assertEquals(tools.get_bytes(0, 1024), base.DecompressData(b'abc'))
def testLookupOffset(self):
"""Test the lookup_offset() method of the base class"""
def MyFindEntryByNode(node):
return self.found
base = entry.Entry.Create(None, self.GetNode(), 'blob-dtb')
base.FindEntryByNode = MyFindEntryByNode
base.section = base
self.found = None
base.offset_from_elf = [self.GetNode(), 'start', 0]
with self.assertRaises(ValueError) as e:
base.lookup_offset()
self.assertIn("Cannot find entry for node 'u-boot'", str(e.exception))
self.found = base
with self.assertRaises(ValueError) as e:
base.lookup_offset()
self.assertIn("Need elf-fname property 'u-boot'", str(e.exception))
if __name__ == "__main__":
unittest.main()

View file

@ -70,6 +70,11 @@ class Entry_fit(Entry_section):
Indicates that the contents of the FIT are external and provides the
external offset. This is passed to mkimage via the -E and -p flags.
fit,align
Indicates what alignment to use for the FIT and its external data,
and provides the alignment to use. This is passed to mkimage via
the -B flag.
fit,fdt-list
Indicates the entry argument which provides the list of device tree
files for the gen-fdt-nodes operation (as below). This is often
@ -182,6 +187,12 @@ class Entry_fit(Entry_section):
fit,data
Generates a `data = <...>` property with the contents of the segment
fit,firmware
Generates a `firmware = <...>` property. Provides a list of possible
nodes to be used as the `firmware` property value. The first valid
node is picked as the firmware. Any remaining valid nodes is
prepended to the `loadable` property generated by `fit,loadables`
fit,loadables
Generates a `loadable = <...>` property with a list of the generated
nodes (including all nodes if this operation is used multiple times)
@ -223,6 +234,9 @@ class Entry_fit(Entry_section):
atf-bl31 {
};
hash {
algo = "sha256";
};
};
@tee-SEQ {
@ -238,6 +252,9 @@ class Entry_fit(Entry_section):
tee-os {
};
hash {
algo = "sha256";
};
};
};
@ -246,7 +263,7 @@ class Entry_fit(Entry_section):
@config-SEQ {
description = "conf-NAME.dtb";
fdt = "fdt-SEQ";
firmware = "u-boot";
fit,firmware = "atf-1", "u-boot";
fit,loadables;
};
};
@ -266,6 +283,10 @@ class Entry_fit(Entry_section):
arch = "arm64";
type = "firmware";
description = "ARM Trusted Firmware";
hash {
algo = "sha256";
value = <...hash of first segment...>;
};
};
atf-2 {
data = <...contents of second segment...>;
@ -275,6 +296,10 @@ class Entry_fit(Entry_section):
arch = "arm64";
type = "firmware";
description = "ARM Trusted Firmware";
hash {
algo = "sha256";
value = <...hash of second segment...>;
};
};
};
@ -293,15 +318,15 @@ class Entry_fit(Entry_section):
configurations {
default = "config-1";
config-1 {
loadables = "atf-1", "atf-2", "atf-3", "tee-1", "tee-2";
loadables = "u-boot", "atf-2", "atf-3", "tee-1", "tee-2";
description = "rk3399-firefly.dtb";
fdt = "fdt-1";
firmware = "u-boot";
firmware = "atf-1";
};
};
U-Boot SPL can then load the firmware (U-Boot proper) and all the loadables
(ATF and TEE), then proceed with the boot.
U-Boot SPL can then load the firmware (ATF) and all the loadables (U-Boot
proper, ATF and TEE), then proceed with the boot.
"""
def __init__(self, section, etype, node):
"""
@ -423,6 +448,9 @@ class Entry_fit(Entry_section):
'external': True,
'pad': fdt_util.fdt32_to_cpu(ext_offset.value)
}
align = self._fit_props.get('fit,align')
if align is not None:
args.update({'align': fdt_util.fdt32_to_cpu(align.value)})
if self.mkimage.run(reset_timestamp=True, output_fname=output_fname,
**args) is None:
# Bintool is missing; just use empty data as the output
@ -488,6 +516,42 @@ class Entry_fit(Entry_section):
return
fsw.property(pname, prop.bytes)
def _process_firmware_prop(node):
"""Process optional fit,firmware property
Picks the first valid entry for use as the firmware, remaining valid
entries is prepended to loadables
Args:
node (Node): Generator node to process
Returns:
firmware (str): Firmware or None
result (list): List of remaining loadables
"""
val = fdt_util.GetStringList(node, 'fit,firmware')
if val is None:
return None, self._loadables
valid_entries = list(self._loadables)
for name, entry in self.GetEntries().items():
missing = []
entry.CheckMissing(missing)
entry.CheckOptional(missing)
if not missing:
valid_entries.append(name)
firmware = None
result = []
for name in val:
if name in valid_entries:
if not firmware:
firmware = name
elif name not in result:
result.append(name)
for name in self._loadables:
if name != firmware and name not in result:
result.append(name)
return firmware, result
def _gen_fdt_nodes(base_node, node, depth, in_images):
"""Generate FDT nodes
@ -498,20 +562,24 @@ class Entry_fit(Entry_section):
first.
Args:
node (None): Generator node to process
node (Node): Generator node to process
depth: Current node depth (0 is the base 'fit' node)
in_images: True if this is inside the 'images' node, so that
'data' properties should be generated
"""
if self._fdts:
firmware, fit_loadables = _process_firmware_prop(node)
# Generate nodes for each FDT
for seq, fdt_fname in enumerate(self._fdts):
node_name = node.name[1:].replace('SEQ', str(seq + 1))
fname = tools.get_input_filename(fdt_fname + '.dtb')
with fsw.add_node(node_name):
for pname, prop in node.props.items():
if pname == 'fit,loadables':
val = '\0'.join(self._loadables) + '\0'
if pname == 'fit,firmware':
if firmware:
fsw.property_string('firmware', firmware)
elif pname == 'fit,loadables':
val = '\0'.join(fit_loadables) + '\0'
fsw.property('loadables', val.encode('utf-8'))
elif pname == 'fit,operation':
pass
@ -540,12 +608,13 @@ class Entry_fit(Entry_section):
else:
self.Raise("Generator node requires 'fit,fdt-list' property")
def _gen_split_elf(base_node, node, segments, entry_addr):
def _gen_split_elf(base_node, node, depth, 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)
depth: Current node depth (0 is the base 'fit' node)
segments (list): list of segments, each:
int: Segment number (0 = first)
int: Start address of segment in memory
@ -570,6 +639,10 @@ class Entry_fit(Entry_section):
self._raise_subnode(
node, f"Unknown directive '{pname}'")
for subnode in node.subnodes:
with fsw.add_node(subnode.name):
_add_node(node, depth + 1, subnode)
def _gen_node(base_node, node, depth, in_images, entry):
"""Generate nodes from a template
@ -623,7 +696,7 @@ class Entry_fit(Entry_section):
self._raise_subnode(
node, f'Failed to read ELF file: {str(exc)}')
_gen_split_elf(base_node, node, segments, entry_addr)
_gen_split_elf(base_node, node, depth, segments, entry_addr)
def _add_node(base_node, depth, node):
"""Add nodes to the output FIT

View file

@ -883,9 +883,9 @@ class TestFunctional(unittest.TestCase):
self.assertIn('image', control.images)
image = control.images['image']
entries = image.GetEntries()
self.assertEqual(5, len(entries))
self.assertEqual(6, len(entries))
# First u-boot with padding before and after
# First u-boot with padding before and after (included in minimum size)
self.assertIn('u-boot', entries)
entry = entries['u-boot']
self.assertEqual(0, entry.offset)
@ -934,8 +934,17 @@ class TestFunctional(unittest.TestCase):
self.assertEqual(U_BOOT_DATA + tools.get_bytes(0, 64 - len(U_BOOT_DATA)),
data[pos:pos + entry.size])
# Sixth u-boot with both minimum size and aligned size
self.assertIn('u-boot-min-size', entries)
entry = entries['u-boot-min-size']
self.assertEqual(128, entry.offset)
self.assertEqual(32, entry.size)
self.assertEqual(U_BOOT_DATA, entry.data[:len(U_BOOT_DATA)])
self.assertEqual(U_BOOT_DATA + tools.get_bytes(0, 32 - len(U_BOOT_DATA)),
data[pos:pos + entry.size])
self.CheckNoGaps(entries)
self.assertEqual(128, image.size)
self.assertEqual(160, image.size)
dtb = fdt.Fdt(out_dtb_fname)
dtb.Scan()
@ -943,7 +952,7 @@ class TestFunctional(unittest.TestCase):
expected = {
'image-pos': 0,
'offset': 0,
'size': 128,
'size': 160,
'u-boot:image-pos': 0,
'u-boot:offset': 0,
@ -964,6 +973,10 @@ class TestFunctional(unittest.TestCase):
'u-boot-align-both:image-pos': 64,
'u-boot-align-both:offset': 64,
'u-boot-align-both:size': 64,
'u-boot-min-size:image-pos': 128,
'u-boot-min-size:offset': 128,
'u-boot-min-size:size': 32,
}
self.assertEqual(expected, props)
@ -5439,6 +5452,10 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
fdt_util.fdt32_to_cpu(atf1.props['load'].value))
self.assertEqual(data, atf1.props['data'].bytes)
hash_node = atf1.FindNode('hash')
self.assertIsNotNone(hash_node)
self.assertEqual({'algo', 'value'}, hash_node.props.keys())
atf2 = dtb.GetNode('/images/atf-2')
self.assertEqual(base_keys, atf2.props.keys())
_, start, data = segments[1]
@ -5446,6 +5463,14 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
fdt_util.fdt32_to_cpu(atf2.props['load'].value))
self.assertEqual(data, atf2.props['data'].bytes)
hash_node = atf2.FindNode('hash')
self.assertIsNotNone(hash_node)
self.assertEqual({'algo', 'value'}, hash_node.props.keys())
hash_node = dtb.GetNode('/images/tee-1/hash-1')
self.assertIsNotNone(hash_node)
self.assertEqual({'algo', 'value'}, hash_node.props.keys())
conf = dtb.GetNode('/configurations')
self.assertEqual({'default'}, conf.props.keys())
@ -6309,6 +6334,66 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertEqual(base + 8, inset.image_pos);
self.assertEqual(4, inset.size);
def testFitAlign(self):
"""Test an image with an FIT with aligned external data"""
data = self._DoReadFile('275_fit_align.dts')
self.assertEqual(4096, len(data))
dtb = fdt.Fdt.FromData(data)
dtb.Scan()
props = self._GetPropTree(dtb, ['data-position'])
expected = {
'u-boot:data-position': 1024,
'fdt-1:data-position': 2048,
'fdt-2:data-position': 3072,
}
self.assertEqual(expected, props)
def testFitFirmwareLoadables(self):
"""Test an image with an FIT that use fit,firmware"""
if not elf.ELF_TOOLS:
self.skipTest('Python elftools not available')
entry_args = {
'of-list': 'test-fdt1',
'default-dt': 'test-fdt1',
'atf-bl31-path': 'bl31.elf',
'tee-os-path': 'missing.bin',
}
test_subdir = os.path.join(self._indir, TEST_FDT_SUBDIR)
data = self._DoReadFileDtb(
'276_fit_firmware_loadables.dts',
entry_args=entry_args,
extra_indirs=[test_subdir])[0]
dtb = fdt.Fdt.FromData(data)
dtb.Scan()
node = dtb.GetNode('/configurations/conf-uboot-1')
self.assertEqual('u-boot', node.props['firmware'].value)
self.assertEqual(['atf-1', 'atf-2'],
fdt_util.GetStringList(node, 'loadables'))
node = dtb.GetNode('/configurations/conf-atf-1')
self.assertEqual('atf-1', node.props['firmware'].value)
self.assertEqual(['u-boot', 'atf-2'],
fdt_util.GetStringList(node, 'loadables'))
node = dtb.GetNode('/configurations/conf-missing-uboot-1')
self.assertEqual('u-boot', node.props['firmware'].value)
self.assertEqual(['atf-1', 'atf-2'],
fdt_util.GetStringList(node, 'loadables'))
node = dtb.GetNode('/configurations/conf-missing-atf-1')
self.assertEqual('atf-1', node.props['firmware'].value)
self.assertEqual(['u-boot', 'atf-2'],
fdt_util.GetStringList(node, 'loadables'))
node = dtb.GetNode('/configurations/conf-missing-tee-1')
self.assertEqual('atf-1', node.props['firmware'].value)
self.assertEqual(['u-boot', 'atf-2'],
fdt_util.GetStringList(node, 'loadables'))
if __name__ == "__main__":
unittest.main()

View file

@ -6,6 +6,7 @@
binman {
u-boot {
min-size = <12>;
pad-before = <3>;
pad-after = <5>;
};
@ -31,5 +32,11 @@
align = <64>;
align-end = <128>;
};
u-boot-min-size {
type = "u-boot";
min-size = <24>;
align-size = <16>;
};
};
};

View file

@ -33,6 +33,9 @@
atf-bl31 {
};
hash {
algo = "sha256";
};
};
@tee-SEQ {
@ -48,6 +51,9 @@
tee-os {
};
hash-1 {
algo = "sha256";
};
};
};

View file

@ -0,0 +1,59 @@
// SPDX-License-Identifier: GPL-2.0+
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
fit {
description = "test desc";
#address-cells = <1>;
fit,external-offset = <1024>;
fit,align = <1024>;
images {
u-boot {
description = "test u-boot";
type = "standalone";
arch = "arm64";
os = "u-boot";
compression = "none";
load = <00000000>;
entry = <00000000>;
u-boot-nodtb {
};
};
fdt-1 {
description = "test fdt";
type = "flat_dt";
compression = "none";
u-boot-dtb {
};
};
fdt-2 {
description = "test fdt";
type = "flat_dt";
compression = "none";
u-boot-dtb {
};
};
};
configurations {
default = "config-1";
config-1 {
description = "test config";
fdt = "fdt-1";
firmware = "u-boot";
};
};
};
};
};

View file

@ -0,0 +1,96 @@
// 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 {
u-boot {
description = "test u-boot";
type = "standalone";
arch = "arm64";
os = "u-boot";
compression = "none";
load = <0x00000000>;
entry = <0x00000000>;
u-boot-nodtb {
};
};
tee {
description = "test tee";
type = "tee";
arch = "arm64";
os = "tee";
compression = "none";
load = <0x00200000>;
tee-os {
optional;
};
};
@atf-SEQ {
fit,operation = "split-elf";
description = "test tf-a";
type = "firmware";
arch = "arm64";
os = "arm-trusted-firmware";
compression = "none";
fit,load;
fit,entry;
fit,data;
atf-bl31 {
};
};
@fdt-SEQ {
description = "test fdt";
type = "flat_dt";
compression = "none";
};
};
configurations {
default = "@conf-uboot-DEFAULT-SEQ";
@conf-uboot-SEQ {
description = "uboot config";
fdt = "fdt-SEQ";
fit,firmware = "u-boot";
fit,loadables;
};
@conf-atf-SEQ {
description = "atf config";
fdt = "fdt-SEQ";
fit,firmware = "atf-1", "u-boot";
fit,loadables;
};
@conf-missing-uboot-SEQ {
description = "missing uboot config";
fdt = "fdt-SEQ";
fit,firmware = "missing-1", "u-boot";
fit,loadables;
};
@conf-missing-atf-SEQ {
description = "missing atf config";
fdt = "fdt-SEQ";
fit,firmware = "missing-1", "atf-1", "u-boot";
fit,loadables;
};
@conf-missing-tee-SEQ {
description = "missing tee config";
fdt = "fdt-SEQ";
fit,firmware = "atf-1", "u-boot", "tee";
fit,loadables;
};
};
};
};
};

View file

@ -7,6 +7,7 @@
*/
int first[10] = {1};
int before[2] __attribute__((section(".embed"))) = {2, 3};
int embed[3] __attribute__((section(".embed"))) = {0x1234, 0x5678};
int second[10] = {1};