Boot: Set load address in image header

When a #define macro, IMAGE_LOAD_ADDRESS, is present in the platform's
flash_layout.h file, write the corresponding address to the image header
and set a flag to indicate it should be used to copy the image from
flash to SRAM at the address

Signed-off-by: Oliver Swede <oli.swede@arm.com>
Change-Id: I5911bbc94b7d15e72689dccccf6992bb17fb280b
diff --git a/bl2/ext/mcuboot/scripts/imgtool.py b/bl2/ext/mcuboot/scripts/imgtool.py
index 4c5b451..4b62d3b 100644
--- a/bl2/ext/mcuboot/scripts/imgtool.py
+++ b/bl2/ext/mcuboot/scripts/imgtool.py
@@ -16,12 +16,30 @@
 # limitations under the License.
 
 import os
+import re
 import argparse
 from imgtool import keys
 from imgtool import image
 from imgtool import version
 import sys
 
+def find_load_address(args):
+    load_address_re = re.compile(r"^#define\sIMAGE_LOAD_ADDRESS\s+(0x[0-9a-fA-F]+)")
+    scriptsDir = os.path.dirname(os.path.abspath(__file__))
+    configFile = os.path.join(scriptsDir, args.layout)
+    ramLoadAddress = None
+    with open(configFile, 'r') as flash_layout_file:
+        for line in flash_layout_file:
+            m = load_address_re.match(line)
+            if m is not None:
+                ramLoadAddress = int(m.group(1), 0)
+                print("**[INFO]** Writing load address from the macro in "
+                      "flash_layout.h to the image header.. "
+                       + hex(ramLoadAddress)
+                       + " (dec. " + str(ramLoadAddress) + ")")
+                break
+    return ramLoadAddress
+
 # Returns the last version number if present, or None if not
 def get_last_version(path):
     if (os.path.isfile(path) == False): # Version file not present
@@ -86,7 +104,7 @@
             included_header=args.included_header,
             pad=args.pad)
     key = keys.load(args.key) if args.key else None
-    img.sign(key)
+    img.sign(key, find_load_address(args))
 
     if args.pad:
         img.pad_to(args.pad, args.align)
@@ -125,6 +143,8 @@
     getpub.add_argument('-l', '--lang', metavar='lang', default='c')
 
     sign = subs.add_parser('sign', help='Sign an image with a private key')
+    sign.add_argument('--layout', required=True,
+                      help='Location of the memory layout file')
     sign.add_argument('-k', '--key', metavar='filename')
     sign.add_argument("--align", type=alignment_value, required=True)
     sign.add_argument("-v", "--version", type=version.decode_version,
diff --git a/bl2/ext/mcuboot/scripts/imgtool/image.py b/bl2/ext/mcuboot/scripts/imgtool/image.py
index 58f7088..b3915e0 100644
--- a/bl2/ext/mcuboot/scripts/imgtool/image.py
+++ b/bl2/ext/mcuboot/scripts/imgtool/image.py
@@ -1,4 +1,5 @@
 # Copyright 2017 Linaro Limited
+# Copyright (c) 2018, Arm Limited.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -26,8 +27,8 @@
 # Image header flags.
 IMAGE_F = {
         'PIC':                   0x0000001,
-        'NON_BOOTABLE':          0x0000010, }
-
+        'NON_BOOTABLE':          0x0000010,
+        'RAM_LOAD':              0x0000020, }
 TLV_VALUES = {
         'KEYHASH': 0x01,
         'SHA256' : 0x10,
@@ -102,8 +103,8 @@
             if any(v != 0 for v in self.payload[0:self.header_size]):
                 raise Exception("Padding requested, but image does not start with zeros")
 
-    def sign(self, key):
-        self.add_header(key)
+    def sign(self, key, ramLoadAddress):
+        self.add_header(key, ramLoadAddress)
 
         tlv = TLV()
 
@@ -125,13 +126,17 @@
 
         self.payload += tlv.get()
 
-    def add_header(self, key):
+    def add_header(self, key, ramLoadAddress):
         """Install the image header.
 
         The key is needed to know the type of signature, and
         approximate the size of the signature."""
 
         flags = 0
+        if ramLoadAddress is not None:
+            # add the load address flag to the header to indicate that an SRAM
+            # load address macro has been defined
+            flags |= IMAGE_F["RAM_LOAD"]
 
         fmt = ('<' +
             # type ImageHdr struct {
@@ -147,7 +152,7 @@
         assert struct.calcsize(fmt) == IMAGE_HEADER_SIZE
         header = struct.pack(fmt,
                 IMAGE_MAGIC,
-                0, # LoadAddr
+                0 if (ramLoadAddress is None) else ramLoadAddress, # LoadAddr
                 self.header_size,
                 0, # Pad1
                 len(self.payload) - self.header_size, # ImageSz