mirror of
https://xff.cz/git/u-boot/
synced 2025-09-02 09:12:08 +02:00
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>
This commit is contained in:
@@ -10,6 +10,7 @@ from __future__ import print_function
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from entry import Entry
|
||||||
import fdt_util
|
import fdt_util
|
||||||
import re
|
import re
|
||||||
import state
|
import state
|
||||||
@@ -512,3 +513,11 @@ class Section(object):
|
|||||||
image size is dynamic and its sections have not yet been packed
|
image size is dynamic and its sections have not yet been packed
|
||||||
"""
|
"""
|
||||||
return self._image._size
|
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)
|
||||||
|
@@ -33,6 +33,10 @@ our_path = os.path.dirname(os.path.realpath(__file__))
|
|||||||
# device-tree properties.
|
# device-tree properties.
|
||||||
EntryArg = namedtuple('EntryArg', ['name', 'datatype'])
|
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):
|
class Entry(object):
|
||||||
"""An Entry in the section
|
"""An Entry in the section
|
||||||
@@ -617,3 +621,35 @@ features to produce new behaviours.
|
|||||||
if not self.HasSibling(name):
|
if not self.HasSibling(name):
|
||||||
return False
|
return False
|
||||||
return self.section.GetEntries()[name].image_pos
|
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)
|
||||||
|
@@ -195,7 +195,6 @@ class Entry_cbfs(Entry):
|
|||||||
entry._type)
|
entry._type)
|
||||||
if cfile:
|
if cfile:
|
||||||
entry._cbfs_file = cfile
|
entry._cbfs_file = cfile
|
||||||
entry.size = cfile.data_len
|
|
||||||
data = cbfs.get_data()
|
data = cbfs.get_data()
|
||||||
self.SetContents(data)
|
self.SetContents(data)
|
||||||
return True
|
return True
|
||||||
@@ -249,3 +248,9 @@ class Entry_cbfs(Entry):
|
|||||||
state.SetInt(entry._node, 'image-pos', entry.image_pos)
|
state.SetInt(entry._node, 'image-pos', entry.image_pos)
|
||||||
if entry.uncomp_size is not None:
|
if entry.uncomp_size is not None:
|
||||||
state.SetInt(entry._node, 'uncomp-size', entry.uncomp_size)
|
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)
|
||||||
|
@@ -111,3 +111,7 @@ class Entry_section(Entry):
|
|||||||
def ExpandToLimit(self, limit):
|
def ExpandToLimit(self, limit):
|
||||||
super(Entry_section, self).ExpandToLimit(limit)
|
super(Entry_section, self).ExpandToLimit(limit)
|
||||||
self._section.ExpandSize(self.size)
|
self._section.ExpandSize(self.size)
|
||||||
|
|
||||||
|
def ListEntries(self, entries, indent):
|
||||||
|
"""List the files in the section"""
|
||||||
|
self._section.ListEntries(entries, indent)
|
||||||
|
@@ -2191,6 +2191,82 @@ class TestFunctional(unittest.TestCase):
|
|||||||
self._DoReadFile('126_cbfs_bad_type.dts')
|
self._DoReadFile('126_cbfs_bad_type.dts')
|
||||||
self.assertIn("Unknown cbfs-type 'badtype'", str(e.exception))
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
@@ -162,3 +162,13 @@ class Image:
|
|||||||
file=fd)
|
file=fd)
|
||||||
self._section.WriteMap(fd, 0)
|
self._section.WriteMap(fd, 0)
|
||||||
return fname
|
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
|
||||||
|
33
tools/binman/test/127_list.dts
Normal file
33
tools/binman/test/127_list.dts
Normal file
@@ -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";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
Reference in New Issue
Block a user