binman: Allow collection to use entries from other sections

At present the collections etype only works with entries in the same
section. This can be limiting, since in some cases the data may be inside
a subsection, e.g. if there are alignment constraints.

Add a function to find the entries in an etype and have it search
recursively. Make use of this for mkimage also.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2022-08-13 11:40:50 -06:00
parent 9db9e932c7
commit d626e825f5
8 changed files with 110 additions and 4 deletions

View File

@ -447,6 +447,9 @@ listed entries are combined to form this entry. This serves as a useful
base class for entry types which need to process data from elsewhere in base class for entry types which need to process data from elsewhere in
the image, not necessarily child entries. the image, not necessarily child entries.
The entries can generally be anywhere in the same image, even if they are in
a different section from this entry.
.. _etype_cros_ec_rw: .. _etype_cros_ec_rw:

View File

@ -679,6 +679,7 @@ class Entry(object):
self.WriteMapLine(fd, indent, self.name, self.offset, self.size, self.WriteMapLine(fd, indent, self.name, self.offset, self.size,
self.image_pos) self.image_pos)
# pylint: disable=assignment-from-none
def GetEntries(self): def GetEntries(self):
"""Return a list of entries contained by this entry """Return a list of entries contained by this entry
@ -688,6 +689,28 @@ class Entry(object):
""" """
return None return None
def FindEntryByNode(self, find_node):
"""Find a node in an entry, searching all subentries
This does a recursive search.
Args:
find_node (fdt.Node): Node to find
Returns:
Entry: entry, if found, else None
"""
entries = self.GetEntries()
if entries:
for entry in entries.values():
if entry._node == find_node:
return entry
found = entry.FindEntryByNode(find_node)
if found:
return found
return None
def GetArg(self, name, datatype=str): def GetArg(self, name, datatype=str):
"""Get the value of an entry argument or device-tree-node property """Get the value of an entry argument or device-tree-node property

View File

@ -21,6 +21,9 @@ class Entry_collection(Entry):
listed entries are combined to form this entry. This serves as a useful listed entries are combined to form this entry. This serves as a useful
base class for entry types which need to process data from elsewhere in base class for entry types which need to process data from elsewhere in
the image, not necessarily child entries. the image, not necessarily child entries.
The entries can generally be anywhere in the same image, even if they are in
a different section from this entry.
""" """
def __init__(self, section, etype, node): def __init__(self, section, etype, node):
super().__init__(section, etype, node) super().__init__(section, etype, node)

View File

@ -148,6 +148,13 @@ class Entry_mkimage(Entry):
return True return True
def GetEntries(self):
# Make a copy so we don't change the original
entries = OrderedDict(self._mkimage_entries)
if self._imagename:
entries['imagename'] = self._imagename
return entries
def SetAllowMissing(self, allow_missing): def SetAllowMissing(self, allow_missing):
"""Set whether a section allows missing external blobs """Set whether a section allows missing external blobs

View File

@ -506,10 +506,10 @@ class Entry_section(Entry):
node = self._node.GetFdt().LookupPhandle(phandle) node = self._node.GetFdt().LookupPhandle(phandle)
if not node: if not node:
source_entry.Raise("Cannot find node for phandle %d" % phandle) source_entry.Raise("Cannot find node for phandle %d" % phandle)
for entry in self._entries.values(): entry = self.FindEntryByNode(node)
if entry._node == node: if not entry:
return entry.GetData(required) source_entry.Raise("Cannot find entry for node '%s'" % node.name)
source_entry.Raise("Cannot find entry for node '%s'" % node.name) return entry.GetData(required)
def LookupSymbol(self, sym_name, optional, msg, base_addr, entries=None): def LookupSymbol(self, sym_name, optional, msg, base_addr, entries=None):
"""Look up a symbol in an ELF file """Look up a symbol in an ELF file

View File

@ -5773,6 +5773,20 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self.assertIn('Cannot use both imagename node and data-to-imagename', self.assertIn('Cannot use both imagename node and data-to-imagename',
str(exc.exception)) str(exc.exception))
def testCollectionOther(self):
"""Test a collection where the data comes from another section"""
data = self._DoReadFile('239_collection_other.dts')
self.assertEqual(U_BOOT_NODTB_DATA + U_BOOT_DTB_DATA +
tools.get_bytes(0xff, 2) + U_BOOT_NODTB_DATA +
tools.get_bytes(0xfe, 3) + U_BOOT_DTB_DATA,
data)
def testMkimageCollection(self):
"""Test using a collection referring to an entry in a mkimage entry"""
data = self._DoReadFile('240_mkimage_coll.dts')
expect = U_BOOT_SPL_DATA + U_BOOT_DATA
self.assertEqual(expect, data[:len(expect)])
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@ -0,0 +1,29 @@
// SPDX-License-Identifier: GPL-2.0+
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
collection {
content = <&u_boot_nodtb &dtb>;
};
section {
fill {
size = <2>;
fill-byte = [ff];
};
u_boot_nodtb: u-boot-nodtb {
};
fill2 {
type = "fill";
size = <3>;
fill-byte = [fe];
};
};
dtb: u-boot-dtb {
};
};
};

View File

@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-2.0+
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
collection {
content = <&spl &u_boot>;
};
mkimage {
args = "-T script";
spl: u-boot-spl {
};
imagename {
type = "section";
u_boot: u-boot {
};
};
};
};
};