mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
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:
commit
b3b6cc28c2
15 changed files with 441 additions and 23 deletions
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
|
||||
atf-bl31 {
|
||||
};
|
||||
hash {
|
||||
algo = "sha256";
|
||||
};
|
||||
};
|
||||
|
||||
@tee-SEQ {
|
||||
|
@ -48,6 +51,9 @@
|
|||
|
||||
tee-os {
|
||||
};
|
||||
hash-1 {
|
||||
algo = "sha256";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
59
tools/binman/test/275_fit_align.dts
Normal file
59
tools/binman/test/275_fit_align.dts
Normal 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
96
tools/binman/test/276_fit_firmware_loadables.dts
Normal file
96
tools/binman/test/276_fit_firmware_loadables.dts
Normal 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;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
|
@ -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};
|
||||
|
||||
|
|
Loading…
Reference in a new issue