From 41b8ba090ced0bb54733dc3dd32e945e7e332801 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 8 Jul 2019 14:25:43 -0600 Subject: [PATCH] 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 --- tools/binman/bsection.py | 9 ++++ tools/binman/entry.py | 36 ++++++++++++++++ tools/binman/etype/cbfs.py | 7 +++- tools/binman/etype/section.py | 4 ++ tools/binman/ftest.py | 76 ++++++++++++++++++++++++++++++++++ tools/binman/image.py | 10 +++++ tools/binman/test/127_list.dts | 33 +++++++++++++++ 7 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 tools/binman/test/127_list.dts diff --git a/tools/binman/bsection.py b/tools/binman/bsection.py index 9047e55a34..082f424241 100644 --- a/tools/binman/bsection.py +++ b/tools/binman/bsection.py @@ -10,6 +10,7 @@ from __future__ import print_function from collections import OrderedDict import sys +from entry import Entry import fdt_util import re import state @@ -512,3 +513,11 @@ class Section(object): 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 e38cb71c59..ee63d18353 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -33,6 +33,10 @@ our_path = os.path.dirname(os.path.realpath(__file__)) # 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 @@ features to produce new behaviours. 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 175ecae158..953d6f4868 100644 --- a/tools/binman/etype/cbfs.py +++ b/tools/binman/etype/cbfs.py @@ -195,7 +195,6 @@ class Entry_cbfs(Entry): 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 @@ class Entry_cbfs(Entry): 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 23bf22113d..178e89352e 100644 --- a/tools/binman/etype/section.py +++ b/tools/binman/etype/section.py @@ -111,3 +111,7 @@ class Entry_section(Entry): 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 21bea6c9d1..de459b2b3b 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -2191,6 +2191,82 @@ class TestFunctional(unittest.TestCase): 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 6339d020e7..6f4bd5d37b 100644 --- a/tools/binman/image.py +++ b/tools/binman/image.py @@ -162,3 +162,13 @@ class Image: 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 0000000000..c1d6fce3f9 --- /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"; + }; + }; + }; +}; -- 2.39.5