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>
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index 2205bc8..e7a8365 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -102,7 +102,7 @@
         self.allow_missing = False
 
     @staticmethod
-    def Lookup(node_path, etype, expanded):
+    def FindEntryClass(etype, expanded):
         """Look up the entry class for a node.
 
         Args:
@@ -113,10 +113,9 @@
 
         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
+                is True, else a tuple:
+                    module name that could not be found
+                    exception received
         """
         # Convert something like 'u-boot@0' to 'u_boot' since we are only
         # interested in the type.
@@ -137,30 +136,66 @@
             except ImportError as e:
                 if expanded:
                     return None
-                raise ValueError("Unknown entry type '%s' in node '%s' (expected etype/%s.py, error '%s'" %
-                                 (etype, node_path, module_name, e))
+                return module_name, e
             modules[module_name] = module
 
         # Look up the expected class name
         return getattr(module, 'Entry_%s' % module_name)
 
     @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.
 
         Args:
-            section:  Section object containing this node
-            node:     Node object containing information about the entry to
-                      create
-            etype:    Entry type to use, or None to work it out (used for tests)
-            expanded: True to use expanded versions of entries, where available
+            section (entry_Section):  Section object containing this node
+            node (Node): Node object containing information about the entry to
+                create
+            etype (str): Entry type to use, or None to work it out (used for
+                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:
             A new Entry object of the correct type (a subclass of Entry)
         """
         if not etype:
             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:
             # Check whether to use the expanded entry
             new_etype = etype + '-expanded'
@@ -170,7 +205,7 @@
             else:
                 obj = None
         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.
         return obj(section, etype, node)