binman: Add a new 'image-pos' property

At present each entry has an offset within its parent section. This is
useful for figuring out how entries relate to one another. However it
is sometimes necessary to locate an entry within an image, regardless
of which sections it is nested inside.

Add a new 'image-pos' property to provide this information. Also add
some documentation for the -u option binman provides, which updates the
device tree with final entry information.

Since the image position is a better symbol to use for the position of
U-Boot as obtained by SPL, update the SPL symbols to use this instead of
offset, which might be incorrect if hierarchical sections are used.

Signed-off-by: Simon Glass <sjg@chromium.org>
lime2-spi
Simon Glass 6 years ago
parent 8122f3967f
commit dbf6be9f7f
  1. 4
      common/spl/spl.c
  2. 2
      common/spl/spl_ram.c
  3. 2
      include/spl.h
  4. 22
      tools/binman/README
  5. 10
      tools/binman/bsection.py
  6. 1
      tools/binman/control.py
  7. 12
      tools/binman/entry.py
  8. 4
      tools/binman/etype/section.py
  9. 9
      tools/binman/ftest.py
  10. 3
      tools/binman/image.py
  11. BIN
      tools/binman/test/u_boot_binman_syms
  12. 2
      tools/binman/test/u_boot_binman_syms.c

@ -34,7 +34,7 @@ DECLARE_GLOBAL_DATA_PTR;
u32 *boot_params_ptr = NULL; u32 *boot_params_ptr = NULL;
/* See spl.h for information about this */ /* See spl.h for information about this */
binman_sym_declare(ulong, u_boot_any, offset); binman_sym_declare(ulong, u_boot_any, image_pos);
/* Define board data structure */ /* Define board data structure */
static bd_t bdata __attribute__ ((section(".data"))); static bd_t bdata __attribute__ ((section(".data")));
@ -129,7 +129,7 @@ __weak void spl_board_prepare_for_boot(void)
void spl_set_header_raw_uboot(struct spl_image_info *spl_image) void spl_set_header_raw_uboot(struct spl_image_info *spl_image)
{ {
ulong u_boot_pos = binman_sym(ulong, u_boot_any, offset); ulong u_boot_pos = binman_sym(ulong, u_boot_any, image_pos);
spl_image->size = CONFIG_SYS_MONITOR_LEN; spl_image->size = CONFIG_SYS_MONITOR_LEN;

@ -49,7 +49,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image,
load.read = spl_ram_load_read; load.read = spl_ram_load_read;
spl_load_simple_fit(spl_image, &load, 0, header); spl_load_simple_fit(spl_image, &load, 0, header);
} else { } else {
ulong u_boot_pos = binman_sym(ulong, u_boot_any, offset); ulong u_boot_pos = binman_sym(ulong, u_boot_any, image_pos);
debug("Legacy image\n"); debug("Legacy image\n");
/* /*

@ -60,7 +60,7 @@ struct spl_load_info {
* image is found. For * example if u-boot.img is used we don't check that * image is found. For * example if u-boot.img is used we don't check that
* spl_parse_image_header() can parse a valid header. * spl_parse_image_header() can parse a valid header.
*/ */
binman_sym_extern(ulong, u_boot_any, offset); binman_sym_extern(ulong, u_boot_any, image_pos);
/** /**
* spl_load_simple_fit() - Loads a fit image from a device. * spl_load_simple_fit() - Loads a fit image from a device.

@ -324,6 +324,12 @@ offset-unset:
property is present, binman will give an error if another entry does property is present, binman will give an error if another entry does
not set the offset (with the GetOffsets() method). not set the offset (with the GetOffsets() method).
image-pos:
This cannot be set on entry (or at least it is ignored if it is), but
with the -u option, binman will set it to the absolute image position
for each entry. This makes it easy to find out exactly where the entry
ended up in the image, regardless of parent sections, etc.
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.
@ -550,8 +556,8 @@ the 'warning' line in scripts/Makefile.lib to see what it has found:
# u_boot_dtsi_options_debug = $(u_boot_dtsi_options_raw) # u_boot_dtsi_options_debug = $(u_boot_dtsi_options_raw)
Access to binman entry offsets at run time Access to binman entry offsets at run time (symbols)
------------------------------------------ ----------------------------------------------------
Binman assembles images and determines where each entry is placed in the image. Binman assembles images and determines where each entry is placed in the image.
This information may be useful to U-Boot at run time. For example, in SPL it This information may be useful to U-Boot at run time. For example, in SPL it
@ -577,6 +583,18 @@ At present this feature is only supported in SPL. In principle it is possible
to fill in such symbols in U-Boot proper, as well. to fill in such symbols in U-Boot proper, as well.
Access to binman entry offsets at run time (fdt)
------------------------------------------------
Binman can update the U-Boot FDT to include the final position and size of
each entry in the images it processes. The option to enable this is -u and it
causes binman to make sure that the 'offset', 'image-pos' and 'size' properties
are set correctly for every entry. Since it is not necessary to specify these in
the image definition, binman calculates the final values and writes these to
the device tree. These can be used by U-Boot at run-time to find the location
of each entry.
Map files Map files
--------- ---------

@ -96,7 +96,7 @@ class Section(object):
def AddMissingProperties(self): def AddMissingProperties(self):
"""Add new properties to the device tree as needed for this entry""" """Add new properties to the device tree as needed for this entry"""
for prop in ['offset', 'size']: for prop in ['offset', 'size', 'image-pos']:
if not prop in self._node.props: if not prop in self._node.props:
self._node.AddZeroProp(prop) self._node.AddZeroProp(prop)
for entry in self._entries.values(): for entry in self._entries.values():
@ -105,6 +105,7 @@ class Section(object):
def SetCalculatedProperties(self): def SetCalculatedProperties(self):
self._node.SetInt('offset', self._offset) self._node.SetInt('offset', self._offset)
self._node.SetInt('size', self._size) self._node.SetInt('size', self._size)
self._node.SetInt('image-pos', self._image_pos)
for entry in self._entries.values(): for entry in self._entries.values():
entry.SetCalculatedProperties() entry.SetCalculatedProperties()
@ -260,6 +261,11 @@ class Section(object):
offset = entry.offset + entry.size offset = entry.offset + entry.size
prev_name = entry.GetPath() prev_name = entry.GetPath()
def SetImagePos(self, image_pos):
self._image_pos = image_pos
for entry in self._entries.values():
entry.SetImagePos(image_pos)
def ProcessEntryContents(self): def ProcessEntryContents(self):
"""Call the ProcessContents() method for each entry """Call the ProcessContents() method for each entry
@ -341,6 +347,8 @@ class Section(object):
raise ValueError(err) raise ValueError(err)
if prop_name == 'offset': if prop_name == 'offset':
return entry.offset return entry.offset
elif prop_name == 'image_pos':
return entry.image_pos
else: else:
raise ValueError("%s: No such property '%s'" % (msg, prop_name)) raise ValueError("%s: No such property '%s'" % (msg, prop_name))

@ -161,6 +161,7 @@ def Binman(options, args):
image.PackEntries() image.PackEntries()
image.CheckSize() image.CheckSize()
image.CheckEntries() image.CheckEntries()
image.SetImagePos()
if options.update_fdt: if options.update_fdt:
image.SetCalculatedProperties() image.SetCalculatedProperties()
image.ProcessEntryContents() image.ProcessEntryContents()

@ -64,6 +64,7 @@ class Entry(object):
self.pad_before = 0 self.pad_before = 0
self.pad_after = 0 self.pad_after = 0
self.offset_unset = False self.offset_unset = False
self.image_pos = None
if read_node: if read_node:
self.ReadNode() self.ReadNode()
@ -133,7 +134,7 @@ class Entry(object):
def AddMissingProperties(self): def AddMissingProperties(self):
"""Add new properties to the device tree as needed for this entry""" """Add new properties to the device tree as needed for this entry"""
for prop in ['offset', 'size']: for prop in ['offset', 'size', 'image-pos']:
if not prop in self._node.props: if not prop in self._node.props:
self._node.AddZeroProp(prop) self._node.AddZeroProp(prop)
@ -141,6 +142,7 @@ class Entry(object):
"""Set the value of device-tree properties calculated by binman""" """Set the value of device-tree properties calculated by binman"""
self._node.SetInt('offset', self.offset) self._node.SetInt('offset', self.offset)
self._node.SetInt('size', self.size) self._node.SetInt('size', self.size)
self._node.SetInt('image-pos', self.image_pos)
def ProcessFdt(self, fdt): def ProcessFdt(self, fdt):
return True return True
@ -265,6 +267,14 @@ class Entry(object):
self.offset = pos self.offset = pos
self.size = size self.size = size
def SetImagePos(self, image_pos):
"""Set the position in the image
Args:
image_pos: Position of this entry in the image
"""
self.image_pos = image_pos + self.offset
def ProcessContents(self): def ProcessContents(self):
pass pass

@ -46,6 +46,10 @@ class Entry_section(Entry):
self.size = self._section.GetSize() self.size = self._section.GetSize()
return super(Entry_section, self).Pack(offset) return super(Entry_section, self).Pack(offset)
def SetImagePos(self, image_pos):
Entry.SetImagePos(self, image_pos)
self._section.SetImagePos(image_pos + self.offset)
def WriteSymbols(self, section): def WriteSymbols(self, section):
"""Write symbol values into binary files for access at run time""" """Write symbol values into binary files for access at run time"""
self._section.WriteSymbols() self._section.WriteSymbols()

@ -1051,23 +1051,30 @@ class TestFunctional(unittest.TestCase):
"""Test that we can update the device tree with offset/size info""" """Test that we can update the device tree with offset/size info"""
_, _, _, out_dtb_fname = self._DoReadFileDtb('60_fdt_update.dts', _, _, _, out_dtb_fname = self._DoReadFileDtb('60_fdt_update.dts',
update_dtb=True) update_dtb=True)
props = self._GetPropTree(out_dtb_fname, ['offset', 'size']) props = self._GetPropTree(out_dtb_fname, ['offset', 'size',
'image-pos'])
with open('/tmp/x.dtb', 'wb') as outf: with open('/tmp/x.dtb', 'wb') as outf:
with open(out_dtb_fname) as inf: with open(out_dtb_fname) as inf:
outf.write(inf.read()) outf.write(inf.read())
self.assertEqual({ self.assertEqual({
'image-pos': 0,
'offset': 0, 'offset': 0,
'_testing:offset': 32, '_testing:offset': 32,
'_testing:size': 1, '_testing:size': 1,
'_testing:image-pos': 32,
'section@0/u-boot:offset': 0, 'section@0/u-boot:offset': 0,
'section@0/u-boot:size': len(U_BOOT_DATA), 'section@0/u-boot:size': len(U_BOOT_DATA),
'section@0/u-boot:image-pos': 0,
'section@0:offset': 0, 'section@0:offset': 0,
'section@0:size': 16, 'section@0:size': 16,
'section@0:image-pos': 0,
'section@1/u-boot:offset': 0, 'section@1/u-boot:offset': 0,
'section@1/u-boot:size': len(U_BOOT_DATA), 'section@1/u-boot:size': len(U_BOOT_DATA),
'section@1/u-boot:image-pos': 16,
'section@1:offset': 16, 'section@1:offset': 16,
'section@1:size': 16, 'section@1:size': 16,
'section@1:image-pos': 16,
'size': 40 'size': 40
}, props) }, props)

@ -96,6 +96,9 @@ class Image:
def SetCalculatedProperties(self): def SetCalculatedProperties(self):
self._section.SetCalculatedProperties() self._section.SetCalculatedProperties()
def SetImagePos(self):
self._section.SetImagePos(0)
def ProcessEntryContents(self): def ProcessEntryContents(self):
"""Call the ProcessContents() method for each entry """Call the ProcessContents() method for each entry

@ -10,4 +10,4 @@
binman_sym_declare(unsigned long, u_boot_spl, offset); binman_sym_declare(unsigned long, u_boot_spl, offset);
binman_sym_declare(unsigned long long, u_boot_spl2, offset); binman_sym_declare(unsigned long long, u_boot_spl2, offset);
binman_sym_declare(unsigned long, u_boot_any, offset); binman_sym_declare(unsigned long, u_boot_any, image_pos);

Loading…
Cancel
Save