blob: 8a0fd7de01d5ab05e6d4e4863ad8f78429f545b9 [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
Martí Bolívar74929972020-08-07 15:40:05 -070022from zephyr_ext_common import Forceable, load_dot_config, \
Torsten Rasmussene819fa42020-03-10 14:52:35 +010023 ZEPHYR_SCRIPTS
Jun Li2d5fb6d2019-05-07 02:00:20 -070024
Martí Bolívar9c92baa2020-07-08 14:43:07 -070025# This is needed to load edt.pickle files.
Torsten Rasmussene819fa42020-03-10 14:52:35 +010026sys.path.append(str(ZEPHYR_SCRIPTS / 'dts'))
Martí Bolívar6dab1632020-02-10 16:53:06 -080027
Marti Bolivard1780aa2019-01-30 20:30:42 -070028SIGN_DESCRIPTION = '''\
29This command automates some of the drudgery of creating signed Zephyr
30binaries for chain-loading by a bootloader.
31
32In the simplest usage, run this from your build directory:
33
34 west sign -t your_tool -- ARGS_FOR_YOUR_TOOL
35
Andrei Emeltchenkofb441882020-07-07 11:57:51 +030036The "ARGS_FOR_YOUR_TOOL" value can be any additional
Marti Bolivard1780aa2019-01-30 20:30:42 -070037arguments you want to pass to the tool, such as the location of a
38signing key, a version identifier, etc.
39
40See tool-specific help below for details.'''
41
42SIGN_EPILOG = '''\
43imgtool
44-------
45
Andrei Emeltchenko51182ab2020-07-06 15:37:00 +030046To build a signed binary you can load with MCUboot using imgtool,
47run this from your build directory:
Marti Bolivard1780aa2019-01-30 20:30:42 -070048
49 west sign -t imgtool -- --key YOUR_SIGNING_KEY.pem
50
Marti Bolivar4a0f1f22019-02-14 14:49:03 -070051For this to work, either imgtool must be installed (e.g. using pip3),
52or you must pass the path to imgtool.py using the -p option.
53
Andrei Emeltchenkofb441882020-07-07 11:57:51 +030054Assuming your binary was properly built for processing and handling by
55imgtool, this creates zephyr.signed.bin and zephyr.signed.hex
56files which are ready for use by your bootloader.
57
Marti Bolivard1780aa2019-01-30 20:30:42 -070058The image header size, alignment, and slot sizes are determined from
Marti Bolivar4a0f1f22019-02-14 14:49:03 -070059the build directory using .config and the device tree. A default
60version number of 0.0.0+0 is used (which can be overridden by passing
61"--version x.y.z+w" after "--key"). As shown above, extra arguments
Andrei Emeltchenko51182ab2020-07-06 15:37:00 +030062after a '--' are passed to imgtool directly.
63
64rimage
65------
66
67To create a signed binary with the rimage tool, run this from your build
68directory:
69
70 west sign -t rimage -- -k YOUR_SIGNING_KEY.pem
71
72For this to work, either rimage must be installed or you must pass
73the path to rimage using the -p option.'''
Marti Bolivard1780aa2019-01-30 20:30:42 -070074
75
76class ToggleAction(argparse.Action):
77
78 def __call__(self, parser, args, ignored, option):
79 setattr(args, self.dest, not option.startswith('--no-'))
80
81
82class Sign(Forceable):
83 def __init__(self):
84 super(Sign, self).__init__(
85 'sign',
86 # Keep this in sync with the string in west-commands.yml.
87 'sign a Zephyr binary for bootloader chain-loading',
88 SIGN_DESCRIPTION,
89 accepts_unknown_args=False)
90
91 def do_add_parser(self, parser_adder):
92 parser = parser_adder.add_parser(
93 self.name,
94 epilog=SIGN_EPILOG,
95 help=self.help,
96 formatter_class=argparse.RawDescriptionHelpFormatter,
97 description=self.description)
98
Marti Bolivar3bd07a22019-06-12 11:48:50 -060099 parser.add_argument('-d', '--build-dir',
100 help=FIND_BUILD_DIR_DESCRIPTION)
Martí Bolívar9b673672020-08-19 15:29:37 -0700101 parser.add_argument('-q', '--quiet', action='store_true',
102 help='suppress non-error output')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700103 self.add_force_arg(parser)
104
105 # general options
106 group = parser.add_argument_group('tool control options')
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200107 group.add_argument('-t', '--tool', choices=['imgtool', 'rimage'],
108 required=True,
109 help='''image signing tool name; imgtool and rimage
110 are currently supported''')
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700111 group.add_argument('-p', '--tool-path', default=None,
Marti Bolivard1780aa2019-01-30 20:30:42 -0700112 help='''path to the tool itself, if needed''')
Anas Nashifb5531662021-01-25 13:57:20 -0500113 group.add_argument('-D', '--tool-data', default=None,
114 help='''path to tool data/configuration directory, if needed''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700115 group.add_argument('tool_args', nargs='*', metavar='tool_opt',
116 help='extra option(s) to pass to the signing tool')
117
118 # bin file options
119 group = parser.add_argument_group('binary (.bin) file options')
120 group.add_argument('--bin', '--no-bin', dest='gen_bin', nargs=0,
121 action=ToggleAction,
122 help='''produce a signed .bin file?
Marti Bolivard371c542019-06-12 11:39:09 -0600123 (default: yes, if supported and unsigned bin
124 exists)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700125 group.add_argument('-B', '--sbin', metavar='BIN',
Marti Bolivard1780aa2019-01-30 20:30:42 -0700126 help='''signed .bin file name
Marti Bolivar33cbba32019-06-12 10:29:01 -0600127 (default: zephyr.signed.bin in the build
128 directory, next to zephyr.bin)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700129
130 # hex file options
131 group = parser.add_argument_group('Intel HEX (.hex) file options')
132 group.add_argument('--hex', '--no-hex', dest='gen_hex', nargs=0,
133 action=ToggleAction,
134 help='''produce a signed .hex file?
Marti Bolivard371c542019-06-12 11:39:09 -0600135 (default: yes, if supported and unsigned hex
136 exists)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700137 group.add_argument('-H', '--shex', metavar='HEX',
Marti Bolivard1780aa2019-01-30 20:30:42 -0700138 help='''signed .hex file name
Marti Bolivar33cbba32019-06-12 10:29:01 -0600139 (default: zephyr.signed.hex in the build
140 directory, next to zephyr.hex)''')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700141
Marti Bolivard1780aa2019-01-30 20:30:42 -0700142 return parser
143
144 def do_run(self, args, ignored):
Marti Bolivarf13fa532019-02-14 10:01:00 -0700145 self.args = args # for check_force
Marti Bolivard371c542019-06-12 11:39:09 -0600146
147 # Find the build directory and parse .config and DT.
148 build_dir = find_build_dir(args.build_dir)
Marti Bolivar06c9f8e2019-06-12 11:49:02 -0600149 self.check_force(os.path.isdir(build_dir),
150 'no such build directory {}'.format(build_dir))
151 self.check_force(is_zephyr_build(build_dir),
Marti Bolivard1780aa2019-01-30 20:30:42 -0700152 "build directory {} doesn't look like a Zephyr build "
Marti Bolivar06c9f8e2019-06-12 11:49:02 -0600153 'directory'.format(build_dir))
Marti Bolivard371c542019-06-12 11:39:09 -0600154 bcfg = BuildConfiguration(build_dir)
Marti Bolivard1780aa2019-01-30 20:30:42 -0700155
Marti Bolivard371c542019-06-12 11:39:09 -0600156 # Decide on output formats.
157 formats = []
158 bin_exists = 'CONFIG_BUILD_OUTPUT_BIN' in bcfg
159 if args.gen_bin:
160 self.check_force(bin_exists,
161 '--bin given but CONFIG_BUILD_OUTPUT_BIN not set '
162 "in build directory's ({}) .config".
163 format(build_dir))
164 formats.append('bin')
165 elif args.gen_bin is None and bin_exists:
166 formats.append('bin')
167
168 hex_exists = 'CONFIG_BUILD_OUTPUT_HEX' in bcfg
169 if args.gen_hex:
170 self.check_force(hex_exists,
171
172 '--hex given but CONFIG_BUILD_OUTPUT_HEX not set '
173 "in build directory's ({}) .config".
174 format(build_dir))
175 formats.append('hex')
176 elif args.gen_hex is None and hex_exists:
177 formats.append('hex')
178
Marti Bolivard371c542019-06-12 11:39:09 -0600179 # Delegate to the signer.
Marti Bolivard1780aa2019-01-30 20:30:42 -0700180 if args.tool == 'imgtool':
181 signer = ImgtoolSigner()
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200182 elif args.tool == 'rimage':
183 signer = RimageSigner()
Marti Bolivard1780aa2019-01-30 20:30:42 -0700184 # (Add support for other signers here in elif blocks)
185 else:
186 raise RuntimeError("can't happen")
187
Marti Bolivard371c542019-06-12 11:39:09 -0600188 signer.sign(self, build_dir, bcfg, formats)
Marti Bolivard1780aa2019-01-30 20:30:42 -0700189
190
191class Signer(abc.ABC):
192 '''Common abstract superclass for signers.
193
194 To add support for a new tool, subclass this and add support for
195 it in the Sign.do_run() method.'''
196
197 @abc.abstractmethod
Marti Bolivard371c542019-06-12 11:39:09 -0600198 def sign(self, command, build_dir, bcfg, formats):
Marti Bolivard1780aa2019-01-30 20:30:42 -0700199 '''Abstract method to perform a signature; subclasses must implement.
200
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700201 :param command: the Sign instance
Marti Bolivar06c9f8e2019-06-12 11:49:02 -0600202 :param build_dir: the build directory
Marti Bolivard371c542019-06-12 11:39:09 -0600203 :param bcfg: BuildConfiguration for build directory
204 :param formats: list of formats to generate ('bin', 'hex')
Marti Bolivard1780aa2019-01-30 20:30:42 -0700205 '''
206
207
208class ImgtoolSigner(Signer):
209
Marti Bolivard371c542019-06-12 11:39:09 -0600210 def sign(self, command, build_dir, bcfg, formats):
Martí Bolívard8f459a2019-11-12 14:55:03 -0800211 if not formats:
212 return
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700213
Martí Bolívard8f459a2019-11-12 14:55:03 -0800214 args = command.args
215 b = pathlib.Path(build_dir)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800216
Martí Bolívarb4903d42021-02-02 12:05:58 -0800217 imgtool = self.find_imgtool(command, args)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800218 # The vector table offset is set in Kconfig:
Stephanos Ioannidis33224892020-02-10 16:37:24 +0900219 vtoff = self.get_cfg(command, bcfg, 'CONFIG_ROM_START_OFFSET')
Martí Bolívard8f459a2019-11-12 14:55:03 -0800220 # Flash device write alignment and the partition's slot size
221 # come from devicetree:
Martí Bolívar9b673672020-08-19 15:29:37 -0700222 flash = self.edt_flash_node(b, args.quiet)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800223 align, addr, size = self.edt_flash_params(flash)
224
Martí Bolívar74929972020-08-07 15:40:05 -0700225 dot_config_file = b / 'zephyr' / '.config'
226 if not dot_config_file.is_file():
227 log.die(f"no .config found at {dot_config_file}")
228
229 dot_config = load_dot_config(dot_config_file)
230
231 if dot_config.get('CONFIG_BOOTLOADER_MCUBOOT', 'n') != 'y':
232 log.wrn("CONFIG_BOOTLOADER_MCUBOOT is not set to y in "
233 f"{dot_config_file}; this probably won't work")
234
235 kernel = dot_config.get('CONFIG_KERNEL_BIN_NAME', 'zephyr')
236
Martí Bolívard8f459a2019-11-12 14:55:03 -0800237 if 'bin' in formats:
Martí Bolívar74929972020-08-07 15:40:05 -0700238 in_bin = b / 'zephyr' / f'{kernel}.bin'
239 if not in_bin.is_file():
240 log.die(f"no unsigned .bin found at {in_bin}")
241 in_bin = os.fspath(in_bin)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800242 else:
243 in_bin = None
244 if 'hex' in formats:
Martí Bolívar74929972020-08-07 15:40:05 -0700245 in_hex = b / 'zephyr' / f'{kernel}.hex'
246 if not in_hex.is_file():
247 log.die(f"no unsigned .hex found at {in_hex}")
248 in_hex = os.fspath(in_hex)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800249 else:
250 in_hex = None
251
Martí Bolívar9b673672020-08-19 15:29:37 -0700252 if not args.quiet:
253 log.banner('image configuration:')
254 log.inf('partition offset: {0} (0x{0:x})'.format(addr))
255 log.inf('partition size: {0} (0x{0:x})'.format(size))
256 log.inf('rom start offset: {0} (0x{0:x})'.format(vtoff))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800257
258 # Base sign command.
259 #
260 # We provide a default --version in case the user is just
261 # messing around and doesn't want to set one. It will be
262 # overridden if there is a --version in args.tool_args.
Martí Bolívarb4903d42021-02-02 12:05:58 -0800263 sign_base = imgtool + ['sign',
264 '--version', '0.0.0+0',
265 '--align', str(align),
266 '--header-size', str(vtoff),
267 '--slot-size', str(size)]
Martí Bolívard8f459a2019-11-12 14:55:03 -0800268 sign_base.extend(args.tool_args)
269
Martí Bolívar9b673672020-08-19 15:29:37 -0700270 if not args.quiet:
271 log.banner('signing binaries')
Martí Bolívard8f459a2019-11-12 14:55:03 -0800272 if in_bin:
273 out_bin = args.sbin or str(b / 'zephyr' / 'zephyr.signed.bin')
274 sign_bin = sign_base + [in_bin, out_bin]
Martí Bolívar9b673672020-08-19 15:29:37 -0700275 if not args.quiet:
276 log.inf(f'unsigned bin: {in_bin}')
277 log.inf(f'signed bin: {out_bin}')
278 log.dbg(quote_sh_list(sign_bin))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800279 subprocess.check_call(sign_bin)
280 if in_hex:
281 out_hex = args.shex or str(b / 'zephyr' / 'zephyr.signed.hex')
282 sign_hex = sign_base + [in_hex, out_hex]
Martí Bolívar9b673672020-08-19 15:29:37 -0700283 if not args.quiet:
284 log.inf(f'unsigned hex: {in_hex}')
285 log.inf(f'signed hex: {out_hex}')
286 log.dbg(quote_sh_list(sign_hex))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800287 subprocess.check_call(sign_hex)
288
289 @staticmethod
290 def find_imgtool(command, args):
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700291 if args.tool_path:
Martí Bolívar698db692021-02-02 12:20:47 -0800292 imgtool = args.tool_path
293 if not os.path.isfile(imgtool):
294 log.die(f'--tool-path {imgtool}: no such file')
295 else:
296 imgtool = shutil.which('imgtool') or shutil.which('imgtool.py')
297 if not imgtool:
298 log.die('imgtool not found; either install it',
299 '(e.g. "pip3 install imgtool") or provide --tool-path')
Martí Bolívarb4903d42021-02-02 12:05:58 -0800300
Martí Bolívar698db692021-02-02 12:20:47 -0800301 if platform.system() == 'Windows' and imgtool.endswith('.py'):
302 # Windows users may not be able to run .py files
303 # as executables in subprocesses, regardless of
304 # what the mode says. Always run imgtool as
305 # 'python path/to/imgtool.py' instead of
306 # 'path/to/imgtool.py' in these cases.
307 # https://github.com/zephyrproject-rtos/zephyr/issues/31876
308 return [sys.executable, imgtool]
309
Martí Bolívarb4903d42021-02-02 12:05:58 -0800310 return [imgtool]
Marti Bolivar2f839da2019-06-12 11:25:23 -0600311
Ulf Magnussonbb634162019-09-04 16:28:50 +0200312 @staticmethod
313 def get_cfg(command, bcfg, item):
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700314 try:
Marti Bolivar2f839da2019-06-12 11:25:23 -0600315 return bcfg[item]
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700316 except KeyError:
317 command.check_force(
Martí Bolívard8f459a2019-11-12 14:55:03 -0800318 False, "build .config is missing a {} value".format(item))
Marti Bolivar4a0f1f22019-02-14 14:49:03 -0700319 return None
Martí Bolívard8f459a2019-11-12 14:55:03 -0800320
321 @staticmethod
Martí Bolívar9b673672020-08-19 15:29:37 -0700322 def edt_flash_node(b, quiet=False):
Martí Bolívard8f459a2019-11-12 14:55:03 -0800323 # Get the EDT Node corresponding to the zephyr,flash chosen DT
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700324 # node; 'b' is the build directory as a pathlib object.
Martí Bolívard8f459a2019-11-12 14:55:03 -0800325
326 # Ensure the build directory has a compiled DTS file
327 # where we expect it to be.
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700328 dts = b / 'zephyr' / 'zephyr.dts'
Martí Bolívar9b673672020-08-19 15:29:37 -0700329 if not quiet:
330 log.dbg('DTS file:', dts, level=log.VERBOSE_VERY)
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700331 edt_pickle = b / 'zephyr' / 'edt.pickle'
332 if not edt_pickle.is_file():
333 log.die("can't load devicetree; expected to find:", edt_pickle)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800334
Martí Bolívar9c92baa2020-07-08 14:43:07 -0700335 # Load the devicetree.
336 with open(edt_pickle, 'rb') as f:
337 edt = pickle.load(f)
Martí Bolívard8f459a2019-11-12 14:55:03 -0800338
339 # By convention, the zephyr,flash chosen node contains the
340 # partition information about the zephyr image to sign.
341 flash = edt.chosen_node('zephyr,flash')
342 if not flash:
343 log.die('devicetree has no chosen zephyr,flash node;',
344 "can't infer flash write block or image-0 slot sizes")
345
346 return flash
347
348 @staticmethod
349 def edt_flash_params(flash):
Fabio Utzig716ab472020-08-17 08:59:36 -0300350 # Get the flash device's write alignment and offset from the
351 # image-0 partition and the size from image-1 partition, out of the
352 # build directory's devicetree. image-1 partition size is used,
353 # when available, because in swap-move mode it can be one sector
354 # smaller. When not available, fallback to image-0 (single image dfu).
Martí Bolívard8f459a2019-11-12 14:55:03 -0800355
356 # The node must have a "partitions" child node, which in turn
Fabio Utzig716ab472020-08-17 08:59:36 -0300357 # must have child node labeled "image-0" and may have a child node
358 # named "image-1". By convention, the slots for consumption by
359 # imgtool are linked into these partitions.
Martí Bolívard8f459a2019-11-12 14:55:03 -0800360 if 'partitions' not in flash.children:
361 log.die("DT zephyr,flash chosen node has no partitions,",
Fabio Utzig716ab472020-08-17 08:59:36 -0300362 "can't find partitions for MCUboot slots")
Martí Bolívard8f459a2019-11-12 14:55:03 -0800363
Fabio Utzig716ab472020-08-17 08:59:36 -0300364 partitions = flash.children['partitions']
365 images = {
366 node.label: node for node in partitions.children.values()
367 if node.label in set(['image-0', 'image-1'])
368 }
369
370 if 'image-0' not in images:
371 log.die("DT zephyr,flash chosen node has no image-0 partition,",
372 "can't determine its address")
Martí Bolívard8f459a2019-11-12 14:55:03 -0800373
374 # Die on missing or zero alignment or slot_size.
375 if "write-block-size" not in flash.props:
376 log.die('DT zephyr,flash node has no write-block-size;',
377 "can't determine imgtool write alignment")
378 align = flash.props['write-block-size'].val
379 if align == 0:
380 log.die('expected nonzero flash alignment, but got '
381 'DT flash device write-block-size {}'.format(align))
Martí Bolívard8f459a2019-11-12 14:55:03 -0800382
Fabio Utzig716ab472020-08-17 08:59:36 -0300383 # The partitions node, and its subnode, must provide
384 # the size of image-1 or image-0 partition via the regs property.
385 image_key = 'image-1' if 'image-1' in images else 'image-0'
386 if not images[image_key].regs:
387 log.die(f'{image_key} flash partition has no regs property;',
388 "can't determine size of image")
389
390 # always use addr of image-0, which is where images are run
391 addr = images['image-0'].regs[0].addr
392
393 size = images[image_key].regs[0].size
394 if size == 0:
395 log.die('expected nonzero slot size for {}'.format(image_key))
396
397 return (align, addr, size)
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200398
399class RimageSigner(Signer):
400
Anas Nashiff751dd42020-10-14 14:44:53 -0400401 @staticmethod
402 def edt_get_rimage_target(board):
Anas Nashif3ac163e2020-10-21 09:40:02 -0400403 if 'intel_adsp_cavs15' in board:
Anas Nashiff751dd42020-10-14 14:44:53 -0400404 return 'apl'
405 if 'intel_adsp_cavs18' in board:
406 return 'cnl'
407 if 'intel_adsp_cavs20' in board:
408 return 'icl'
409 if 'intel_adsp_cavs25' in board:
410 return 'tgl'
411
412 log.die('Signing not supported for board ' + board)
413
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200414 def sign(self, command, build_dir, bcfg, formats):
415 args = command.args
416
417 if args.tool_path:
418 command.check_force(shutil.which(args.tool_path),
419 '--tool-path {}: not an executable'.
420 format(args.tool_path))
421 tool_path = args.tool_path
422 else:
423 tool_path = shutil.which('rimage')
424 if not tool_path:
425 log.die('rimage not found; either install it',
426 'or provide --tool-path')
427
428 b = pathlib.Path(build_dir)
429 cache = CMakeCache.from_build_dir(build_dir)
430
431 board = cache['CACHED_BOARD']
Anas Nashiff751dd42020-10-14 14:44:53 -0400432 log.inf('Signing for board ' + board)
433 target = self.edt_get_rimage_target(board)
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100434 conf = target + '.toml'
435 log.inf('Signing for SOC target ' + target + ' using ' + conf)
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200436
Martí Bolívar9b673672020-08-19 15:29:37 -0700437 if not args.quiet:
438 log.inf('Signing with tool {}'.format(tool_path))
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200439
440 bootloader = str(b / 'zephyr' / 'bootloader.elf.mod')
441 kernel = str(b / 'zephyr' / 'zephyr.elf.mod')
442 out_bin = str(b / 'zephyr' / 'zephyr.ri')
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100443 out_xman = str(b / 'zephyr' / 'zephyr.ri.xman')
444 out_tmp = str(b / 'zephyr' / 'zephyr.rix')
Anas Nashiffee9af22021-01-25 13:59:57 -0500445 conf_path_cmd = []
446 if cache.get('RIMAGE_CONFIG_PATH') and not args.tool_data:
447 rimage_conf = pathlib.Path(cache['RIMAGE_CONFIG_PATH'])
448 conf_path = str(rimage_conf / conf)
449 conf_path_cmd = ['-c', conf_path]
450 elif args.tool_data:
451 conf_dir = pathlib.Path(args.tool_data)
452 conf_path = str(conf_dir / conf)
453 conf_path_cmd = ['-c', conf_path]
454 else:
455 log.die('Configuration not found')
Jian Kang8c9b06a2021-02-03 17:05:24 +0800456 if '--no-manifest' in args.tool_args:
457 no_manifest = True
458 args.tool_args.remove('--no-manifest')
459 else:
460 no_manifest = False
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200461
462 sign_base = ([tool_path] + args.tool_args +
Anas Nashiffee9af22021-01-25 13:59:57 -0500463 ['-o', out_bin] + conf_path_cmd + ['-i', '3', '-e'] +
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200464 [bootloader, kernel])
465
Martí Bolívar9b673672020-08-19 15:29:37 -0700466 if not args.quiet:
467 log.inf(quote_sh_list(sign_base))
Andrei Emeltchenkod44d9862019-11-19 12:35:49 +0200468 subprocess.check_call(sign_base)
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100469
Jian Kang8c9b06a2021-02-03 17:05:24 +0800470 if no_manifest:
471 filenames = [out_bin]
472 else:
473 filenames = [out_xman, out_bin]
Guennadi Liakhovetski3de40b42020-10-27 12:48:36 +0100474 with open(out_tmp, 'wb') as outfile:
475 for fname in filenames:
476 with open(fname, 'rb') as infile:
477 outfile.write(infile.read())
478
479 os.remove(out_bin)
480 os.rename(out_tmp, out_bin)