summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2019-07-08 14:25:46 -0600
committerSimon Glass <sjg@chromium.org>2019-07-24 12:54:08 -0700
commitffded7527ad5272249ae728a88585373182cc7f4 (patch)
tree04140bde0535c6d018dff213975ff032cf0b15df
parent2d26003df79839d7f6b5e30eaa49e191dc9e6c87 (diff)
downloadu-boot-ffded7527ad5272249ae728a88585373182cc7f4.tar.gz
u-boot-ffded7527ad5272249ae728a88585373182cc7f4.tar.bz2
u-boot-ffded7527ad5272249ae728a88585373182cc7f4.zip
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>
-rw-r--r--tools/binman/entry.py5
-rw-r--r--tools/binman/ftest.py39
-rw-r--r--tools/binman/image.py38
-rw-r--r--tools/binman/test/129_decode_image_nohdr.dts33
4 files changed, 111 insertions, 4 deletions
diff --git a/tools/binman/entry.py b/tools/binman/entry.py
index ee63d18353..6c74f2a217 100644
--- a/tools/binman/entry.py
+++ b/tools/binman/entry.py
@@ -162,6 +162,11 @@ class Entry(object):
self.orig_offset = self.offset
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')
if tools.NotPowerOfTwo(self.align):
raise ValueError("Node '%s': Alignment %s must be a power of two" %
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index ce66e3a2f2..f3a8e64ad1 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -30,6 +30,7 @@ import fdt_util
import fmap_util
import test_util
import gzip
+from image import Image
import state
import tools
import tout
@@ -2286,8 +2287,7 @@ class TestFunctional(unittest.TestCase):
def testFindImageHeader(self):
"""Test locating a image header"""
self._CheckLz4()
- data = self._DoReadFileDtb('128_decode_image.dts', use_real_dtb=True,
- update_dtb=True)[0]
+ data = self.data = self._DoReadFileRealDtb('128_decode_image.dts')
image = control.images['image']
entries = image.GetEntries()
entry = entries['fdtmap']
@@ -2296,8 +2296,7 @@ class TestFunctional(unittest.TestCase):
def testFindImageHeaderStart(self):
"""Test locating a image header located at the start of an image"""
- data = self._DoReadFileDtb('117_fdtmap_hdr_start.dts',
- use_real_dtb=True, update_dtb=True)[0]
+ data = self.data = self._DoReadFileRealDtb('117_fdtmap_hdr_start.dts')
image = control.images['image']
entries = image.GetEntries()
entry = entries['fdtmap']
@@ -2309,6 +2308,38 @@ class TestFunctional(unittest.TestCase):
data = self._DoReadFile('005_simple.dts')
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__":
unittest.main()
diff --git a/tools/binman/image.py b/tools/binman/image.py
index 6f4bd5d37b..f890350a8d 100644
--- a/tools/binman/image.py
+++ b/tools/binman/image.py
@@ -12,6 +12,9 @@ from operator import attrgetter
import re
import sys
+from etype import fdtmap
+from etype import image_header
+import fdt
import fdt_util
import bsection
import tools
@@ -47,6 +50,41 @@ class Image:
else:
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):
"""Read properties from the image node"""
self._size = fdt_util.GetInt(self._node, 'size')
diff --git a/tools/binman/test/129_decode_image_nohdr.dts b/tools/binman/test/129_decode_image_nohdr.dts
new file mode 100644
index 0000000000..90fdd8820c
--- /dev/null
+++ b/tools/binman/test/129_decode_image_nohdr.dts
@@ -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 {
+ };
+ };
+};