summaryrefslogtreecommitdiff
path: root/cxmanage_api/image.py
diff options
context:
space:
mode:
Diffstat (limited to 'cxmanage_api/image.py')
-rw-r--r--cxmanage_api/image.py178
1 files changed, 178 insertions, 0 deletions
diff --git a/cxmanage_api/image.py b/cxmanage_api/image.py
new file mode 100644
index 0000000..23642c4
--- /dev/null
+++ b/cxmanage_api/image.py
@@ -0,0 +1,178 @@
+# Copyright (c) 2012, Calxeda Inc.
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of Calxeda Inc. nor the names of its contributors
+# may be used to endorse or promote products derived from this software
+# without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+# DAMAGE.
+
+
+import os
+import subprocess
+
+from cxmanage_api import temp_file
+from cxmanage_api.simg import create_simg, has_simg
+from cxmanage_api.simg import valid_simg, get_simg_contents
+from cxmanage_api.cx_exceptions import InvalidImageError
+
+
+class Image:
+ """An Image consists of: an image type, a filename, and SIMG header info.
+
+ >>> from cxmanage_api.image import Image
+ >>> img = Image(filename='spi_highbank.bin', image_type='PACAKGE')
+
+ :param filename: Path to the image.
+ :type filename: string
+ :param image_type: Type of image. [CDB, BOOT_LOG, SOC_ELF]
+ :type image_type: string
+ :param simg: Path to the simg file.
+ :type simg: string
+ :param daddr: The daddr field in the SIMG Header.
+ :type daddr: integer
+ :param skip_crc32: Flag to skip (or not) CRC32 checking.
+ :type skip_crc32: boolean
+ :param version: Image version.
+ :type version: string
+
+ :raises ValueError: If the image file does not exist.
+ :raises InvalidImageError: If the file is NOT a valid image.
+
+ """
+
+ def __init__(self, filename, image_type, simg=None, daddr=None,
+ skip_crc32=False, version=None):
+ """Default constructor for the Image class."""
+ self.filename = filename
+ self.type = image_type
+ self.daddr = daddr
+ self.skip_crc32 = skip_crc32
+ self.version = version
+
+ if (not os.path.exists(filename)):
+ raise ValueError("File %s does not exist" % filename)
+
+ if (simg == None):
+ contents = open(filename).read()
+ self.simg = has_simg(contents)
+ else:
+ self.simg = simg
+
+ if (not self.verify()):
+ raise InvalidImageError("%s is not a valid %s image" %
+ (filename, image_type))
+
+ def render_to_simg(self, priority, daddr):
+ """Creates a SIMG file.
+
+ >>> img.render_to_simg(priority=1, daddr=0)
+ >>> 'spi_highbank.bin'
+
+ :param priority: SIMG header priority value.
+ :type priority: integer
+ :param daddr: SIMG daddr field value.
+ :type daddr: integer
+
+ :returns: The file name of the image.
+ :rtype: string
+
+ :raises InvalidImageError: If the SIMG image is not valid.
+
+ """
+ filename = self.filename
+ # Create new image if necessary
+ if (not self.simg):
+ contents = open(filename).read()
+ # Figure out daddr
+ if (self.daddr != None):
+ daddr = self.daddr
+ # Create simg
+ align = (self.type in ["CDB", "BOOT_LOG"])
+ simg = create_simg(contents, priority=priority, daddr=daddr,
+ skip_crc32=self.skip_crc32, align=align,
+ version=self.version)
+ filename = temp_file()
+ with open(filename, "w") as f:
+ f.write(simg)
+
+ # Make sure the simg was built correctly
+ if (not valid_simg(open(filename).read())):
+ raise InvalidImageError("%s is not a valid SIMG" %
+ os.path.basename(self.filename))
+
+ return filename
+
+ def size(self):
+ """Return the full size of this image (as an SIMG)
+
+ >>> img.size()
+ 2174976
+
+ :returns: The size of the image file in bytes.
+ :rtype: integer
+
+ """
+ if (self.simg):
+ return os.path.getsize(self.filename)
+ else:
+ contents = open(self.filename).read()
+ align = (self.type in ["CDB", "BOOT_LOG"])
+ simg = create_simg(contents, skip_crc32=True, align=align)
+ return len(simg)
+
+ def verify(self):
+ """Returns true if the image is valid, false otherwise.
+
+ >>> img.verify()
+ True
+
+ :returns: Whether or not the image file is valid.
+ :rtype: boolean
+
+ """
+ if (self.type == "SOC_ELF"):
+ try:
+ file_process = subprocess.Popen(["file", self.filename],
+ stdout=subprocess.PIPE)
+ file_type = file_process.communicate()[0].split()[1]
+
+ if (file_type != "ELF"):
+ return False
+ except OSError:
+ # "file" tool wasn't found, just continue without it
+ # typically located: /usr/bin/file
+ pass
+
+ if (self.type in ["CDB", "BOOT_LOG"]):
+ # Look for "CDBH"
+ contents = open(self.filename).read()
+ if (self.simg):
+ contents = get_simg_contents(contents)
+ if (contents[:4] != "CDBH"):
+ return False
+ return True
+
+
+# End of file: ./image.py