blob: 5a754246994409aba17dd29553d3e2524268cad2 [file] [log] [blame]
Tamas Banf70ef8c2017-12-19 15:35:09 +00001#! /usr/bin/env python3
2#
3# Copyright 2017 Linaro Limited
Sverteczky, Marcell4b78a4b2019-06-03 14:17:10 +02004# Copyright (c) 2017-2019, Arm Limited.
Tamas Banf70ef8c2017-12-19 15:35:09 +00005#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18"""
19Assemble multiple images into a single image that can be flashed on the device.
20"""
21
22import argparse
23import errno
24import io
25import re
Tamas Ban581034a2017-12-19 19:54:37 +000026import os
27import shutil
Sverteczky, Marcell7d069e82019-07-04 18:17:33 +020028import macro_parser
Tamas Banf70ef8c2017-12-19 15:35:09 +000029
Sverteczky, Marcell7d069e82019-07-04 18:17:33 +020030offset_re = re.compile(r"^\s*RE_([0-9A-Z_]+)_IMAGE_OFFSET\s*=\s*(.*)")
31size_re = re.compile(r"^\s*RE_([0-9A-Z_]+)_IMAGE_MAX_SIZE\s*=\s*(.*)")
Tamas Banf70ef8c2017-12-19 15:35:09 +000032
33class Assembly():
Mate Toth-Pal48fc6a02018-01-24 09:50:14 +010034 def __init__(self, layout_path, output):
35 self.output = output
36 self.layout_path = layout_path
Tamas Ban581034a2017-12-19 19:54:37 +000037 self.find_slots()
Tamas Banf70ef8c2017-12-19 15:35:09 +000038 try:
39 os.unlink(output)
40 except OSError as e:
41 if e.errno != errno.ENOENT:
42 raise
Tamas Banf70ef8c2017-12-19 15:35:09 +000043
Tamas Ban581034a2017-12-19 19:54:37 +000044 def find_slots(self):
Tamas Banf70ef8c2017-12-19 15:35:09 +000045 offsets = {}
46 sizes = {}
Tamas Ban581034a2017-12-19 19:54:37 +000047
Sverteczky, Marcell7d069e82019-07-04 18:17:33 +020048 offsets = macro_parser.evaluate_macro(self.layout_path, offset_re, 1, 2)
49 sizes = macro_parser.evaluate_macro(self.layout_path, size_re, 1, 2)
Tamas Banf70ef8c2017-12-19 15:35:09 +000050
Tamas Ban581034a2017-12-19 19:54:37 +000051 if 'SECURE' not in offsets:
52 raise Exception("Image config does not have secure partition")
Tamas Banf70ef8c2017-12-19 15:35:09 +000053
Tamas Ban581034a2017-12-19 19:54:37 +000054 if 'NON_SECURE' not in offsets:
55 raise Exception("Image config does not have non-secure partition")
Tamas Banf70ef8c2017-12-19 15:35:09 +000056
57 self.offsets = offsets
58 self.sizes = sizes
59
60 def add_image(self, source, partition):
61 with open(self.output, 'ab') as ofd:
Gabor Kertesz33e9b232018-09-12 15:38:41 +020062 ofd.seek(0, os.SEEK_END)
Tamas Banf70ef8c2017-12-19 15:35:09 +000063 pos = ofd.tell()
Tamas Banf70ef8c2017-12-19 15:35:09 +000064 if pos > self.offsets[partition]:
65 raise Exception("Partitions not in order, unsupported")
66 if pos < self.offsets[partition]:
Tamas Ban581034a2017-12-19 19:54:37 +000067 ofd.write(b'\xFF' * (self.offsets[partition] - pos))
68 statinfo = os.stat(source)
69 if statinfo.st_size > self.sizes[partition]:
70 raise Exception("Image {} is too large for partition".format(source))
Tamas Banf70ef8c2017-12-19 15:35:09 +000071 with open(source, 'rb') as rfd:
Tamas Ban581034a2017-12-19 19:54:37 +000072 shutil.copyfileobj(rfd, ofd, 0x10000)
Tamas Banf70ef8c2017-12-19 15:35:09 +000073
74def main():
75 parser = argparse.ArgumentParser()
76
Mate Toth-Pal48fc6a02018-01-24 09:50:14 +010077 parser.add_argument('-l', '--layout', required=True,
Sverteczky, Marcell7d069e82019-07-04 18:17:33 +020078 help='Location of the file that contains preprocessed macros')
Tamas Ban581034a2017-12-19 19:54:37 +000079 parser.add_argument('-s', '--secure', required=True,
80 help='Unsigned secure image')
81 parser.add_argument('-n', '--non_secure',
82 help='Unsigned non-secure image')
Tamas Banf70ef8c2017-12-19 15:35:09 +000083 parser.add_argument('-o', '--output', required=True,
84 help='Filename to write full image to')
85
86 args = parser.parse_args()
Mate Toth-Pal48fc6a02018-01-24 09:50:14 +010087 output = Assembly(args.layout, args.output)
Tamas Banf70ef8c2017-12-19 15:35:09 +000088
Tamas Ban581034a2017-12-19 19:54:37 +000089 output.add_image(args.secure, "SECURE")
90 output.add_image(args.non_secure, "NON_SECURE")
Tamas Banf70ef8c2017-12-19 15:35:09 +000091
92if __name__ == '__main__':
93 main()