[U-Boot] [PATCH 26/26] binman: Support listing an image

Simon Glass sjg at chromium.org
Tue Jul 2 00:24:55 UTC 2019


Add support for listing the entries in an image. This relies on the image
having an FDT map.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 tools/binman/README     | 25 +++++++++++++-
 tools/binman/control.py | 73 +++++++++++++++++++++++++++++++++++++++++
 tools/binman/ftest.py   | 31 +++++++++++++++++
 3 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/tools/binman/README b/tools/binman/README
index 7e745a2d466..2f3ded58c91 100644
--- a/tools/binman/README
+++ b/tools/binman/README
@@ -490,6 +490,30 @@ see README.entries. This is generated from the source code using:
 	binman entry-docs >tools/binman/README.entries
 
 
+Listing images
+--------------
+
+It is possible to list the entries in an existing firmware image created by
+binman. For example:
+
+    $ binman list image.bin
+    Name              Image-pos  Size  Entry-type    Offset  Uncomp-size
+    ----------------------------------------------------------------------
+    main-section                  c00  section            0
+      u-boot                  0     4  u-boot             0
+      section                     5ff  section            4
+        cbfs                100   400  cbfs               0
+          u-boot            138     4  u-boot            38
+          u-boot-dtb        180   108  u-boot-dtb        80          3b5
+        u-boot-dtb          500   1ff  u-boot-dtb       400          3b5
+      fdtmap                6ff   381  fdtmap           6ff
+      image-header          bf8     8  image-header     bf8
+
+This shows the hierarchy of the image, the position, size and type of each
+entry, the offset of each entry within its parent and the uncompressed size if
+the entry is compressed.
+
+    
 Hashing Entries
 ---------------
 
@@ -825,7 +849,6 @@ Some ideas:
 - Add an option to decode an image into the constituent binaries
 - Support building an image for a board (-b) more completely, with a
   configurable build directory
-- Support listing files in images
 - Support logging of binman's operations, with different levels of verbosity
 
 --
diff --git a/tools/binman/control.py b/tools/binman/control.py
index d48e7ac0070..3ac3f0c3e71 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -67,6 +67,75 @@ def WriteEntryDocs(modules, test_missing=None):
     from entry import Entry
     Entry.WriteDocs(modules, test_missing)
 
+def EntryToStrings(entry):
+    """Convert an entry to a list of strings, one for each column
+
+    Args:
+        entry: EntryInfo object containing information to output
+
+    Returns:
+        List of strings, one for each field in entry
+    """
+    def _AppendHex(val):
+        """Append a hex value, or an empty string if val is None
+
+        Args:
+            val: Integer value, or None if none
+        """
+        args.append('' if val is None else '>%x' % val)
+
+    args = ['  ' * entry.indent + entry.name]
+    _AppendHex(entry.image_pos)
+    _AppendHex(entry.size)
+    args.append(entry.etype)
+    _AppendHex(entry.offset)
+    _AppendHex(entry.uncomp_size)
+    return args
+
+def ListEntries(fname):
+    """List the entries in an image
+
+    This decodes the supplied image and displays a table of entries from that
+    image, preceded by a header.
+
+    Args:
+        fname: Filename to process
+    """
+    def _DoLine(line):
+        out = []
+        for i, item in enumerate(line):
+            lengths[i] = max(lengths[i], len(item))
+            out.append(item)
+        return out
+
+    image = Image.FromFile(fname)
+
+    # Check for error
+    if isinstance(image, str):
+        print("Unable to read image '%s' (%s)" % (fname, image))
+        return
+    entries = image.ListEntries()
+
+    num_columns = 6
+    lines = []
+    lengths = [0] * num_columns
+    lines.append(_DoLine(['Name', 'Image-pos', 'Size', 'Entry-type',
+                          'Offset', 'Uncomp-size']))
+    for entry in entries:
+        lines.append(_DoLine(EntryToStrings(entry)))
+    for linenum, line in enumerate(lines):
+        if linenum == 1:
+            print('-' * (sum(lengths) + num_columns * 2))
+        out = ''
+        for i, item in enumerate(line):
+            width = -lengths[i]
+            if item.startswith('>'):
+                width = -width
+                item = item[1:]
+            txt = '%*s  ' % (width, item)
+            out += txt
+        print(out.rstrip())
+
 def Binman(args):
     """The main control code for binman
 
@@ -87,6 +156,10 @@ def Binman(args):
         command.Run(pager, fname)
         return 0
 
+    if args.cmd == 'list':
+        ListEntries(args.fname)
+        return 0
+
     # Try to figure out which device tree contains our image description
     if args.dt:
         dtb_fname = args.dt
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 88c3d847f82..f5353911705 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -2336,5 +2336,36 @@ class TestFunctional(unittest.TestCase):
         self.assertTrue(isinstance(image, str))
         self.assertEqual('Cannot find FDT map in image', image)
 
+    def testListCmd(self):
+        """Test listing the files in an image using an Fdtmap"""
+        data = self._DoReadFileDtb('129_list_fdtmap.dts', use_real_dtb=True,
+                                   update_dtb=True)[0]
+        image_fname = tools.GetOutputFilename('image.bin')
+        with test_util.capture_sys_output() as (stdout, stderr):
+            self._DoBinman('list', image_fname)
+        lines = stdout.getvalue().splitlines()
+        expected = [
+            'Name              Image-pos  Size  Entry-type    Offset  Uncomp-size',
+'----------------------------------------------------------------------',
+'main-section                  c00  section            0',
+'  u-boot                  0     4  u-boot             0',
+'  section                     5ff  section            4',
+'    cbfs                100   400  cbfs               0',
+'      u-boot            138     4  u-boot            38',
+'      u-boot-dtb        180   108  u-boot-dtb        80          3b5',
+'    u-boot-dtb          500   1ff  u-boot-dtb       400          3b5',
+'  fdtmap                6ff   381  fdtmap           6ff',
+'  image-header          bf8     8  image-header     bf8',
+            ]
+        self.assertEqual(expected, lines)
+
+    def testListCmdFail(self):
+        """Test failing to list an image"""
+        self._DoReadFile('005_simple.dts')
+        image_fname = tools.GetOutputFilename('image.bin')
+        with test_util.capture_sys_output() as (stdout, stderr):
+            self._DoBinman('list', image_fname)
+
+
 if __name__ == "__main__":
     unittest.main()
-- 
2.22.0.410.gd8fdbe21b5-goog



More information about the U-Boot mailing list