/ util / qualcomm / ipqheader.py
ipqheader.py
  1  #!/usr/bin/env python3
  2  #
  3  # SPDX-License-Identifier: BSD-3-Clause
  4  
  5  import os
  6  import struct
  7  import sys
  8  
  9  PROG_NAME = os.path.basename(sys.argv[0])
 10  
 11  def create_header(base, size):
 12      """Returns a packed MBN header image with the specified base and size.
 13  
 14      @arg base: integer, specifies the image load address in RAM
 15      @arg size: integer, specifies the size of the image
 16      @returns: string, the MBN header
 17      """
 18  
 19      # SBLs require size to be 4 bytes aligned.
 20      size = (size + 3) & 0xfffffffc
 21  
 22      # We currently do not support appending certificates. Signing GPL
 23      # code might violate the GPL. So U-Boot will never be signed. So
 24      # this is not required for U-Boot.
 25  
 26      header = [
 27          0x5,         # Type: APPSBL
 28          0x3,         # Version: 3
 29          0x0,         # Image source pointer
 30          base,        # Image destination pointer
 31          size,        # Code Size + Cert Size + Signature Size
 32          size,        # Code Size
 33          base + size, # Destination + Code Size
 34          0x0,         # Signature Size
 35          base + size, # Destination + Code Size + Signature Size
 36          0x0,         # Cert Size
 37      ]
 38  
 39      header_packed = struct.pack('<10I', *header)
 40      return header_packed
 41  
 42  def mkheader(base_addr, infname, outfname):
 43      """Prepends the image with the MBN header.
 44  
 45      @arg base_addr: integer, specifies the image load address in RAM
 46      @arg infname: string, image filename
 47      @arg outfname: string, output image with header prepended
 48      @raises IOError: if reading/writing input/output file fails
 49      """
 50      with open(infname, "rb") as infp:
 51          image = infp.read()
 52          insize = len(image)
 53  
 54      if base_addr > 0xFFFFFFFF:
 55          raise ValueError("invalid base address")
 56  
 57      if base_addr + insize > 0xFFFFFFFF:
 58          raise ValueError("invalid destination range")
 59  
 60      header = create_header(base_addr, insize)
 61      with open(outfname, "wb") as outfp:
 62          outfp.write(header)
 63          outfp.write(image)
 64  
 65  def usage(msg=None):
 66      """Print command usage.
 67  
 68      @arg msg: string, error message if any (default: None)
 69      """
 70      if msg != None:
 71          sys.stderr.write("%s: %s\n" % (PROG_NAME, msg))
 72  
 73      print("Usage: %s <base-addr> <input-file> <output-file>" % PROG_NAME)
 74  
 75      if msg != None:
 76          exit(1)
 77  
 78  def main():
 79      """Main entry function"""
 80  
 81      if len(sys.argv) != 4:
 82          usage("incorrect number of arguments")
 83  
 84      try:
 85          base_addr = int(sys.argv[1], 0)
 86          infname = sys.argv[2]
 87          outfname = sys.argv[3]
 88      except ValueError as e:
 89          sys.stderr.write("mkheader: invalid base address '%s'\n" % sys.argv[1])
 90          exit(1)
 91  
 92      try:
 93          mkheader(base_addr, infname, outfname)
 94      except IOError as e:
 95          sys.stderr.write("%s: %s\n" % (PROG_NAME, e))
 96          exit(1)
 97      except ValueError as e:
 98          sys.stderr.write("%s: %s\n" % (PROG_NAME, e))
 99          exit(1)
100  
101  if __name__ == "__main__":
102      main()