images to be created.
"""
-from __future__ import print_function
-
from collections import OrderedDict
import re
import sys
-from entry import Entry
-import fdt_util
-import tools
+from binman.entry import Entry
+from dtoc import fdt_util
+from patman import tools
+from patman import tout
class Entry_section(Entry):
def __init__(self, section, etype, node, test=False):
if not test:
Entry.__init__(self, section, etype, node)
- if section:
- self.image = section.image
self._entries = OrderedDict()
self._pad_byte = 0
self._sort = False
self._skip_at_start = None
self._end_4gb = False
- if not test:
- self._ReadNode()
- self._ReadEntries()
-
- def _Raise(self, msg):
- """Raises an error for this section
-
- Args:
- msg: Error message to use in the raise string
- Raises:
- ValueError()
- """
- raise ValueError("Section '%s': %s" % (self._node.path, msg))
- def _ReadNode(self):
+ def ReadNode(self):
"""Read properties from the image node"""
+ Entry.ReadNode(self)
self._pad_byte = fdt_util.GetInt(self._node, 'pad-byte', 0)
self._sort = fdt_util.GetBool(self._node, 'sort-by-offset')
self._end_4gb = fdt_util.GetBool(self._node, 'end-at-4gb')
if filename:
self._filename = filename
+ self._ReadEntries()
+
def _ReadEntries(self):
for node in self._node.subnodes:
if node.name == 'hash':
continue
entry = Entry.Create(self, node)
+ entry.ReadNode()
entry.SetPrefix(self._name_prefix)
self._entries[node.name] = entry
+ def _Raise(self, msg):
+ """Raises an error for this section
+
+ Args:
+ msg: Error message to use in the raise string
+ Raises:
+ ValueError()
+ """
+ raise ValueError("Section '%s': %s" % (self._node.path, msg))
+
def GetFdts(self):
fdts = {}
for entry in self._entries.values():
return self.GetEntryContents()
def GetData(self):
- section_data = tools.GetBytes(self._pad_byte, self.size)
+ section_data = b''
for entry in self._entries.values():
data = entry.GetData()
- base = self.pad_before + entry.offset - self._skip_at_start
- section_data = (section_data[:base] + data +
- section_data[base + len(data):])
+ base = self.pad_before + (entry.offset or 0) - self._skip_at_start
+ pad = base - len(section_data)
+ if pad > 0:
+ section_data += tools.GetBytes(self._pad_byte, pad)
+ section_data += data
+ if self.size:
+ pad = self.size - len(section_data)
+ if pad > 0:
+ section_data += tools.GetBytes(self._pad_byte, pad)
self.Detail('GetData: %d entries, total size %#x' %
(len(self._entries), len(section_data)))
return section_data
return entry.GetData()
source_entry.Raise("Cannot find entry for node '%s'" % node.name)
- def LookupSymbol(self, sym_name, optional, msg):
+ def LookupSymbol(self, sym_name, optional, msg, base_addr):
"""Look up a symbol in an ELF file
Looks up a symbol in an ELF file. Only entry types which come from an
ELF image can be used by this function.
- At present the only entry property supported is offset.
+ At present the only entry properties supported are:
+ offset
+ image_pos - 'base_addr' is added if this is not an end-at-4gb image
+ size
Args:
sym_name: Symbol name in the ELF file to look up in the format
optional: True if the symbol is optional. If False this function
will raise if the symbol is not found
msg: Message to display if an error occurs
+ base_addr: Base address of image. This is added to the returned
+ image_pos in most cases so that the returned position indicates
+ where the targetted entry/binary has actually been loaded. But
+ if end-at-4gb is used, this is not done, since the binary is
+ already assumed to be linked to the ROM position and using
+ execute-in-place (XIP).
Returns:
Value that should be assigned to that symbol, or None if it was
if prop_name == 'offset':
return entry.offset
elif prop_name == 'image_pos':
- return entry.image_pos
+ value = entry.image_pos
+ if not self.GetImage()._end_4gb:
+ value += base_addr
+ return value
+ if prop_name == 'size':
+ return entry.size
else:
raise ValueError("%s: No such property '%s'" % (msg, prop_name))
Image size as an integer number of bytes, which may be None if the
image size is dynamic and its sections have not yet been packed
"""
- return self.image.size
+ return self.GetImage().size
def FindEntryType(self, etype):
"""Find an entry type in the section
self.image_pos, None, self.offset, self)
for entry in self._entries.values():
entry.ListEntries(entries, indent + 1)
+
+ def LoadData(self, decomp=True):
+ for entry in self._entries.values():
+ entry.LoadData(decomp)
+ self.Detail('Loaded data')
+
+ def GetImage(self):
+ """Get the image containing this section
+
+ Note that a top-level section is actually an Image, so this function may
+ return self.
+
+ Returns:
+ Image object containing this section
+ """
+ if not self.section:
+ return self
+ return self.section.GetImage()
+
+ def GetSort(self):
+ """Check if the entries in this section will be sorted
+
+ Returns:
+ True if to be sorted, False if entries will be left in the order
+ they appear in the device tree
+ """
+ return self._sort
+
+ def ReadData(self, decomp=True):
+ tout.Info("ReadData path='%s'" % self.GetPath())
+ parent_data = self.section.ReadData(True)
+ tout.Info('%s: Reading data from offset %#x-%#x, size %#x' %
+ (self.GetPath(), self.offset, self.offset + self.size,
+ self.size))
+ data = parent_data[self.offset:self.offset + self.size]
+ return data
+
+ def ReadChildData(self, child, decomp=True):
+ tout.Debug("ReadChildData for child '%s'" % child.GetPath())
+ parent_data = self.ReadData(True)
+ offset = child.offset - self._skip_at_start
+ tout.Debug("Extract for child '%s': offset %#x, skip_at_start %#x, result %#x" %
+ (child.GetPath(), child.offset, self._skip_at_start, offset))
+ data = parent_data[offset:offset + child.size]
+ if decomp:
+ indata = data
+ data = tools.Decompress(indata, child.compress)
+ if child.uncomp_size:
+ tout.Info("%s: Decompressing data size %#x with algo '%s' to data size %#x" %
+ (child.GetPath(), len(indata), child.compress,
+ len(data)))
+ return data
+
+ def WriteChildData(self, child):
+ return True