1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2018 Google, Inc
3 # Written by Simon Glass <sjg@chromium.org>
5 """# Entry-type module for a full map of the firmware image
7 This handles putting an FDT into the image with just the information about the
13 from entry import Entry
19 FDTMAP_MAGIC = b'_FDTMAP_'
22 def LocateFdtmap(data):
23 """Search an image for an fdt map
29 Position of fdt map in data, or None if not found. Note that the
30 position returned is of the FDT header, i.e. before the FDT data
32 hdr_pos = data.find(FDTMAP_MAGIC)
35 hdr = data[hdr_pos:hdr_pos + FDTMAP_HDR_LEN]
36 if len(hdr) == FDTMAP_HDR_LEN:
40 class Entry_fdtmap(Entry):
41 """An entry which contains an FDT map
43 Properties / Entry arguments:
46 An FDT map is just a header followed by an FDT containing a list of all the
47 entries in the image. The root node corresponds to the image node in the
48 original FDT, and an image-name property indicates the image name in that
51 The header is the string _FDTMAP_ followed by 8 unused bytes.
53 When used, this entry will be populated with an FDT map which reflects the
54 entries in the current image. Hierarchy is preserved, and all offsets and
57 Note that the -u option must be provided to ensure that binman updates the
58 FDT with the position of each entry.
60 Example output for a simple image with U-Boot and an FDT map:
63 image-name = "binman";
65 image-pos = <0x00000000>;
66 offset = <0x00000000>;
69 image-pos = <0x00000000>;
70 offset = <0x00000000>;
74 image-pos = <0x00000004>;
75 offset = <0x00000004>;
79 If allow-repack is used then 'orig-offset' and 'orig-size' properties are
80 added as necessary. See the binman README.
82 def __init__(self, section, etype, node):
83 Entry.__init__(self, section, etype, node)
86 """Build an FDT map from the entries in the current image
92 """Add a node to the FDT map"""
93 for pname, prop in node.props.items():
94 fsw.property(pname, prop.bytes)
95 for subnode in node.subnodes:
96 with fsw.add_node(subnode.name):
99 data = state.GetFdtContents('fdtmap')[1]
100 # If we have an fdtmap it means that we are using this as the
101 # fdtmap for this image.
103 # Get the FDT data into an Fdt object
104 data = state.GetFdtContents()[1]
105 infdt = Fdt.FromData(data)
108 # Find the node for the image containing the Fdt-map entry
109 path = self.section.GetPath()
110 self.Detail("Fdtmap: Using section '%s' (path '%s')" %
111 (self.section.name, path))
112 node = infdt.GetNode(path)
114 self.Raise("Internal error: Cannot locate node for path '%s'" %
117 # Build a new tree with all nodes and properties starting from that
120 fsw.finish_reservemap()
121 with fsw.add_node(''):
122 fsw.property_string('image-node', node.name)
126 # Pack this new FDT and return its contents
128 outfdt = Fdt.FromData(fdt.as_bytearray())
129 data = outfdt.GetContents()
130 data = FDTMAP_MAGIC + tools.GetBytes(0, 8) + data
133 def ObtainContents(self):
134 """Obtain a placeholder for the fdt-map contents"""
135 self.SetContents(self._GetFdtmap())
138 def ProcessContents(self):
139 """Write an updated version of the FDT map to this entry
141 This is necessary since new data may have been written back to it during
142 processing, e.g. the image-pos properties.
144 return self.ProcessContentsUpdate(self._GetFdtmap())