mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-08 19:11:53 +00:00
binman: Allow listing an image created by a newer version
If an older version of binman is used to list images created by a newer one, it is possible that it will contain entry types that are not supported. At present this produces an error. Adjust binman to use a plain 'blob' entry type to cope with this, so the image can at least be listed. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
7945077f79
commit
858436dfda
5 changed files with 74 additions and 18 deletions
|
@ -913,6 +913,11 @@ or with wildcards::
|
||||||
u-boot-dtb 180 108 u-boot-dtb 80 3b5
|
u-boot-dtb 180 108 u-boot-dtb 80 3b5
|
||||||
image-header bf8 8 image-header bf8
|
image-header bf8 8 image-header bf8
|
||||||
|
|
||||||
|
If an older version of binman is used to list images created by a newer one, it
|
||||||
|
is possible that it will contain entry types that are not supported. These still
|
||||||
|
show with the correct type, but binman just sees them as blobs (plain binary
|
||||||
|
data). Any special features of that etype are not supported by the old binman.
|
||||||
|
|
||||||
|
|
||||||
Extracting files from images
|
Extracting files from images
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
|
@ -102,7 +102,7 @@ class Entry(object):
|
||||||
self.allow_missing = False
|
self.allow_missing = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def Lookup(node_path, etype, expanded):
|
def FindEntryClass(etype, expanded):
|
||||||
"""Look up the entry class for a node.
|
"""Look up the entry class for a node.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -113,10 +113,9 @@ class Entry(object):
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The entry class object if found, else None if not found and expanded
|
The entry class object if found, else None if not found and expanded
|
||||||
is True
|
is True, else a tuple:
|
||||||
|
module name that could not be found
|
||||||
Raise:
|
exception received
|
||||||
ValueError if expanded is False and the class is not found
|
|
||||||
"""
|
"""
|
||||||
# Convert something like 'u-boot@0' to 'u_boot' since we are only
|
# Convert something like 'u-boot@0' to 'u_boot' since we are only
|
||||||
# interested in the type.
|
# interested in the type.
|
||||||
|
@ -137,30 +136,66 @@ class Entry(object):
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
if expanded:
|
if expanded:
|
||||||
return None
|
return None
|
||||||
raise ValueError("Unknown entry type '%s' in node '%s' (expected etype/%s.py, error '%s'" %
|
return module_name, e
|
||||||
(etype, node_path, module_name, e))
|
|
||||||
modules[module_name] = module
|
modules[module_name] = module
|
||||||
|
|
||||||
# Look up the expected class name
|
# Look up the expected class name
|
||||||
return getattr(module, 'Entry_%s' % module_name)
|
return getattr(module, 'Entry_%s' % module_name)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def Create(section, node, etype=None, expanded=False):
|
def Lookup(node_path, etype, expanded, missing_etype=False):
|
||||||
|
"""Look up the entry class for a node.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
node_node (str): Path name of Node object containing information
|
||||||
|
about the entry to create (used for errors)
|
||||||
|
etype (str): Entry type to use
|
||||||
|
expanded (bool): Use the expanded version of etype
|
||||||
|
missing_etype (bool): True to default to a blob etype if the
|
||||||
|
requested etype is not found
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The entry class object if found, else None if not found and expanded
|
||||||
|
is True
|
||||||
|
|
||||||
|
Raise:
|
||||||
|
ValueError if expanded is False and the class is not found
|
||||||
|
"""
|
||||||
|
# Convert something like 'u-boot@0' to 'u_boot' since we are only
|
||||||
|
# interested in the type.
|
||||||
|
cls = Entry.FindEntryClass(etype, expanded)
|
||||||
|
if cls is None:
|
||||||
|
return None
|
||||||
|
elif isinstance(cls, tuple):
|
||||||
|
if missing_etype:
|
||||||
|
cls = Entry.FindEntryClass('blob', False)
|
||||||
|
if isinstance(cls, tuple): # This should not fail
|
||||||
|
module_name, e = cls
|
||||||
|
raise ValueError(
|
||||||
|
"Unknown entry type '%s' in node '%s' (expected etype/%s.py, error '%s'" %
|
||||||
|
(etype, node_path, module_name, e))
|
||||||
|
return cls
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def Create(section, node, etype=None, expanded=False, missing_etype=False):
|
||||||
"""Create a new entry for a node.
|
"""Create a new entry for a node.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
section: Section object containing this node
|
section (entry_Section): Section object containing this node
|
||||||
node: Node object containing information about the entry to
|
node (Node): Node object containing information about the entry to
|
||||||
create
|
create
|
||||||
etype: Entry type to use, or None to work it out (used for tests)
|
etype (str): Entry type to use, or None to work it out (used for
|
||||||
expanded: True to use expanded versions of entries, where available
|
tests)
|
||||||
|
expanded (bool): Use the expanded version of etype
|
||||||
|
missing_etype (bool): True to default to a blob etype if the
|
||||||
|
requested etype is not found
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A new Entry object of the correct type (a subclass of Entry)
|
A new Entry object of the correct type (a subclass of Entry)
|
||||||
"""
|
"""
|
||||||
if not etype:
|
if not etype:
|
||||||
etype = fdt_util.GetString(node, 'type', node.name)
|
etype = fdt_util.GetString(node, 'type', node.name)
|
||||||
obj = Entry.Lookup(node.path, etype, expanded)
|
obj = Entry.Lookup(node.path, etype, expanded, missing_etype)
|
||||||
if obj and expanded:
|
if obj and expanded:
|
||||||
# Check whether to use the expanded entry
|
# Check whether to use the expanded entry
|
||||||
new_etype = etype + '-expanded'
|
new_etype = etype + '-expanded'
|
||||||
|
@ -170,7 +205,7 @@ class Entry(object):
|
||||||
else:
|
else:
|
||||||
obj = None
|
obj = None
|
||||||
if not obj:
|
if not obj:
|
||||||
obj = Entry.Lookup(node.path, etype, False)
|
obj = Entry.Lookup(node.path, etype, False, missing_etype)
|
||||||
|
|
||||||
# Call its constructor to get the object we want.
|
# Call its constructor to get the object we want.
|
||||||
return obj(section, etype, node)
|
return obj(section, etype, node)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import sys
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from binman import entry
|
from binman import entry
|
||||||
|
from binman.etype.blob import Entry_blob
|
||||||
from dtoc import fdt
|
from dtoc import fdt
|
||||||
from dtoc import fdt_util
|
from dtoc import fdt_util
|
||||||
from patman import tools
|
from patman import tools
|
||||||
|
@ -100,5 +101,13 @@ class TestEntry(unittest.TestCase):
|
||||||
self.assertIn("Unknown entry type 'missing' in node '/binman/u-boot'",
|
self.assertIn("Unknown entry type 'missing' in node '/binman/u-boot'",
|
||||||
str(e.exception))
|
str(e.exception))
|
||||||
|
|
||||||
|
def testMissingEtype(self):
|
||||||
|
"""Test use of a blob etype when the requested one is not available"""
|
||||||
|
ent = entry.Entry.Create(None, self.GetNode(), 'missing',
|
||||||
|
missing_etype=True)
|
||||||
|
self.assertTrue(isinstance(ent, Entry_blob))
|
||||||
|
self.assertEquals('missing', ent.etype)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -185,7 +185,8 @@ class Entry_section(Entry):
|
||||||
if node.name.startswith('hash') or node.name.startswith('signature'):
|
if node.name.startswith('hash') or node.name.startswith('signature'):
|
||||||
continue
|
continue
|
||||||
entry = Entry.Create(self, node,
|
entry = Entry.Create(self, node,
|
||||||
expanded=self.GetImage().use_expanded)
|
expanded=self.GetImage().use_expanded,
|
||||||
|
missing_etype=self.GetImage().missing_etype)
|
||||||
entry.ReadNode()
|
entry.ReadNode()
|
||||||
entry.SetPrefix(self._name_prefix)
|
entry.SetPrefix(self._name_prefix)
|
||||||
self._entries[node.name] = entry
|
self._entries[node.name] = entry
|
||||||
|
|
|
@ -63,9 +63,13 @@ class Image(section.Entry_section):
|
||||||
to ignore 'u-boot-bin' in this case, and build it ourselves in
|
to ignore 'u-boot-bin' in this case, and build it ourselves in
|
||||||
binman with 'u-boot-dtb.bin' and 'u-boot.dtb'. See
|
binman with 'u-boot-dtb.bin' and 'u-boot.dtb'. See
|
||||||
Entry_u_boot_expanded and Entry_blob_phase for details.
|
Entry_u_boot_expanded and Entry_blob_phase for details.
|
||||||
|
missing_etype: Use a default entry type ('blob') if the requested one
|
||||||
|
does not exist in binman. This is useful if an image was created by
|
||||||
|
binman a newer version of binman but we want to list it in an older
|
||||||
|
version which does not support all the entry types.
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, node, copy_to_orig=True, test=False,
|
def __init__(self, name, node, copy_to_orig=True, test=False,
|
||||||
ignore_missing=False, use_expanded=False):
|
ignore_missing=False, use_expanded=False, missing_etype=False):
|
||||||
super().__init__(None, 'section', node, test=test)
|
super().__init__(None, 'section', node, test=test)
|
||||||
self.copy_to_orig = copy_to_orig
|
self.copy_to_orig = copy_to_orig
|
||||||
self.name = 'main-section'
|
self.name = 'main-section'
|
||||||
|
@ -75,6 +79,7 @@ class Image(section.Entry_section):
|
||||||
self.fdtmap_data = None
|
self.fdtmap_data = None
|
||||||
self.allow_repack = False
|
self.allow_repack = False
|
||||||
self._ignore_missing = ignore_missing
|
self._ignore_missing = ignore_missing
|
||||||
|
self.missing_etype = missing_etype
|
||||||
self.use_expanded = use_expanded
|
self.use_expanded = use_expanded
|
||||||
self.test_section_timeout = False
|
self.test_section_timeout = False
|
||||||
if not test:
|
if not test:
|
||||||
|
@ -124,7 +129,8 @@ class Image(section.Entry_section):
|
||||||
|
|
||||||
# Return an Image with the associated nodes
|
# Return an Image with the associated nodes
|
||||||
root = dtb.GetRoot()
|
root = dtb.GetRoot()
|
||||||
image = Image('image', root, copy_to_orig=False, ignore_missing=True)
|
image = Image('image', root, copy_to_orig=False, ignore_missing=True,
|
||||||
|
missing_etype=True)
|
||||||
|
|
||||||
image.image_node = fdt_util.GetString(root, 'image-node', 'image')
|
image.image_node = fdt_util.GetString(root, 'image-node', 'image')
|
||||||
image.fdtmap_dtb = dtb
|
image.fdtmap_dtb = dtb
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue