1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2018 Google, Inc
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
11 from binman.entry import Entry
12 from patman import tools
13 from patman import tout
15 FDTMAP_MAGIC = b'_FDTMAP_'
18 def LocateFdtmap(data):
19 """Search an image for an fdt map
25 Position of fdt map in data, or None if not found. Note that the
26 position returned is of the FDT header, i.e. before the FDT data
28 hdr_pos = data.find(FDTMAP_MAGIC)
31 hdr = data[hdr_pos:hdr_pos + FDTMAP_HDR_LEN]
32 if len(hdr) == FDTMAP_HDR_LEN:
36 class Entry_fdtmap(Entry):
37 """An entry which contains an FDT map
39 Properties / Entry arguments:
42 An FDT map is just a header followed by an FDT containing a list of all the
43 entries in the image. The root node corresponds to the image node in the
44 original FDT, and an image-name property indicates the image name in that
47 The header is the string _FDTMAP_ followed by 8 unused bytes.
49 When used, this entry will be populated with an FDT map which reflects the
50 entries in the current image. Hierarchy is preserved, and all offsets and
53 Note that the -u option must be provided to ensure that binman updates the
54 FDT with the position of each entry.
56 Example output for a simple image with U-Boot and an FDT map:
59 image-name = "binman";
61 image-pos = <0x00000000>;
62 offset = <0x00000000>;
65 image-pos = <0x00000000>;
66 offset = <0x00000000>;
70 image-pos = <0x00000004>;
71 offset = <0x00000004>;
75 If allow-repack is used then 'orig-offset' and 'orig-size' properties are
76 added as necessary. See the binman README.
78 def __init__(self, section, etype, node):
79 # Put these here to allow entry-docs and help to work without libfdt
85 from binman import state
86 from dtoc.fdt import Fdt
88 Entry.__init__(self, section, etype, node)
91 """Build an FDT map from the entries in the current image
97 """Add a node to the FDT map"""
98 for pname, prop in node.props.items():
99 fsw.property(pname, prop.bytes)
100 for subnode in node.subnodes:
101 with fsw.add_node(subnode.name):
104 data = state.GetFdtContents('fdtmap')[1]
105 # If we have an fdtmap it means that we are using this as the
106 # fdtmap for this image.
108 # Get the FDT data into an Fdt object
109 data = state.GetFdtContents()[1]
110 infdt = Fdt.FromData(data)
113 # Find the node for the image containing the Fdt-map entry
114 path = self.section.GetPath()
115 self.Detail("Fdtmap: Using section '%s' (path '%s')" %
116 (self.section.name, path))
117 node = infdt.GetNode(path)
119 self.Raise("Internal error: Cannot locate node for path '%s'" %
122 # Build a new tree with all nodes and properties starting from that
125 fsw.finish_reservemap()
126 with fsw.add_node(''):
127 fsw.property_string('image-node', node.name)
131 # Pack this new FDT and return its contents
133 outfdt = Fdt.FromData(fdt.as_bytearray())
134 data = outfdt.GetContents()
135 data = FDTMAP_MAGIC + tools.GetBytes(0, 8) + data
138 def ObtainContents(self):
139 """Obtain a placeholder for the fdt-map contents"""
140 self.SetContents(self._GetFdtmap())
143 def ProcessContents(self):
144 """Write an updated version of the FDT map to this entry
146 This is necessary since new data may have been written back to it during
147 processing, e.g. the image-pos properties.
149 return self.ProcessContentsUpdate(self._GetFdtmap())