1#!/usr/bin/env python3 2# 3# SPDX-License-Identifier: BSD-3-Clause 4 5import os 6import struct 7import sys 8 9PROG_NAME = os.path.basename(sys.argv[0]) 10 11def 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 42def 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 65def 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 78def 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 101if __name__ == "__main__": 102 main() 103