1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-02 01:02:19 +02:00

binman: Support reading an image into an Image object

It is possible to read an Image, locate its FDT map and then read it into
the binman data structures. This allows full access to the entries that
were written to the image. Add support for this.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2019-07-08 14:25:46 -06:00
parent 2d26003df7
commit ffded7527a
4 changed files with 111 additions and 4 deletions

View File

@@ -162,6 +162,11 @@ class Entry(object):
self.orig_offset = self.offset self.orig_offset = self.offset
self.orig_size = self.size self.orig_size = self.size
# These should not be set in input files, but are set in an FDT map,
# which is also read by this code.
self.image_pos = fdt_util.GetInt(self._node, 'image-pos')
self.uncomp_size = fdt_util.GetInt(self._node, 'uncomp-size')
self.align = fdt_util.GetInt(self._node, 'align') self.align = fdt_util.GetInt(self._node, 'align')
if tools.NotPowerOfTwo(self.align): if tools.NotPowerOfTwo(self.align):
raise ValueError("Node '%s': Alignment %s must be a power of two" % raise ValueError("Node '%s': Alignment %s must be a power of two" %

View File

@@ -30,6 +30,7 @@ import fdt_util
import fmap_util import fmap_util
import test_util import test_util
import gzip import gzip
from image import Image
import state import state
import tools import tools
import tout import tout
@@ -2286,8 +2287,7 @@ class TestFunctional(unittest.TestCase):
def testFindImageHeader(self): def testFindImageHeader(self):
"""Test locating a image header""" """Test locating a image header"""
self._CheckLz4() self._CheckLz4()
data = self._DoReadFileDtb('128_decode_image.dts', use_real_dtb=True, data = self.data = self._DoReadFileRealDtb('128_decode_image.dts')
update_dtb=True)[0]
image = control.images['image'] image = control.images['image']
entries = image.GetEntries() entries = image.GetEntries()
entry = entries['fdtmap'] entry = entries['fdtmap']
@@ -2296,8 +2296,7 @@ class TestFunctional(unittest.TestCase):
def testFindImageHeaderStart(self): def testFindImageHeaderStart(self):
"""Test locating a image header located at the start of an image""" """Test locating a image header located at the start of an image"""
data = self._DoReadFileDtb('117_fdtmap_hdr_start.dts', data = self.data = self._DoReadFileRealDtb('117_fdtmap_hdr_start.dts')
use_real_dtb=True, update_dtb=True)[0]
image = control.images['image'] image = control.images['image']
entries = image.GetEntries() entries = image.GetEntries()
entry = entries['fdtmap'] entry = entries['fdtmap']
@@ -2309,6 +2308,38 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('005_simple.dts') data = self._DoReadFile('005_simple.dts')
self.assertEqual(None, image_header.LocateHeaderOffset(data)) self.assertEqual(None, image_header.LocateHeaderOffset(data))
def testReadImage(self):
"""Test reading an image and accessing its FDT map"""
self._CheckLz4()
data = self.data = self._DoReadFileRealDtb('128_decode_image.dts')
image_fname = tools.GetOutputFilename('image.bin')
orig_image = control.images['image']
image = Image.FromFile(image_fname)
self.assertEqual(orig_image.GetEntries().keys(),
image.GetEntries().keys())
orig_entry = orig_image.GetEntries()['fdtmap']
entry = image.GetEntries()['fdtmap']
self.assertEquals(orig_entry.offset, entry.offset)
self.assertEquals(orig_entry.size, entry.size)
self.assertEquals(orig_entry.image_pos, entry.image_pos)
def testReadImageNoHeader(self):
"""Test accessing an image's FDT map without an image header"""
self._CheckLz4()
data = self._DoReadFileRealDtb('129_decode_image_nohdr.dts')
image_fname = tools.GetOutputFilename('image.bin')
image = Image.FromFile(image_fname)
self.assertTrue(isinstance(image, Image))
self.assertEqual('image', image._name)
def testReadImageFail(self):
"""Test failing to read an image image's FDT map"""
self._DoReadFile('005_simple.dts')
image_fname = tools.GetOutputFilename('image.bin')
with self.assertRaises(ValueError) as e:
image = Image.FromFile(image_fname)
self.assertIn("Cannot find FDT map in image", str(e.exception))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@@ -12,6 +12,9 @@ from operator import attrgetter
import re import re
import sys import sys
from etype import fdtmap
from etype import image_header
import fdt
import fdt_util import fdt_util
import bsection import bsection
import tools import tools
@@ -47,6 +50,41 @@ class Image:
else: else:
self._ReadNode() self._ReadNode()
@classmethod
def FromFile(cls, fname):
"""Convert an image file into an Image for use in binman
Args:
fname: Filename of image file to read
Returns:
Image object on success
Raises:
ValueError if something goes wrong
"""
data = tools.ReadFile(fname)
size = len(data)
# First look for an image header
pos = image_header.LocateHeaderOffset(data)
if pos is None:
# Look for the FDT map
pos = fdtmap.LocateFdtmap(data)
if pos is None:
raise ValueError('Cannot find FDT map in image')
# We don't know the FDT size, so check its header first
probe_dtb = fdt.Fdt.FromData(
data[pos + fdtmap.FDTMAP_HDR_LEN:pos + 256])
dtb_size = probe_dtb.GetFdtObj().totalsize()
fdtmap_data = data[pos:pos + dtb_size + fdtmap.FDTMAP_HDR_LEN]
dtb = fdt.Fdt.FromData(fdtmap_data[fdtmap.FDTMAP_HDR_LEN:])
dtb.Scan()
# Return an Image with the associated nodes
return Image('image', dtb.GetRoot())
def _ReadNode(self): def _ReadNode(self):
"""Read properties from the image node""" """Read properties from the image node"""
self._size = fdt_util.GetInt(self._node, 'size') self._size = fdt_util.GetInt(self._node, 'size')

View File

@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0+
/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
binman {
size = <0xc00>;
u-boot {
};
section {
align = <0x100>;
cbfs {
size = <0x400>;
u-boot {
cbfs-type = "raw";
};
u-boot-dtb {
cbfs-type = "raw";
cbfs-compress = "lzma";
cbfs-offset = <0x80>;
};
};
u-boot-dtb {
compress = "lz4";
};
};
fdtmap {
};
};
};