183d290c5STom Rini# SPDX-License-Identifier: GPL-2.0+ 2bf7fd50bSSimon Glass# Copyright (c) 2016 Google, Inc 3bf7fd50bSSimon Glass# Written by Simon Glass <sjg@chromium.org> 4bf7fd50bSSimon Glass# 5bf7fd50bSSimon Glass# Class for an image, the output of binman 6bf7fd50bSSimon Glass# 7bf7fd50bSSimon Glass 819790632SSimon Glassfrom __future__ import print_function 919790632SSimon Glass 10bf7fd50bSSimon Glassfrom collections import OrderedDict 11bf7fd50bSSimon Glassfrom operator import attrgetter 1219790632SSimon Glassimport re 1319790632SSimon Glassimport sys 14bf7fd50bSSimon Glass 15bf7fd50bSSimon Glassimport fdt_util 168f1da50cSSimon Glassimport bsection 17bf7fd50bSSimon Glassimport tools 18bf7fd50bSSimon Glass 19bf7fd50bSSimon Glassclass Image: 20bf7fd50bSSimon Glass """A Image, representing an output from binman 21bf7fd50bSSimon Glass 22bf7fd50bSSimon Glass An image is comprised of a collection of entries each containing binary 23bf7fd50bSSimon Glass data. The image size must be large enough to hold all of this data. 24bf7fd50bSSimon Glass 25bf7fd50bSSimon Glass This class implements the various operations needed for images. 26bf7fd50bSSimon Glass 27bf7fd50bSSimon Glass Atrtributes: 28bf7fd50bSSimon Glass _node: Node object that contains the image definition in device tree 29bf7fd50bSSimon Glass _name: Image name 30bf7fd50bSSimon Glass _size: Image size in bytes, or None if not known yet 31bf7fd50bSSimon Glass _filename: Output filename for image 328f1da50cSSimon Glass _sections: Sections present in this image (may be one or more) 337ae5f315SSimon Glass 347ae5f315SSimon Glass Args: 357ae5f315SSimon Glass test: True if this is being called from a test of Images. This this case 367ae5f315SSimon Glass there is no device tree defining the structure of the section, so 377ae5f315SSimon Glass we create a section manually. 38bf7fd50bSSimon Glass """ 3919790632SSimon Glass def __init__(self, name, node, test=False): 40bf7fd50bSSimon Glass self._node = node 41bf7fd50bSSimon Glass self._name = name 42bf7fd50bSSimon Glass self._size = None 43bf7fd50bSSimon Glass self._filename = '%s.bin' % self._name 448f1da50cSSimon Glass if test: 4508723a7aSSimon Glass self._section = bsection.Section('main-section', None, self._node, 4608723a7aSSimon Glass self, True) 478f1da50cSSimon Glass else: 48bf7fd50bSSimon Glass self._ReadNode() 49bf7fd50bSSimon Glass 50bf7fd50bSSimon Glass def _ReadNode(self): 51bf7fd50bSSimon Glass """Read properties from the image node""" 52bf7fd50bSSimon Glass self._size = fdt_util.GetInt(self._node, 'size') 53bf7fd50bSSimon Glass filename = fdt_util.GetString(self._node, 'filename') 54bf7fd50bSSimon Glass if filename: 55bf7fd50bSSimon Glass self._filename = filename 5608723a7aSSimon Glass self._section = bsection.Section('main-section', None, self._node, self) 57bf7fd50bSSimon Glass 58539aece5SSimon Glass def GetFdtSet(self): 59539aece5SSimon Glass """Get the set of device tree files used by this image""" 60539aece5SSimon Glass return self._section.GetFdtSet() 61539aece5SSimon Glass 620a98b28bSSimon Glass def ExpandEntries(self): 630a98b28bSSimon Glass """Expand out any entries which have calculated sub-entries 640a98b28bSSimon Glass 650a98b28bSSimon Glass Some entries are expanded out at runtime, e.g. 'files', which produces 660a98b28bSSimon Glass a section containing a list of files. Process these entries so that 670a98b28bSSimon Glass this information is added to the device tree. 680a98b28bSSimon Glass """ 690a98b28bSSimon Glass self._section.ExpandEntries() 700a98b28bSSimon Glass 71078ab1a2SSimon Glass def AddMissingProperties(self): 72078ab1a2SSimon Glass """Add properties that are not present in the device tree 73078ab1a2SSimon Glass 743ab9598dSSimon Glass When binman has completed packing the entries the offset and size of 75078ab1a2SSimon Glass each entry are known. But before this the device tree may not specify 76078ab1a2SSimon Glass these. Add any missing properties, with a dummy value, so that the 77078ab1a2SSimon Glass size of the entry is correct. That way we can insert the correct values 78078ab1a2SSimon Glass later. 79078ab1a2SSimon Glass """ 80078ab1a2SSimon Glass self._section.AddMissingProperties() 81078ab1a2SSimon Glass 82ecab8973SSimon Glass def ProcessFdt(self, fdt): 836ed45ba0SSimon Glass """Allow entries to adjust the device tree 846ed45ba0SSimon Glass 856ed45ba0SSimon Glass Some entries need to adjust the device tree for their purposes. This 866ed45ba0SSimon Glass may involve adding or deleting properties. 876ed45ba0SSimon Glass """ 88ecab8973SSimon Glass return self._section.ProcessFdt(fdt) 89ecab8973SSimon Glass 90bf7fd50bSSimon Glass def GetEntryContents(self): 918f1da50cSSimon Glass """Call ObtainContents() for the section 92bf7fd50bSSimon Glass """ 938f1da50cSSimon Glass self._section.GetEntryContents() 94bf7fd50bSSimon Glass 953ab9598dSSimon Glass def GetEntryOffsets(self): 963ab9598dSSimon Glass """Handle entries that want to set the offset/size of other entries 97bf7fd50bSSimon Glass 983ab9598dSSimon Glass This calls each entry's GetOffsets() method. If it returns a list 99bf7fd50bSSimon Glass of entries to update, it updates them. 100bf7fd50bSSimon Glass """ 1013ab9598dSSimon Glass self._section.GetEntryOffsets() 102bf7fd50bSSimon Glass 103bf7fd50bSSimon Glass def PackEntries(self): 104bf7fd50bSSimon Glass """Pack all entries into the image""" 1058f1da50cSSimon Glass self._section.PackEntries() 106bf7fd50bSSimon Glass 1078f1da50cSSimon Glass def CheckSize(self): 1088f1da50cSSimon Glass """Check that the image contents does not exceed its size, etc.""" 1098f1da50cSSimon Glass self._size = self._section.CheckSize() 110bf7fd50bSSimon Glass 111bf7fd50bSSimon Glass def CheckEntries(self): 112bf7fd50bSSimon Glass """Check that entries do not overlap or extend outside the image""" 1138f1da50cSSimon Glass self._section.CheckEntries() 114bf7fd50bSSimon Glass 115078ab1a2SSimon Glass def SetCalculatedProperties(self): 116078ab1a2SSimon Glass self._section.SetCalculatedProperties() 117078ab1a2SSimon Glass 118dbf6be9fSSimon Glass def SetImagePos(self): 119dbf6be9fSSimon Glass self._section.SetImagePos(0) 120dbf6be9fSSimon Glass 121bf7fd50bSSimon Glass def ProcessEntryContents(self): 122bf7fd50bSSimon Glass """Call the ProcessContents() method for each entry 123bf7fd50bSSimon Glass 124bf7fd50bSSimon Glass This is intended to adjust the contents as needed by the entry type. 125bf7fd50bSSimon Glass """ 1268f1da50cSSimon Glass self._section.ProcessEntryContents() 127bf7fd50bSSimon Glass 12819790632SSimon Glass def WriteSymbols(self): 12919790632SSimon Glass """Write symbol values into binary files for access at run time""" 1308f1da50cSSimon Glass self._section.WriteSymbols() 13119790632SSimon Glass 132bf7fd50bSSimon Glass def BuildImage(self): 133bf7fd50bSSimon Glass """Write the image to a file""" 134bf7fd50bSSimon Glass fname = tools.GetOutputFilename(self._filename) 135bf7fd50bSSimon Glass with open(fname, 'wb') as fd: 1368f1da50cSSimon Glass self._section.BuildSection(fd, 0) 137bf7fd50bSSimon Glass 1388f1da50cSSimon Glass def GetEntries(self): 1398f1da50cSSimon Glass return self._section.GetEntries() 1403b0c3821SSimon Glass 1413b0c3821SSimon Glass def WriteMap(self): 142*163ed6c3SSimon Glass """Write a map of the image to a .map file 143*163ed6c3SSimon Glass 144*163ed6c3SSimon Glass Returns: 145*163ed6c3SSimon Glass Filename of map file written 146*163ed6c3SSimon Glass """ 1473b0c3821SSimon Glass filename = '%s.map' % self._name 1483b0c3821SSimon Glass fname = tools.GetOutputFilename(filename) 1493b0c3821SSimon Glass with open(fname, 'w') as fd: 1501be70d20SSimon Glass print('%8s %8s %8s %s' % ('ImagePos', 'Offset', 'Size', 'Name'), 1511be70d20SSimon Glass file=fd) 1523b0c3821SSimon Glass self._section.WriteMap(fd, 0) 153*163ed6c3SSimon Glass return fname 154