| # SPDX-License-Identifier: GPL-2.0+ |
| # Copyright (c) 2018 Google, Inc |
| # Written by Simon Glass <sjg@chromium.org> |
| |
| """# Entry-type module for a full map of the firmware image |
| |
| This handles putting an FDT into the image with just the information about the |
| image. |
| """ |
| |
| import libfdt |
| |
| from entry import Entry |
| from fdt import Fdt |
| import state |
| import tools |
| import tout |
| |
| FDTMAP_MAGIC = b'_FDTMAP_' |
| FDTMAP_HDR_LEN = 16 |
| |
| def LocateFdtmap(data): |
| """Search an image for an fdt map |
| |
| Args: |
| data: Data to search |
| |
| Returns: |
| Position of fdt map in data, or None if not found. Note that the |
| position returned is of the FDT header, i.e. before the FDT data |
| """ |
| hdr_pos = data.find(FDTMAP_MAGIC) |
| size = len(data) |
| if hdr_pos != -1: |
| hdr = data[hdr_pos:hdr_pos + FDTMAP_HDR_LEN] |
| if len(hdr) == FDTMAP_HDR_LEN: |
| return hdr_pos |
| return None |
| |
| class Entry_fdtmap(Entry): |
| """An entry which contains an FDT map |
| |
| Properties / Entry arguments: |
| None |
| |
| An FDT map is just a header followed by an FDT containing a list of all the |
| entries in the image. The root node corresponds to the image node in the |
| original FDT, and an image-name property indicates the image name in that |
| original tree. |
| |
| The header is the string _FDTMAP_ followed by 8 unused bytes. |
| |
| When used, this entry will be populated with an FDT map which reflects the |
| entries in the current image. Hierarchy is preserved, and all offsets and |
| sizes are included. |
| |
| Note that the -u option must be provided to ensure that binman updates the |
| FDT with the position of each entry. |
| |
| Example output for a simple image with U-Boot and an FDT map: |
| |
| / { |
| image-name = "binman"; |
| size = <0x00000112>; |
| image-pos = <0x00000000>; |
| offset = <0x00000000>; |
| u-boot { |
| size = <0x00000004>; |
| image-pos = <0x00000000>; |
| offset = <0x00000000>; |
| }; |
| fdtmap { |
| size = <0x0000010e>; |
| image-pos = <0x00000004>; |
| offset = <0x00000004>; |
| }; |
| }; |
| |
| If allow-repack is used then 'orig-offset' and 'orig-size' properties are |
| added as necessary. See the binman README. |
| """ |
| def __init__(self, section, etype, node): |
| Entry.__init__(self, section, etype, node) |
| |
| def _GetFdtmap(self): |
| """Build an FDT map from the entries in the current image |
| |
| Returns: |
| FDT map binary data |
| """ |
| def _AddNode(node): |
| """Add a node to the FDT map""" |
| for pname, prop in node.props.items(): |
| fsw.property(pname, prop.bytes) |
| for subnode in node.subnodes: |
| with fsw.add_node(subnode.name): |
| _AddNode(subnode) |
| |
| data = state.GetFdtContents('fdtmap')[1] |
| # If we have an fdtmap it means that we are using this as the |
| # fdtmap for this image. |
| if data is None: |
| # Get the FDT data into an Fdt object |
| data = state.GetFdtContents()[1] |
| infdt = Fdt.FromData(data) |
| infdt.Scan() |
| |
| # Find the node for the image containing the Fdt-map entry |
| path = self.section.GetPath() |
| self.Detail("Fdtmap: Using section '%s' (path '%s')" % |
| (self.section.name, path)) |
| node = infdt.GetNode(path) |
| if not node: |
| self.Raise("Internal error: Cannot locate node for path '%s'" % |
| path) |
| |
| # Build a new tree with all nodes and properties starting from that |
| # node |
| fsw = libfdt.FdtSw() |
| fsw.finish_reservemap() |
| with fsw.add_node(''): |
| fsw.property_string('image-node', node.name) |
| _AddNode(node) |
| fdt = fsw.as_fdt() |
| |
| # Pack this new FDT and return its contents |
| fdt.pack() |
| outfdt = Fdt.FromData(fdt.as_bytearray()) |
| data = outfdt.GetContents() |
| data = FDTMAP_MAGIC + tools.GetBytes(0, 8) + data |
| return data |
| |
| def ObtainContents(self): |
| """Obtain a placeholder for the fdt-map contents""" |
| self.SetContents(self._GetFdtmap()) |
| return True |
| |
| def ProcessContents(self): |
| """Write an updated version of the FDT map to this entry |
| |
| This is necessary since new data may have been written back to it during |
| processing, e.g. the image-pos properties. |
| """ |
| return self.ProcessContentsUpdate(self._GetFdtmap()) |