mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-08 10:39:08 +00:00
binman: Support expanding entries
It is useful to have entries which can grow automatically to fill available space. Add support for this. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
0a98b28b06
commit
ba64a0bbb7
8 changed files with 136 additions and 2 deletions
|
@ -330,6 +330,10 @@ image-pos:
|
||||||
for each entry. This makes it easy to find out exactly where the entry
|
for each entry. This makes it easy to find out exactly where the entry
|
||||||
ended up in the image, regardless of parent sections, etc.
|
ended up in the image, regardless of parent sections, etc.
|
||||||
|
|
||||||
|
expand-size:
|
||||||
|
Expand the size of this entry to fit available space. This space is only
|
||||||
|
limited by the size of the image/section and the position of the next
|
||||||
|
entry.
|
||||||
|
|
||||||
The attributes supported for images are described below. Several are similar
|
The attributes supported for images are described below. Several are similar
|
||||||
to those for entries.
|
to those for entries.
|
||||||
|
|
|
@ -253,10 +253,26 @@ class Section(object):
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
self._entries[entry._node.name] = entry
|
self._entries[entry._node.name] = entry
|
||||||
|
|
||||||
|
def _ExpandEntries(self):
|
||||||
|
"""Expand any entries that are permitted to"""
|
||||||
|
exp_entry = None
|
||||||
|
for entry in self._entries.values():
|
||||||
|
if exp_entry:
|
||||||
|
exp_entry.ExpandToLimit(entry.offset)
|
||||||
|
exp_entry = None
|
||||||
|
if entry.expand_size:
|
||||||
|
exp_entry = entry
|
||||||
|
if exp_entry:
|
||||||
|
exp_entry.ExpandToLimit(self._size)
|
||||||
|
|
||||||
def CheckEntries(self):
|
def CheckEntries(self):
|
||||||
"""Check that entries do not overlap or extend outside the section"""
|
"""Check that entries do not overlap or extend outside the section
|
||||||
|
|
||||||
|
This also sorts entries, if needed and expands
|
||||||
|
"""
|
||||||
if self._sort:
|
if self._sort:
|
||||||
self._SortEntries()
|
self._SortEntries()
|
||||||
|
self._ExpandEntries()
|
||||||
offset = 0
|
offset = 0
|
||||||
prev_name = 'None'
|
prev_name = 'None'
|
||||||
for entry in self._entries.values():
|
for entry in self._entries.values():
|
||||||
|
@ -419,3 +435,7 @@ class Section(object):
|
||||||
return None
|
return None
|
||||||
return entry.data
|
return entry.data
|
||||||
source_entry.Raise("Cannot find entry for node '%s'" % node.name)
|
source_entry.Raise("Cannot find entry for node '%s'" % node.name)
|
||||||
|
|
||||||
|
def ExpandSize(self, size):
|
||||||
|
if size != self._size:
|
||||||
|
self._size = size
|
||||||
|
|
|
@ -76,6 +76,7 @@ class Entry(object):
|
||||||
self.pad_after = 0
|
self.pad_after = 0
|
||||||
self.offset_unset = False
|
self.offset_unset = False
|
||||||
self.image_pos = None
|
self.image_pos = None
|
||||||
|
self._expand_size = False
|
||||||
if read_node:
|
if read_node:
|
||||||
self.ReadNode()
|
self.ReadNode()
|
||||||
|
|
||||||
|
@ -161,6 +162,7 @@ class Entry(object):
|
||||||
"of two" % (self._node.path, self.align_size))
|
"of two" % (self._node.path, self.align_size))
|
||||||
self.align_end = fdt_util.GetInt(self._node, 'align-end')
|
self.align_end = fdt_util.GetInt(self._node, 'align-end')
|
||||||
self.offset_unset = fdt_util.GetBool(self._node, 'offset-unset')
|
self.offset_unset = fdt_util.GetBool(self._node, 'offset-unset')
|
||||||
|
self.expand_size = fdt_util.GetBool(self._node, 'expand-size')
|
||||||
|
|
||||||
def GetDefaultFilename(self):
|
def GetDefaultFilename(self):
|
||||||
return None
|
return None
|
||||||
|
@ -507,3 +509,12 @@ features to produce new behaviours.
|
||||||
break
|
break
|
||||||
name = '%s.%s' % (node.name, name)
|
name = '%s.%s' % (node.name, name)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
def ExpandToLimit(self, limit):
|
||||||
|
"""Expand an entry so that it ends at the given offset limit"""
|
||||||
|
if self.offset + self.size < limit:
|
||||||
|
self.size = limit - self.offset
|
||||||
|
# Request the contents again, since changing the size requires that
|
||||||
|
# the data grows. This should not fail, but check it to be sure.
|
||||||
|
if not self.ObtainContents():
|
||||||
|
self.Raise('Cannot obtain contents when expanding entry')
|
||||||
|
|
|
@ -48,6 +48,8 @@ class Entry__testing(Entry):
|
||||||
'return-unknown-contents')
|
'return-unknown-contents')
|
||||||
self.bad_update_contents = fdt_util.GetBool(self._node,
|
self.bad_update_contents = fdt_util.GetBool(self._node,
|
||||||
'bad-update-contents')
|
'bad-update-contents')
|
||||||
|
self.return_contents_once = fdt_util.GetBool(self._node,
|
||||||
|
'return-contents-once')
|
||||||
|
|
||||||
# Set to True when the entry is ready to process the FDT.
|
# Set to True when the entry is ready to process the FDT.
|
||||||
self.process_fdt_ready = False
|
self.process_fdt_ready = False
|
||||||
|
@ -68,12 +70,15 @@ class Entry__testing(Entry):
|
||||||
EntryArg('test-existing-prop', str)], self.require_args)
|
EntryArg('test-existing-prop', str)], self.require_args)
|
||||||
if self.force_bad_datatype:
|
if self.force_bad_datatype:
|
||||||
self.GetEntryArgsOrProps([EntryArg('test-bad-datatype-arg', bool)])
|
self.GetEntryArgsOrProps([EntryArg('test-bad-datatype-arg', bool)])
|
||||||
|
self.return_contents = True
|
||||||
|
|
||||||
def ObtainContents(self):
|
def ObtainContents(self):
|
||||||
if self.return_unknown_contents:
|
if self.return_unknown_contents or not self.return_contents:
|
||||||
return False
|
return False
|
||||||
self.data = 'a'
|
self.data = 'a'
|
||||||
self.contents_size = len(self.data)
|
self.contents_size = len(self.data)
|
||||||
|
if self.return_contents_once:
|
||||||
|
self.return_contents = False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def GetOffsets(self):
|
def GetOffsets(self):
|
||||||
|
|
|
@ -40,6 +40,10 @@ class Entry_section(Entry):
|
||||||
def ProcessFdt(self, fdt):
|
def ProcessFdt(self, fdt):
|
||||||
return self._section.ProcessFdt(fdt)
|
return self._section.ProcessFdt(fdt)
|
||||||
|
|
||||||
|
def ExpandEntries(self):
|
||||||
|
Entry.ExpandEntries(self)
|
||||||
|
self._section.ExpandEntries()
|
||||||
|
|
||||||
def AddMissingProperties(self):
|
def AddMissingProperties(self):
|
||||||
Entry.AddMissingProperties(self)
|
Entry.AddMissingProperties(self)
|
||||||
self._section.AddMissingProperties()
|
self._section.AddMissingProperties()
|
||||||
|
@ -95,3 +99,7 @@ class Entry_section(Entry):
|
||||||
|
|
||||||
def GetEntries(self):
|
def GetEntries(self):
|
||||||
return self._section.GetEntries()
|
return self._section.GetEntries()
|
||||||
|
|
||||||
|
def ExpandToLimit(self, limit):
|
||||||
|
super(Entry_section, self).ExpandToLimit(limit)
|
||||||
|
self._section.ExpandSize(self.size)
|
||||||
|
|
|
@ -1579,6 +1579,35 @@ class TestFunctional(unittest.TestCase):
|
||||||
self.assertIn("Node '/binman/files': Missing 'pattern' property",
|
self.assertIn("Node '/binman/files': Missing 'pattern' property",
|
||||||
str(e.exception))
|
str(e.exception))
|
||||||
|
|
||||||
|
def testExpandSize(self):
|
||||||
|
"""Test an expanding entry"""
|
||||||
|
data, _, map_data, _ = self._DoReadFileDtb('88_expand_size.dts',
|
||||||
|
map=True)
|
||||||
|
expect = ('a' * 8 + U_BOOT_DATA +
|
||||||
|
MRC_DATA + 'b' * 1 + U_BOOT_DATA +
|
||||||
|
'c' * 8 + U_BOOT_DATA +
|
||||||
|
'd' * 8)
|
||||||
|
self.assertEqual(expect, data)
|
||||||
|
self.assertEqual('''ImagePos Offset Size Name
|
||||||
|
00000000 00000000 00000028 main-section
|
||||||
|
00000000 00000000 00000008 fill
|
||||||
|
00000008 00000008 00000004 u-boot
|
||||||
|
0000000c 0000000c 00000004 section
|
||||||
|
0000000c 00000000 00000003 intel-mrc
|
||||||
|
00000010 00000010 00000004 u-boot2
|
||||||
|
00000014 00000014 0000000c section2
|
||||||
|
00000014 00000000 00000008 fill
|
||||||
|
0000001c 00000008 00000004 u-boot
|
||||||
|
00000020 00000020 00000008 fill2
|
||||||
|
''', map_data)
|
||||||
|
|
||||||
|
def testExpandSizeBad(self):
|
||||||
|
"""Test an expanding entry which fails to provide contents"""
|
||||||
|
with self.assertRaises(ValueError) as e:
|
||||||
|
self._DoReadFileDtb('89_expand_size_bad.dts', map=True)
|
||||||
|
self.assertIn("Node '/binman/_testing': Cannot obtain contents when "
|
||||||
|
'expanding entry', str(e.exception))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
43
tools/binman/test/88_expand_size.dts
Normal file
43
tools/binman/test/88_expand_size.dts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
binman {
|
||||||
|
size = <40>;
|
||||||
|
fill {
|
||||||
|
expand-size;
|
||||||
|
fill-byte = [61];
|
||||||
|
size = <0>;
|
||||||
|
};
|
||||||
|
u-boot {
|
||||||
|
offset = <8>;
|
||||||
|
};
|
||||||
|
section {
|
||||||
|
expand-size;
|
||||||
|
pad-byte = <0x62>;
|
||||||
|
intel-mrc {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
u-boot2 {
|
||||||
|
type = "u-boot";
|
||||||
|
offset = <16>;
|
||||||
|
};
|
||||||
|
section2 {
|
||||||
|
type = "section";
|
||||||
|
fill {
|
||||||
|
expand-size;
|
||||||
|
fill-byte = [63];
|
||||||
|
size = <0>;
|
||||||
|
};
|
||||||
|
u-boot {
|
||||||
|
offset = <8>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
fill2 {
|
||||||
|
type = "fill";
|
||||||
|
expand-size;
|
||||||
|
fill-byte = [64];
|
||||||
|
size = <0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
14
tools/binman/test/89_expand_size_bad.dts
Normal file
14
tools/binman/test/89_expand_size_bad.dts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/dts-v1/;
|
||||||
|
|
||||||
|
/ {
|
||||||
|
binman {
|
||||||
|
_testing {
|
||||||
|
expand-size;
|
||||||
|
return-contents-once;
|
||||||
|
};
|
||||||
|
u-boot {
|
||||||
|
offset = <8>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
Loading…
Add table
Add a link
Reference in a new issue