xref: /openbmc/u-boot/tools/binman/image.py (revision d24c1d0f4da3b081a4fedf7ae2a08790871f08d0)
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