binman: Allow listing the entries in an image
It is useful to be able to summarise all the entries in an image, e.g. to
display this to this user. Add a new ListEntries() method to Entry, and
set up a way to call it through the Image class.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/binman/bsection.py b/tools/binman/bsection.py
index 9047e55..082f424 100644
--- a/tools/binman/bsection.py
+++ b/tools/binman/bsection.py
@@ -10,6 +10,7 @@
from collections import OrderedDict
import sys
+from entry import Entry
import fdt_util
import re
import state
@@ -512,3 +513,11 @@
image size is dynamic and its sections have not yet been packed
"""
return self._image._size
+
+ def ListEntries(self, entries, indent):
+ """Override this method to list all files in the section"""
+ Entry.AddEntryInfo(entries, indent, self._name, 'section', self._size,
+ self._image_pos, None, self._offset,
+ self._parent_section)
+ for entry in self._entries.values():
+ entry.ListEntries(entries, indent + 1)
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index e38cb71..ee63d18 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -33,6 +33,10 @@
# device-tree properties.
EntryArg = namedtuple('EntryArg', ['name', 'datatype'])
+# Information about an entry for use when displaying summaries
+EntryInfo = namedtuple('EntryInfo', ['indent', 'name', 'etype', 'size',
+ 'image_pos', 'uncomp_size', 'offset',
+ 'entry'])
class Entry(object):
"""An Entry in the section
@@ -617,3 +621,35 @@
if not self.HasSibling(name):
return False
return self.section.GetEntries()[name].image_pos
+
+ @staticmethod
+ def AddEntryInfo(entries, indent, name, etype, size, image_pos,
+ uncomp_size, offset, entry):
+ """Add a new entry to the entries list
+
+ Args:
+ entries: List (of EntryInfo objects) to add to
+ indent: Current indent level to add to list
+ name: Entry name (string)
+ etype: Entry type (string)
+ size: Entry size in bytes (int)
+ image_pos: Position within image in bytes (int)
+ uncomp_size: Uncompressed size if the entry uses compression, else
+ None
+ offset: Entry offset within parent in bytes (int)
+ entry: Entry object
+ """
+ entries.append(EntryInfo(indent, name, etype, size, image_pos,
+ uncomp_size, offset, entry))
+
+ def ListEntries(self, entries, indent):
+ """Add files in this entry to the list of entries
+
+ This can be overridden by subclasses which need different behaviour.
+
+ Args:
+ entries: List (of EntryInfo objects) to add to
+ indent: Current indent level to add to list
+ """
+ self.AddEntryInfo(entries, indent, self.name, self.etype, self.size,
+ self.image_pos, self.uncomp_size, self.offset, self)
diff --git a/tools/binman/etype/cbfs.py b/tools/binman/etype/cbfs.py
index 175ecae..953d6f4 100644
--- a/tools/binman/etype/cbfs.py
+++ b/tools/binman/etype/cbfs.py
@@ -195,7 +195,6 @@
entry._type)
if cfile:
entry._cbfs_file = cfile
- entry.size = cfile.data_len
data = cbfs.get_data()
self.SetContents(data)
return True
@@ -249,3 +248,9 @@
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 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)
diff --git a/tools/binman/etype/section.py b/tools/binman/etype/section.py
index 23bf221..178e893 100644
--- a/tools/binman/etype/section.py
+++ b/tools/binman/etype/section.py
@@ -111,3 +111,7 @@
def ExpandToLimit(self, limit):
super(Entry_section, self).ExpandToLimit(limit)
self._section.ExpandSize(self.size)
+
+ def ListEntries(self, entries, indent):
+ """List the files in the section"""
+ self._section.ListEntries(entries, indent)
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 21bea6c..de459b2 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -2191,6 +2191,82 @@
self._DoReadFile('126_cbfs_bad_type.dts')
self.assertIn("Unknown cbfs-type 'badtype'", str(e.exception))
+ def testList(self):
+ """Test listing the files in an image"""
+ self._CheckLz4()
+ data = self._DoReadFile('127_list.dts')
+ image = control.images['image']
+ entries = image.BuildEntryList()
+ self.assertEqual(7, len(entries))
+
+ ent = entries[0]
+ self.assertEqual(0, ent.indent)
+ self.assertEqual('main-section', ent.name)
+ self.assertEqual('section', ent.etype)
+ self.assertEqual(len(data), ent.size)
+ self.assertEqual(0, ent.image_pos)
+ self.assertEqual(None, ent.uncomp_size)
+ self.assertEqual(None, ent.offset)
+
+ ent = entries[1]
+ self.assertEqual(1, ent.indent)
+ self.assertEqual('u-boot', ent.name)
+ self.assertEqual('u-boot', ent.etype)
+ self.assertEqual(len(U_BOOT_DATA), ent.size)
+ self.assertEqual(0, ent.image_pos)
+ self.assertEqual(None, ent.uncomp_size)
+ self.assertEqual(0, ent.offset)
+
+ ent = entries[2]
+ self.assertEqual(1, ent.indent)
+ self.assertEqual('section', ent.name)
+ self.assertEqual('section', ent.etype)
+ section_size = ent.size
+ self.assertEqual(0x100, ent.image_pos)
+ self.assertEqual(None, ent.uncomp_size)
+ self.assertEqual(len(U_BOOT_DATA), ent.offset)
+
+ ent = entries[3]
+ self.assertEqual(2, ent.indent)
+ self.assertEqual('cbfs', ent.name)
+ self.assertEqual('cbfs', ent.etype)
+ self.assertEqual(0x400, ent.size)
+ self.assertEqual(0x100, ent.image_pos)
+ self.assertEqual(None, ent.uncomp_size)
+ self.assertEqual(0, ent.offset)
+
+ ent = entries[4]
+ self.assertEqual(3, ent.indent)
+ self.assertEqual('u-boot', ent.name)
+ self.assertEqual('u-boot', ent.etype)
+ self.assertEqual(len(U_BOOT_DATA), ent.size)
+ self.assertEqual(0x138, ent.image_pos)
+ self.assertEqual(None, ent.uncomp_size)
+ self.assertEqual(0x38, ent.offset)
+
+ ent = entries[5]
+ self.assertEqual(3, ent.indent)
+ self.assertEqual('u-boot-dtb', ent.name)
+ self.assertEqual('text', ent.etype)
+ self.assertGreater(len(COMPRESS_DATA), ent.size)
+ self.assertEqual(0x178, ent.image_pos)
+ self.assertEqual(len(COMPRESS_DATA), ent.uncomp_size)
+ self.assertEqual(0x78, ent.offset)
+
+ ent = entries[6]
+ self.assertEqual(2, ent.indent)
+ self.assertEqual('u-boot-dtb', ent.name)
+ self.assertEqual('u-boot-dtb', ent.etype)
+ self.assertEqual(0x500, ent.image_pos)
+ self.assertEqual(len(U_BOOT_DTB_DATA), ent.uncomp_size)
+ dtb_size = ent.size
+ # Compressing this data expands it since headers are added
+ self.assertGreater(dtb_size, len(U_BOOT_DTB_DATA))
+ self.assertEqual(0x400, ent.offset)
+
+ self.assertEqual(len(data), 0x100 + section_size)
+ self.assertEqual(section_size, 0x400 + dtb_size)
+
if __name__ == "__main__":
unittest.main()
diff --git a/tools/binman/image.py b/tools/binman/image.py
index 6339d02..6f4bd5d 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -162,3 +162,13 @@
file=fd)
self._section.WriteMap(fd, 0)
return fname
+
+ def BuildEntryList(self):
+ """List the files in an image
+
+ Returns:
+ List of entry.EntryInfo objects describing all entries in the image
+ """
+ entries = []
+ self._section.ListEntries(entries, 0)
+ return entries
diff --git a/tools/binman/test/127_list.dts b/tools/binman/test/127_list.dts
new file mode 100644
index 0000000..c1d6fce
--- /dev/null
+++ b/tools/binman/test/127_list.dts
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ u-boot {
+ };
+ section {
+ align = <0x100>;
+ cbfs {
+ size = <0x400>;
+ u-boot {
+ cbfs-type = "raw";
+ cbfs-offset = <0x38>;
+ };
+ u-boot-dtb {
+ type = "text";
+ text = "compress xxxxxxxxxxxxxxxxxxxxxx data";
+ cbfs-type = "raw";
+ cbfs-compress = "lzma";
+ cbfs-offset = <0x78>;
+ };
+ };
+ u-boot-dtb {
+ compress = "lz4";
+ };
+ };
+ };
+};