blob: 4eb9f7e9b45a42605d64e81573ba651f724a4ee7 [file] [log] [blame]
Marti Bolivard1780aa2019-01-30 20:30:42 -07001# Copyright (c) 2018 Foundries.io
2#
3# SPDX-License-Identifier: Apache-2.0
4
5import abc
6import argparse
7import os
Marti Bolivar2f839da2019-06-12 11:25:23 -06008import pathlib
Martí Bolívar9c92baa2020-07-08 14:43:07 -07009import pickle
Martí Bolívar698db692021-02-02 12:20:47 -080010import platform
Marti Bolivar4a0f1f22019-02-14 14:49:03 -070011import shutil
Marti Bolivard1780aa2019-01-30 20:30:42 -070012import subprocess
Martí Bolívard8f459a2019-11-12 14:55:03 -080013import sys
Marti Bolivard1780aa2019-01-30 20:30:42 -070014
Marti Bolivard1780aa2019-01-30 20:30:42 -070015from west import log
Marti Bolivard1780aa2019-01-30 20:30:42 -070016from west.util import quote_sh_list
17
Martí Bolívard8f459a2019-11-12 14:55:03 -080018from build_helpers import find_build_dir, is_zephyr_build, \
Marti Bolivar3bd07a22019-06-12 11:48:50 -060019 FIND_BUILD_DIR_DESCRIPTION
Martí Bolívard8f459a2019-11-12 14:55:03 -080020from runners.core import BuildConfiguration
21from zcmake import CMakeCache
Dominik Ermel09980d62021-01-19 18:19:36 +000022from zephyr_ext_common import Forceable, ZEPHYR_SCRIPTS
Jun Li2d5fb6d2019-05-07 02:00:20 -070023
Martí Bolívar9c92baa2020-07-08 14:43:07 -070024# This is needed to load edt.pickle files.
Mikkel Jakobsen3fe785d2021-04-06 15:05:23 +020025sys.path.append(str(ZEPHYR_SCRIPTS / 'dts' / 'python-devicetree' / 'src'))
Martí Bolívar6dab1632020-02-10 16:53:06 -080026
Marti Bolivard1780aa2019-01-30 20:30:42 -070027SIGN_DESCRIPTION = '''\
28This command automates some of the drudgery of creating signed Zephyr
29binaries for chain-loading by a bootloader.
30
31In the simplest usage, run this from your build directory:
32
33 west sign -t your_tool -- ARGS_FOR_YOUR_TOOL
34
Andrei Emeltchenkofb441882020-07-07 11:57:51 +030035The "ARGS_FOR_YOUR_TOOL" value can be any additional
Marti Bolivard1780aa2019-01-30 20:30:42 -070036arguments you want to pass to the tool, such as the location of a
37signing key, a version identifier, etc.
38
39See tool-specific help below for details.'''
40
41SIGN_EPILOG = '''\
42imgtool
43-------
44
Andrei Emeltchenko51182ab2020-07-06 15:37:00 +030045To build a signed binary you can load with MCUboot using imgtool,
46run this from your build directory:
Marti Bolivard1780aa2019-01-30 20:30:42 -070047
48 west sign -t imgtool -- --key YOUR_SIGNING_KEY.pem
49
Marti Bolivar4a0f1f22019-02-14 14:49:03 -070050For this to work, either imgtool must be installed (e.g. using pip3),
51or you must pass the path to imgtool.py using the -p option.
52
Andrei Emeltchenkofb441882020-07-07 11:57:51 +030053Assuming your binary was properly built for processing and handling by
54imgtool, this creates zephyr.signed.bin and zephyr.signed.hex
55files which are ready for use by your bootloader.
56
Marti Bolivard1780aa2019-01-30 20:30:42 -070057The image header size, alignment, and slot sizes are determined from
Marti Bolivar4a0f1f22019-02-14 14:49:03 -070058the build directory using .config and the device tree. A default
59version number of 0.0.0+0 is used (which can be overridden by passing
60"--version x.y.z+w" after "--key"). As shown above, extra arguments
Andrei Emeltchenko51182ab2020-07-06 15:37:00 +030061after a '--' are passed to imgtool directly.
62
63rimage
64------
65
66To create a signed binary with the rimage tool, run this from your build
67directory:
68
69 west sign -t rimage -- -k YOUR_SIGNING_KEY.pem
70
71For this to work, either rimage must be installed or you must pass
72the path to rimage using the -p option.'''
Marti Bolivard1780aa2019-01-30 20:30:42 -070073
74
75class ToggleAction(argparse.Action):
76
77 def __call__(self, parser, args, ignored, option):
78 setattr(args, self.dest, not option.startswith('--no-'))
79
80
81class Sign(Forceable):
82 def __init__(self):
83 super(Sign, self).__init__(
84 'sign',
85 # Keep this in sync with the string in west-commands.yml.
86 'sign a Zephyr binary for bootloader chain-loading',
87 SIGN_DESCRIPTION,
88 accepts_unknown_args=False)
89
90 def do_add_parser(self, parser_adder):
91 parser = parser_adder.add_parser(
92 self.name,
93 epilog=SIGN_EPILOG,
94 help=self.help,
95 formatter_class=argparse.RawDescriptionHelpFormatter,
96 description=self.description)
97
Marti Bolivar3bd07a22019-06-12 11:48:50 -060098 parser.add_argument('-d', '--build-dir',
99 help=FIND_BUILD_DIR_DESCRIPTION)
Martí Bolívar9b673672020-08-19 15:29:37 -0700100 parser.add_argument('-q', '--quiet', action='store_true',
101 help='suppress non-error output')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700102 self.add_force_arg(parser)
103
104 # general options
105 group = parser.add_argument_group('tool control options')
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200106 group.add_argument('-t', '--tool', choices=['imgtool', 'rimage'],
107 required=True,
108 help='''image signing tool name; imgtool and rimage
109 are currently supported''')
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700110 group.add_argument('-p', '--tool-path', default=None,
Marti Bolivard1780aa2019-01-30 20:30:42 -0700111 help='''path to the tool itself, if needed''')
Anas Nashifb5531662021-01-25 13:57:20 -0500112 group.add_argument('-D', '--tool-data', default=None,
113 help='''path to tool data/configuration directory, if needed''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700114 group.add_argument('tool_args', nargs='*', metavar='tool_opt',
115 help='extra option(s) to pass to the signing tool')
116
117 # bin file options
118 group = parser.add_argument_group('binary (.bin) file options')
119 group.add_argument('--bin', '--no-bin', dest='gen_bin', nargs=0,
120 action=ToggleAction,
121 help='''produce a signed .bin file?
Marti Bolivard371c542019-06-12 11:39:09 -0600122 (default: yes, if supported and unsigned bin
123 exists)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700124 group.add_argument('-B', '--sbin', metavar='BIN',
Marti Bolivard1780aa2019-01-30 20:30:42 -0700125 help='''signed .bin file name
Marti Bolivar33cbba32019-06-12 10:29:01 -0600126 (default: zephyr.signed.bin in the build
127 directory, next to zephyr.bin)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700128
129 # hex file options
130 group = parser.add_argument_group('Intel HEX (.hex) file options')
131 group.add_argument('--hex', '--no-hex', dest='gen_hex', nargs=0,
132 action=ToggleAction,
133 help='''produce a signed .hex file?
Marti Bolivard371c542019-06-12 11:39:09 -0600134 (default: yes, if supported and unsigned hex
135 exists)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700136 group.add_argument('-H', '--shex', metavar='HEX',
Marti Bolivard1780aa2019-01-30 20:30:42 -0700137 help='''signed .hex file name
Marti Bolivar33cbba32019-06-12 10:29:01 -0600138 (default: zephyr.signed.hex in the build
139 directory, next to zephyr.hex)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700140
Marti Bolivard1780aa2019-01-30 20:30:42 -0700141 return parser
142
143 def do_run(self, args, ignored):
Marti Bolivarf13fa532019-02-14 10:01:00 -0700144 self.args = args # for check_force
Marti Bolivard371c542019-06-12 11:39:09 -0600145
146 # Find the build directory and parse .config and DT.
147 build_dir = find_build_dir(args.build_dir)
Marti Bolivar06c9f8e2019-06-12 11:49:02 -0600148 self.check_force(os.path.isdir(build_dir),
149 'no such build directory {}'.format(build_dir))
150 self.check_force(is_zephyr_build(build_dir),
Marti Bolivard1780aa2019-01-30 20:30:42 -0700151 "build directory {} doesn't look like a Zephyr build "
Marti Bolivar06c9f8e2019-06-12 11:49:02 -0600152 'directory'.format(build_dir))
Marti Bolivard371c542019-06-12 11:39:09 -0600153 bcfg = BuildConfiguration(build_dir)
Marti Bolivard1780aa2019-01-30 20:30:42 -0700154
Marti Bolivard371c542019-06-12 11:39:09 -0600155 # Decide on output formats.
156 formats = []
157 bin_exists = 'CONFIG_BUILD_OUTPUT_BIN' in bcfg
158 if args.gen_bin:
159 self.check_force(bin_exists,
160 '--bin given but CONFIG_BUILD_OUTPUT_BIN not set '
161 "in build directory's ({}) .config".
162 format(build_dir))
163 formats.append('bin')
164 elif args.gen_bin is None and bin_exists:
165 formats.append('bin')
166
167 hex_exists = 'CONFIG_BUILD_OUTPUT_HEX' in bcfg
168 if args.gen_hex:
169 self.check_force(hex_exists,
170
171 '--hex given but CONFIG_BUILD_OUTPUT_HEX not set '
172 "in build directory's ({}) .config".
173 format(build_dir))
174 formats.append('hex')
175 elif args.gen_hex is None and hex_exists:
176 formats.append('hex')
177
Marti Bolivard371c542019-06-12 11:39:09 -0600178 # Delegate to the signer.
Marti Bolivard1780aa2019-01-30 20:30:42 -0700179 if args.tool == 'imgtool':
180 signer = ImgtoolSigner()
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200181 elif args.tool == 'rimage':
182 signer = RimageSigner()
Marti Bolivard1780aa2019-01-30 20:30:42 -0700183 # (Add support for other signers here in elif blocks)
184 else:
185 raise RuntimeError("can't happen")
186
Marti Bolivard371c542019-06-12 11:39:09 -0600187 signer.sign(self, build_dir, bcfg, formats)
Marti Bolivard1780aa2019-01-30 20:30:42 -0700188
189
190class Signer(abc.ABC):
191 '''Common abstract superclass for signers.
192
193 To add support for a new tool, subclass this and add support for
194 it in the Sign.do_run() method.'''
195
196 @abc.abstractmethod
Marti Bolivard371c542019-06-12 11:39:09 -0600197 def sign(self, command, build_dir, bcfg, formats):
Marti Bolivard1780aa2019-01-30 20:30:42 -0700198 '''Abstract method to perform a signature; subclasses must implement.
199
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700200 :param command: the Sign instance
Marti Bolivar06c9f8e2019-06-12 11:49:02 -0600201 :param build_dir: the build directory
Marti Bolivard371c542019-06-12 11:39:09 -0600202 :param bcfg: BuildConfiguration for build directory
203 :param formats: list of formats to generate ('bin', 'hex')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700204 '''
205
206
207class ImgtoolSigner(Signer):
208
Marti Bolivard371c542019-06-12 11:39:09 -0600209 def sign(self, command, build_dir, bcfg, formats):
Martí Bolívard8f459a2019-11-12 14:55:03 -0800210 if not formats:
211 return
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700212
Martí Bolívard8f459a2019-11-12 14:55:03 -0800213 args = command.args
214 b = pathlib.Path(build_dir)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800215
Martí Bolívarb4903d42021-02-02 12:05:58 -0800216 imgtool = self.find_imgtool(command, args)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800217 # The vector table offset is set in Kconfig:
Stephanos Ioannidis33224892020-02-10 16:37:24 +0900218 vtoff = self.get_cfg(command, bcfg, 'CONFIG_ROM_START_OFFSET')
Martí Bolívard8f459a2019-11-12 14:55:03 -0800219 # Flash device write alignment and the partition's slot size
220 # come from devicetree:
Martí Bolívar9b673672020-08-19 15:29:37 -0700221 flash = self.edt_flash_node(b, args.quiet)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800222 align, addr, size = self.edt_flash_params(flash)
223
Dominik Ermel09980d62021-01-19 18:19:36 +0000224 if bcfg.get('CONFIG_BOOTLOADER_MCUBOOT', 'n') != 'y':
Martí Bolívar74929972020-08-07 15:40:05 -0700225 log.wrn("CONFIG_BOOTLOADER_MCUBOOT is not set to y in "
Dominik Ermel09980d62021-01-19 18:19:36 +0000226 f"{bcfg.path}; this probably won't work")
Martí Bolívar74929972020-08-07 15:40:05 -0700227
Dominik Ermel09980d62021-01-19 18:19:36 +0000228 kernel = bcfg.get('CONFIG_KERNEL_BIN_NAME', 'zephyr')
Martí Bolívar74929972020-08-07 15:40:05 -0700229
Martí Bolívard8f459a2019-11-12 14:55:03 -0800230 if 'bin' in formats:
Martí Bolívar74929972020-08-07 15:40:05 -0700231 in_bin = b / 'zephyr' / f'{kernel}.bin'
232 if not in_bin.is_file():
233 log.die(f"no unsigned .bin found at {in_bin}")
234 in_bin = os.fspath(in_bin)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800235 else:
236 in_bin = None
237 if 'hex' in formats:
Martí Bolívar74929972020-08-07 15:40:05 -0700238 in_hex = b / 'zephyr' / f'{kernel}.hex'
239 if not in_hex.is_file():
240 log.die(f"no unsigned .hex found at {in_hex}")
241 in_hex = os.fspath(in_hex)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800242 else:
243 in_hex = None
244
Martí Bolívar9b673672020-08-19 15:29:37 -0700245 if not args.quiet:
246 log.banner('image configuration:')
247 log.inf('partition offset: {0} (0x{0:x})'.format(addr))
248 log.inf('partition size: {0} (0x{0:x})'.format(size))
249 log.inf('rom start offset: {0} (0x{0:x})'.format(vtoff))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800250
251 # Base sign command.
252 #
253 # We provide a default --version in case the user is just
254 # messing around and doesn't want to set one. It will be
255 # overridden if there is a --version in args.tool_args.
Martí Bolívarb4903d42021-02-02 12:05:58 -0800256 sign_base = imgtool + ['sign',
257 '--version', '0.0.0+0',
258 '--align', str(align),
259 '--header-size', str(vtoff),
260 '--slot-size', str(size)]
Martí Bolívard8f459a2019-11-12 14:55:03 -0800261 sign_base.extend(args.tool_args)
262
Martí Bolívar9b673672020-08-19 15:29:37 -0700263 if not args.quiet:
264 log.banner('signing binaries')
Martí Bolívard8f459a2019-11-12 14:55:03 -0800265 if in_bin:
266 out_bin = args.sbin or str(b / 'zephyr' / 'zephyr.signed.bin')
267 sign_bin = sign_base + [in_bin, out_bin]
Martí Bolívar9b673672020-08-19 15:29:37 -0700268 if not args.quiet:
269 log.inf(f'unsigned bin: {in_bin}')
270 log.inf(f'signed bin: {out_bin}')
271 log.dbg(quote_sh_list(sign_bin))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800272 subprocess.check_call(sign_bin)
273 if in_hex:
274 out_hex = args.shex or str(b / 'zephyr' / 'zephyr.signed.hex')
275 sign_hex = sign_base + [in_hex, out_hex]
Martí Bolívar9b673672020-08-19 15:29:37 -0700276 if not args.quiet:
277 log.inf(f'unsigned hex: {in_hex}')
278 log.inf(f'signed hex: {out_hex}')
279 log.dbg(quote_sh_list(sign_hex))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800280 subprocess.check_call(sign_hex)
281
282 @staticmethod
283 def find_imgtool(command, args):
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700284 if args.tool_path:
Martí Bolívar698db692021-02-02 12:20:47 -0800285 imgtool = args.tool_path
286 if not os.path.isfile(imgtool):
287 log.die(f'--tool-path {imgtool}: no such file')
288 else:
289 imgtool = shutil.which('imgtool') or shutil.which('imgtool.py')
290 if not imgtool:
291 log.die('imgtool not found; either install it',
292 '(e.g. "pip3 install imgtool") or provide --tool-path')
Martí Bolívarb4903d42021-02-02 12:05:58 -0800293
Martí Bolívar698db692021-02-02 12:20:47 -0800294 if platform.system() == 'Windows' and imgtool.endswith('.py'):
295 # Windows users may not be able to run .py files
296 # as executables in subprocesses, regardless of
297 # what the mode says. Always run imgtool as
298 # 'python path/to/imgtool.py' instead of
299 # 'path/to/imgtool.py' in these cases.
300 # https://github.com/zephyrproject-rtos/zephyr/issues/31876
301 return [sys.executable, imgtool]
302
Martí Bolívarb4903d42021-02-02 12:05:58 -0800303 return [imgtool]
Marti Bolivar2f839da2019-06-12 11:25:23 -0600304
Ulf Magnussonbb634162019-09-04 16:28:50 +0200305 @staticmethod
306 def get_cfg(command, bcfg, item):
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700307 try:
Marti Bolivar2f839da2019-06-12 11:25:23 -0600308 return bcfg[item]
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700309 except KeyError:
310 command.check_force(
Martí Bolívard8f459a2019-11-12 14:55:03 -0800311 False, "build .config is missing a {} value".format(item))
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700312 return None
Martí Bolívard8f459a2019-11-12 14:55:03 -0800313
314 @staticmethod
Martí Bolívar9b673672020-08-19 15:29:37 -0700315 def edt_flash_node(b, quiet=False):
Martí Bolívard8f459a2019-11-12 14:55:03 -0800316 # Get the EDT Node corresponding to the zephyr,flash chosen DT
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700317 # node; 'b' is the build directory as a pathlib object.
Martí Bolívard8f459a2019-11-12 14:55:03 -0800318
319 # Ensure the build directory has a compiled DTS file
320 # where we expect it to be.
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700321 dts = b / 'zephyr' / 'zephyr.dts'
Martí Bolívar9b673672020-08-19 15:29:37 -0700322 if not quiet:
323 log.dbg('DTS file:', dts, level=log.VERBOSE_VERY)
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700324 edt_pickle = b / 'zephyr' / 'edt.pickle'
325 if not edt_pickle.is_file():
326 log.die("can't load devicetree; expected to find:", edt_pickle)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800327
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700328 # Load the devicetree.
329 with open(edt_pickle, 'rb') as f:
330 edt = pickle.load(f)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800331
332 # By convention, the zephyr,flash chosen node contains the
333 # partition information about the zephyr image to sign.
334 flash = edt.chosen_node('zephyr,flash')
335 if not flash:
336 log.die('devicetree has no chosen zephyr,flash node;',
337 "can't infer flash write block or image-0 slot sizes")
338
339 return flash
340
341 @staticmethod
342 def edt_flash_params(flash):
Fabio Utzig716ab472020-08-17 08:59:36 -0300343 # Get the flash device's write alignment and offset from the
344 # image-0 partition and the size from image-1 partition, out of the
345 # build directory's devicetree. image-1 partition size is used,
346 # when available, because in swap-move mode it can be one sector
347 # smaller. When not available, fallback to image-0 (single image dfu).
Martí Bolívard8f459a2019-11-12 14:55:03 -0800348
349 # The node must have a "partitions" child node, which in turn
Fabio Utzig716ab472020-08-17 08:59:36 -0300350 # must have child node labeled "image-0" and may have a child node
351 # named "image-1". By convention, the slots for consumption by
352 # imgtool are linked into these partitions.
Martí Bolívard8f459a2019-11-12 14:55:03 -0800353 if 'partitions' not in flash.children:
354 log.die("DT zephyr,flash chosen node has no partitions,",
Fabio Utzig716ab472020-08-17 08:59:36 -0300355 "can't find partitions for MCUboot slots")
Martí Bolívard8f459a2019-11-12 14:55:03 -0800356
Fabio Utzig716ab472020-08-17 08:59:36 -0300357 partitions = flash.children['partitions']
358 images = {
359 node.label: node for node in partitions.children.values()
360 if node.label in set(['image-0', 'image-1'])
361 }
362
363 if 'image-0' not in images:
364 log.die("DT zephyr,flash chosen node has no image-0 partition,",
365 "can't determine its address")
Martí Bolívard8f459a2019-11-12 14:55:03 -0800366
367 # Die on missing or zero alignment or slot_size.
368 if "write-block-size" not in flash.props:
369 log.die('DT zephyr,flash node has no write-block-size;',
370 "can't determine imgtool write alignment")
371 align = flash.props['write-block-size'].val
372 if align == 0:
373 log.die('expected nonzero flash alignment, but got '
374 'DT flash device write-block-size {}'.format(align))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800375
Fabio Utzig716ab472020-08-17 08:59:36 -0300376 # The partitions node, and its subnode, must provide
377 # the size of image-1 or image-0 partition via the regs property.
378 image_key = 'image-1' if 'image-1' in images else 'image-0'
379 if not images[image_key].regs:
380 log.die(f'{image_key} flash partition has no regs property;',
381 "can't determine size of image")
382
383 # always use addr of image-0, which is where images are run
384 addr = images['image-0'].regs[0].addr
385
386 size = images[image_key].regs[0].size
387 if size == 0:
388 log.die('expected nonzero slot size for {}'.format(image_key))
389
390 return (align, addr, size)
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200391
392class RimageSigner(Signer):
393
Anas Nashiff751dd42020-10-14 14:44:53 -0400394 @staticmethod
395 def edt_get_rimage_target(board):
Anas Nashif3ac163e2020-10-21 09:40:02 -0400396 if 'intel_adsp_cavs15' in board:
Anas Nashiff751dd42020-10-14 14:44:53 -0400397 return 'apl'
398 if 'intel_adsp_cavs18' in board:
399 return 'cnl'
400 if 'intel_adsp_cavs20' in board:
401 return 'icl'
402 if 'intel_adsp_cavs25' in board:
403 return 'tgl'
404
405 log.die('Signing not supported for board ' + board)
406
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200407 def sign(self, command, build_dir, bcfg, formats):
408 args = command.args
409
410 if args.tool_path:
411 command.check_force(shutil.which(args.tool_path),
412 '--tool-path {}: not an executable'.
413 format(args.tool_path))
414 tool_path = args.tool_path
415 else:
416 tool_path = shutil.which('rimage')
417 if not tool_path:
418 log.die('rimage not found; either install it',
419 'or provide --tool-path')
420
421 b = pathlib.Path(build_dir)
422 cache = CMakeCache.from_build_dir(build_dir)
423
424 board = cache['CACHED_BOARD']
Anas Nashiff751dd42020-10-14 14:44:53 -0400425 log.inf('Signing for board ' + board)
426 target = self.edt_get_rimage_target(board)
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100427 conf = target + '.toml'
428 log.inf('Signing for SOC target ' + target + ' using ' + conf)
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200429
Martí Bolívar9b673672020-08-19 15:29:37 -0700430 if not args.quiet:
431 log.inf('Signing with tool {}'.format(tool_path))
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200432
433 bootloader = str(b / 'zephyr' / 'bootloader.elf.mod')
434 kernel = str(b / 'zephyr' / 'zephyr.elf.mod')
435 out_bin = str(b / 'zephyr' / 'zephyr.ri')
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100436 out_xman = str(b / 'zephyr' / 'zephyr.ri.xman')
437 out_tmp = str(b / 'zephyr' / 'zephyr.rix')
Anas Nashiffee9af22021-01-25 13:59:57 -0500438 conf_path_cmd = []
439 if cache.get('RIMAGE_CONFIG_PATH') and not args.tool_data:
440 rimage_conf = pathlib.Path(cache['RIMAGE_CONFIG_PATH'])
441 conf_path = str(rimage_conf / conf)
442 conf_path_cmd = ['-c', conf_path]
443 elif args.tool_data:
444 conf_dir = pathlib.Path(args.tool_data)
445 conf_path = str(conf_dir / conf)
446 conf_path_cmd = ['-c', conf_path]
447 else:
448 log.die('Configuration not found')
Jian Kang8c9b06a2021-02-03 17:05:24 +0800449 if '--no-manifest' in args.tool_args:
450 no_manifest = True
451 args.tool_args.remove('--no-manifest')
452 else:
453 no_manifest = False
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200454
455 sign_base = ([tool_path] + args.tool_args +
Anas Nashiffee9af22021-01-25 13:59:57 -0500456 ['-o', out_bin] + conf_path_cmd + ['-i', '3', '-e'] +
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200457 [bootloader, kernel])
458
Martí Bolívar9b673672020-08-19 15:29:37 -0700459 if not args.quiet:
460 log.inf(quote_sh_list(sign_base))
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200461 subprocess.check_call(sign_base)
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100462
Jian Kang8c9b06a2021-02-03 17:05:24 +0800463 if no_manifest:
464 filenames = [out_bin]
465 else:
466 filenames = [out_xman, out_bin]
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100467 with open(out_tmp, 'wb') as outfile:
468 for fname in filenames:
469 with open(fname, 'rb') as infile:
470 outfile.write(infile.read())
471
472 os.remove(out_bin)
473 os.rename(out_tmp, out_bin)