def __init__(self, section, etype, node): # Put this here to allow entry-docs and help to work without libfdt global state from binman import state Entry.__init__(self, section, etype, node) self._cbfs_arg = fdt_util.GetString(node, 'cbfs-arch', 'x86') self._cbfs_entries = OrderedDict() self._ReadSubnodes() self.reader = None
def __init__(self, section, etype, node): # Put these here to allow entry-docs and help to work without libfdt global libfdt global state global Fdt import libfdt from binman import state from dtoc.fdt import Fdt Entry.__init__(self, section, etype, node)
def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) value = fdt_util.GetString(self._node, 'text') if value: value = tools.ToBytes(value) else: label, = self.GetEntryArgsOrProps([EntryArg('text-label', str)]) self.text_label = label if self.text_label: value, = self.GetEntryArgsOrProps( [EntryArg(self.text_label, str)]) value = tools.ToBytes(value) if value is not None else value self.value = value
def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) self.content = fdt_util.GetPhandleList(self._node, 'content') if not self.content: self.Raise("Vblock must have a 'content' property") (self.keydir, self.keyblock, self.signprivate, self.version, self.kernelkey, self.preamble_flags) = self.GetEntryArgsOrProps([ EntryArg('keydir', str), EntryArg('keyblock', str), EntryArg('signprivate', str), EntryArg('version', int), EntryArg('kernelkey', str), EntryArg('preamble-flags', int) ])
def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) self.hardware_id, self.keydir, self.bmpblk = self.GetEntryArgsOrProps([ EntryArg('hardware-id', str), EntryArg('keydir', str), EntryArg('bmpblk', str) ]) # Read in the GBB flags from the config self.gbb_flags = 0 flags_node = node.FindNode('flags') if flags_node: for flag, value in gbb_flag_properties.items(): if fdt_util.GetBool(flags_node, flag): self.gbb_flags |= value
def ReadChildData(self, child, decomp=True): if not self.reader: data = Entry.ReadData(self, True) self.reader = cbfs_util.CbfsReader(data) reader = self.reader cfile = reader.files.get(child.name) return cfile.data if decomp else cfile.orig_data
def _AddNode(base_node, depth, node): """Add a node to the FIT Args: base_node: Base Node of the FIT (with 'description' property) depth: Current node depth (0 is the base node) node: Current node to process There are two cases to deal with: - hash and signature nodes which become part of the FIT - binman entries which are used to define the 'data' for each image """ for pname, prop in node.props.items(): if pname.startswith('fit,'): self._fit_props[pname] = prop else: fsw.property(pname, prop.bytes) rel_path = node.path[len(base_node.path):] has_images = depth == 2 and rel_path.startswith('/images/') for subnode in node.subnodes: if has_images and not (subnode.name.startswith('hash') or subnode.name.startswith('signature')): # This is a content node. We collect all of these together # and put them in the 'data' property. They do not appear # in the FIT. entry = Entry.Create(self.section, subnode) entry.ReadNode() self._fit_content[rel_path].append(entry) else: with fsw.add_node(subnode.name): _AddNode(base_node, depth + 1, subnode)
def _add_entries(base_node, depth, node): """Add entries for any nodes that need them Args: base_node: Base Node of the FIT (with 'description' property) depth: Current node depth (0 is the base 'fit' node) node: Current node to process Here we only need to provide binman entries which are used to define the 'data' for each image. We create an entry_Section for each. """ rel_path = node.path[len(base_node.path):] in_images = rel_path.startswith('/images') has_images = depth == 2 and in_images if has_images: # This node is a FIT subimage node (e.g. "/images/kernel") # containing content nodes. We collect the subimage nodes and # section entries for them here to merge the content subnodes # together and put the merged contents in the subimage node's # 'data' property later. entry = Entry.Create(self.section, node, etype='section') entry.ReadNode() # The hash subnodes here are for mkimage, not binman. entry.SetUpdateHash(False) self._entries[rel_path] = entry for subnode in node.subnodes: _add_entries(base_node, depth + 1, subnode)
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 _ReadEntries(self): for node in self._node.subnodes: if node.name.startswith('hash') or node.name.startswith('signature'): continue entry = Entry.Create(self, node) entry.ReadNode() entry.SetPrefix(self._name_prefix) self._entries[node.name] = entry
def SetCalculatedProperties(self): """Set the value of device-tree properties calculated by binman""" Entry.SetCalculatedProperties(self) for entry in self._cbfs_entries.values(): state.SetInt(entry._node, 'offset', entry.offset) state.SetInt(entry._node, 'size', entry.size) state.SetInt(entry._node, 'image-pos', entry.image_pos) if entry.uncomp_size is not None: state.SetInt(entry._node, 'uncomp-size', entry.uncomp_size)
def ReadEntries(self): """Read the subnodes to find out what should go in this IFWI""" for node in self._node.subnodes: entry = Entry.Create(self.section, node) entry.ReadNode() entry._ifwi_replace = fdt_util.GetBool(node, 'ifwi-replace') entry._ifwi_subpart = fdt_util.GetString(node, 'ifwi-subpart') entry._ifwi_entry_name = fdt_util.GetString(node, 'ifwi-entry') self._ifwi_entries[entry._ifwi_subpart] = entry
def AddMissingProperties(self): Entry.AddMissingProperties(self) for entry in self._cbfs_entries.values(): entry.AddMissingProperties() if entry._cbfs_compress: state.AddZeroProp(entry._node, 'uncomp-size') # Store the 'compress' property, since we don't look at # 'cbfs-compress' in Entry.ReadData() state.AddString(entry._node, 'compress', cbfs_util.compress_name(entry._cbfs_compress))
def WriteMap(self, fd, indent): """Write a map of the section to a .map file Args: fd: File to write the map to """ Entry.WriteMapLine(fd, indent, self.name, self.offset or 0, self.size, self.image_pos) for entry in self._entries.values(): entry.WriteMap(fd, indent + 1)
def ReadEntries(self): for node in self._node.subnodes: if node.name.startswith('hash') or node.name.startswith('signature'): continue entry = Entry.Create(self, node, expanded=self.GetImage().use_expanded, missing_etype=self.GetImage().missing_etype) entry.ReadNode() entry.SetPrefix(self._name_prefix) self._entries[node.name] = entry
def WriteEntryDocs(modules, test_missing=None): """Write out documentation for all entries Args: modules: List of Module objects to get docs for test_missing: Used for testing only, to force an entry's documeentation to show as missing even if it is present. Should be set to None in normal use. """ from binman.entry import Entry Entry.WriteDocs(modules, test_missing)
def ReadEntries(self): """Read the subnodes to find out what should go in this CBFS""" for node in self._node.subnodes: entry = Entry.Create(self, node) entry.ReadNode() entry._cbfs_name = fdt_util.GetString(node, 'cbfs-name', entry.name) entry._type = fdt_util.GetString(node, 'cbfs-type') compress = fdt_util.GetString(node, 'cbfs-compress', 'none') entry._cbfs_offset = fdt_util.GetInt(node, 'cbfs-offset') entry._cbfs_compress = cbfs_util.find_compress(compress) if entry._cbfs_compress is None: self.Raise("Invalid compression in '%s': '%s'" % (node.name, compress)) self._entries[entry._cbfs_name] = entry
def SetImagePos(self, image_pos): """Override this function to set all the entry properties from CBFS We can only do this once image_pos is known Args: image_pos: Position of this entry in the image """ Entry.SetImagePos(self, image_pos) # Now update the entries with info from the CBFS entries for entry in self._cbfs_entries.values(): cfile = entry._cbfs_file entry.size = cfile.data_len entry.offset = cfile.calced_cbfs_offset entry.image_pos = self.image_pos + entry.offset if entry._cbfs_compress: entry.uncomp_size = cfile.memlen
def _AddNode(base_node, depth, node): """Add a node to the FIT Args: base_node: Base Node of the FIT (with 'description' property) depth: Current node depth (0 is the base 'fit' node) node: Current node to process There are two cases to deal with: - hash and signature nodes which become part of the FIT - binman entries which are used to define the 'data' for each image """ for pname, prop in node.props.items(): if not pname.startswith('fit,'): _process_prop(pname, prop) rel_path = node.path[len(base_node.path):] in_images = rel_path.startswith('/images') has_images = depth == 2 and in_images if has_images: # This node is a FIT subimage node (e.g. "/images/kernel") # containing content nodes. We collect the subimage nodes and # section entries for them here to merge the content subnodes # together and put the merged contents in the subimage node's # 'data' property later. entry = Entry.Create(self.section, node, etype='section') entry.ReadNode() # The hash subnodes here are for mkimage, not binman. entry.SetUpdateHash(False) self._entries[rel_path] = entry for subnode in node.subnodes: if has_images and not (subnode.name.startswith('hash') or subnode.name.startswith('signature')): # This subnode is a content node not meant to appear in # the FIT (e.g. "/images/kernel/u-boot"), so don't call # fsw.add_node() or _AddNode() for it. pass elif self.GetImage().generate and subnode.name.startswith('@'): _scan_node(subnode, depth, in_images) else: with fsw.add_node(subnode.name): _AddNode(base_node, depth + 1, subnode)
def Pack(self, offset): """Special pack method to set the offset to start/end of image""" if not self.offset: if self.location not in ['start', 'end']: self.Raise("Invalid location '%s', expected 'start' or 'end'" % self.location) order = self.GetSiblingOrder() if self.location != order and not self.section.GetSort(): self.Raise( "Invalid sibling order '%s' for image-header: Must be at '%s' to match location" % (order, self.location)) if self.location != 'end': offset = 0 else: image_size = self.section.GetImageSize() if image_size is None: # We don't know the image, but this must be the last entry, # so we can assume it goes offset = offset else: offset = image_size - IMAGE_HEADER_LEN offset += self.section.GetStartOffset() return Entry.Pack(self, offset)
def ReadEntries(self): """Read the subnodes to find out what should go in this FIP""" for node in self._node.subnodes: fip_type = None etype = None if node.name in FIP_TYPES: fip_type = node.name etype = 'blob-ext' entry = Entry.Create(self, node, etype) entry._fip_uuid = fdt_util.GetBytes(node, 'fip-uuid', UUID_LEN) if not fip_type and not entry._fip_uuid: fip_type = fdt_util.GetString(node, 'fip-type') if not fip_type: self.Raise( "Must provide a fip-type (node name '%s' is not a known FIP type)" % node.name) entry._fip_type = fip_type entry._fip_flags = fdt_util.GetInt64(node, 'fip-flags', 0) entry.ReadNode() entry._fip_name = node.name self._entries[entry._fip_name] = entry
def ReadNode(self): Entry.ReadNode(self) self.return_invalid_entry = fdt_util.GetBool(self._node, 'return-invalid-entry') self.return_unknown_contents = fdt_util.GetBool( self._node, 'return-unknown-contents') self.bad_update_contents = fdt_util.GetBool(self._node, 'bad-update-contents') self.bad_shrink_contents = fdt_util.GetBool(self._node, 'bad-shrink-contents') self.return_contents_once = fdt_util.GetBool(self._node, 'return-contents-once') self.bad_update_contents_twice = fdt_util.GetBool( self._node, 'bad-update-contents-twice') # Set to True when the entry is ready to process the FDT. self.process_fdt_ready = False self.never_complete_process_fdt = fdt_util.GetBool( self._node, 'never-complete-process-fdt') self.require_args = fdt_util.GetBool(self._node, 'require-args') # This should be picked up by GetEntryArgsOrProps() self.test_existing_prop = 'existing' self.force_bad_datatype = fdt_util.GetBool(self._node, 'force-bad-datatype') (self.test_str_fdt, self.test_str_arg, self.test_int_fdt, self.test_int_arg, existing) = self.GetEntryArgsOrProps([ EntryArg('test-str-fdt', str), EntryArg('test-str-arg', str), EntryArg('test-int-fdt', int), EntryArg('test-int-arg', int), EntryArg('test-existing-prop', str) ], self.require_args) if self.force_bad_datatype: self.GetEntryArgsOrProps([EntryArg('test-bad-datatype-arg', bool)]) self.return_contents = True self.contents = b'aa'
def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) self._filename = fdt_util.GetString(self._node, 'filename', self.etype) self.compress = fdt_util.GetString(self._node, 'compress', 'none')
def _AddNode(base_node, depth, node): """Add a node to the FIT Args: base_node: Base Node of the FIT (with 'description' property) depth: Current node depth (0 is the base node) node: Current node to process There are two cases to deal with: - hash and signature nodes which become part of the FIT - binman entries which are used to define the 'data' for each image """ for pname, prop in node.props.items(): if not pname.startswith('fit,'): if pname == 'default': val = prop.value # Handle the 'default' property if val.startswith('@'): if not self._fdts: continue if not self._fit_default_dt: self.Raise( "Generated 'default' node requires default-dt entry argument" ) if self._fit_default_dt not in self._fdts: self.Raise( "default-dt entry argument '%s' not found in fdt list: %s" % (self._fit_default_dt, ', '.join( self._fdts))) seq = self._fdts.index(self._fit_default_dt) val = val[1:].replace('DEFAULT-SEQ', str(seq + 1)) fsw.property_string(pname, val) continue fsw.property(pname, prop.bytes) rel_path = node.path[len(base_node.path):] in_images = rel_path.startswith('/images') has_images = depth == 2 and in_images if has_images: # This node is a FIT subimage node (e.g. "/images/kernel") # containing content nodes. We collect the subimage nodes and # section entries for them here to merge the content subnodes # together and put the merged contents in the subimage node's # 'data' property later. entry = Entry.Create(self.section, node, etype='section') entry.ReadNode() self._fit_sections[rel_path] = entry for subnode in node.subnodes: if has_images and not (subnode.name.startswith('hash') or subnode.name.startswith('signature')): # This subnode is a content node not meant to appear in # the FIT (e.g. "/images/kernel/u-boot"), so don't call # fsw.add_node() or _AddNode() for it. pass elif subnode.name.startswith('@'): if self._fdts: # Generate notes for each FDT for seq, fdt_fname in enumerate(self._fdts): node_name = subnode.name[1:].replace( 'SEQ', str(seq + 1)) fname = tools.GetInputFilename(fdt_fname + '.dtb') with fsw.add_node(node_name): for pname, prop in subnode.props.items(): val = prop.bytes.replace( b'NAME', tools.ToBytes(fdt_fname)) val = val.replace( b'SEQ', tools.ToBytes(str(seq + 1))) fsw.property(pname, val) # Add data for 'fdt' nodes (but not 'config') if depth == 1 and in_images: fsw.property('data', tools.ReadFile(fname)) else: if self._fdts is None: if self._fit_list_prop: self.Raise( "Generator node requires '%s' entry argument" % self._fit_list_prop.value) else: self.Raise( "Generator node requires 'fit,fdt-list' property" ) else: with fsw.add_node(subnode.name): _AddNode(base_node, depth + 1, subnode)
def ReadEntries(self): """Read the subnodes to find out what should go in this image""" for node in self._node.subnodes: entry = Entry.Create(self, node) entry.ReadNode() self._mkimage_entries[entry.name] = entry
def ReadNode(self): Entry.ReadNode(self) if self.size is None: self.Raise("'fill' entry must have a size property") self.fill_value = fdt_util.GetByte(self._node, 'fill-byte', 0)
def ListEntries(self, entries, indent): """Override this method to list all files in the section""" Entry.ListEntries(self, entries, indent) for entry in self._cbfs_entries.values(): entry.ListEntries(entries, indent + 1)
def ReadData(self, decomp=True): data = Entry.ReadData(self, True) return data
def ListEntries(self, entries, indent): """List the files in the section""" Entry.AddEntryInfo(entries, indent, self.name, 'section', self.size, self.image_pos, None, self.offset, self) for entry in self._entries.values(): entry.ListEntries(entries, indent + 1)
def __init__(self, section, etype, node): Entry.__init__(self, section, etype, node) self.location = fdt_util.GetString(self._node, 'location')