Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 1 | # Copyright (c) 2018 Foundries.io |
| 2 | # |
| 3 | # SPDX-License-Identifier: Apache-2.0 |
| 4 | |
| 5 | import abc |
| 6 | import argparse |
| 7 | import os |
Marti Bolivar | 2f839da | 2019-06-12 11:25:23 -0600 | [diff] [blame] | 8 | import pathlib |
Martí Bolívar | 9c92baa | 2020-07-08 14:43:07 -0700 | [diff] [blame] | 9 | import pickle |
Martí Bolívar | 698db69 | 2021-02-02 12:20:47 -0800 | [diff] [blame] | 10 | import platform |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 11 | import shutil |
Marc Herbert | 030b740 | 2023-02-24 02:52:14 +0000 | [diff] [blame] | 12 | import shlex |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 13 | import subprocess |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 14 | import sys |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 15 | |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 16 | from west import log |
Marc Herbert | efb8551 | 2023-02-24 02:24:35 +0000 | [diff] [blame] | 17 | from west import manifest |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 18 | from west.util import quote_sh_list |
| 19 | |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 20 | from build_helpers import find_build_dir, is_zephyr_build, \ |
Marti Bolivar | 3bd07a2 | 2019-06-12 11:48:50 -0600 | [diff] [blame] | 21 | FIND_BUILD_DIR_DESCRIPTION |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 22 | from runners.core import BuildConfiguration |
| 23 | from zcmake import CMakeCache |
Dominik Ermel | 09980d6 | 2021-01-19 18:19:36 +0000 | [diff] [blame] | 24 | from zephyr_ext_common import Forceable, ZEPHYR_SCRIPTS |
Jun Li | 2d5fb6d | 2019-05-07 02:00:20 -0700 | [diff] [blame] | 25 | |
Martí Bolívar | 9c92baa | 2020-07-08 14:43:07 -0700 | [diff] [blame] | 26 | # This is needed to load edt.pickle files. |
Jordan Yates | 8e4107f | 2022-04-30 21:13:52 +1000 | [diff] [blame] | 27 | sys.path.insert(0, str(ZEPHYR_SCRIPTS / 'dts' / 'python-devicetree' / 'src')) |
Martí Bolívar | 6dab163 | 2020-02-10 16:53:06 -0800 | [diff] [blame] | 28 | |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 29 | SIGN_DESCRIPTION = '''\ |
| 30 | This command automates some of the drudgery of creating signed Zephyr |
| 31 | binaries for chain-loading by a bootloader. |
| 32 | |
| 33 | In the simplest usage, run this from your build directory: |
| 34 | |
| 35 | west sign -t your_tool -- ARGS_FOR_YOUR_TOOL |
| 36 | |
Andrei Emeltchenko | fb44188 | 2020-07-07 11:57:51 +0300 | [diff] [blame] | 37 | The "ARGS_FOR_YOUR_TOOL" value can be any additional |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 38 | arguments you want to pass to the tool, such as the location of a |
Torsten Rasmussen | 49389b5 | 2023-03-23 11:02:49 +0100 | [diff] [blame] | 39 | signing key etc. |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 40 | |
| 41 | See tool-specific help below for details.''' |
| 42 | |
| 43 | SIGN_EPILOG = '''\ |
| 44 | imgtool |
| 45 | ------- |
| 46 | |
Andrei Emeltchenko | 51182ab | 2020-07-06 15:37:00 +0300 | [diff] [blame] | 47 | To build a signed binary you can load with MCUboot using imgtool, |
| 48 | run this from your build directory: |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 49 | |
| 50 | west sign -t imgtool -- --key YOUR_SIGNING_KEY.pem |
| 51 | |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 52 | For this to work, either imgtool must be installed (e.g. using pip3), |
| 53 | or you must pass the path to imgtool.py using the -p option. |
| 54 | |
Andrei Emeltchenko | fb44188 | 2020-07-07 11:57:51 +0300 | [diff] [blame] | 55 | Assuming your binary was properly built for processing and handling by |
| 56 | imgtool, this creates zephyr.signed.bin and zephyr.signed.hex |
| 57 | files which are ready for use by your bootloader. |
| 58 | |
Torsten Rasmussen | 49389b5 | 2023-03-23 11:02:49 +0100 | [diff] [blame] | 59 | The version number, image header size, alignment, and slot sizes are |
| 60 | determined from the build directory using .config and the device tree. |
| 61 | As shown above, extra arguments after a '--' are passed to imgtool |
| 62 | directly. |
Andrei Emeltchenko | 51182ab | 2020-07-06 15:37:00 +0300 | [diff] [blame] | 63 | |
| 64 | rimage |
| 65 | ------ |
| 66 | |
| 67 | To create a signed binary with the rimage tool, run this from your build |
| 68 | directory: |
| 69 | |
| 70 | west sign -t rimage -- -k YOUR_SIGNING_KEY.pem |
| 71 | |
| 72 | For this to work, either rimage must be installed or you must pass |
Marc Herbert | 030b740 | 2023-02-24 02:52:14 +0000 | [diff] [blame] | 73 | the path to rimage using the -p option. |
| 74 | |
| 75 | You can also pass additional arguments to rimage thanks to [sign] and |
| 76 | [rimage] sections in your west config file(s); this is especially useful |
| 77 | when invoking west sign _indirectly_ through CMake/ninja. See how at |
| 78 | https://docs.zephyrproject.org/latest/develop/west/sign.html |
| 79 | ''' |
| 80 | |
| 81 | |
| 82 | def config_get_words(west_config, section_key, fallback=None): |
| 83 | unparsed = west_config.get(section_key) |
| 84 | log.dbg(f'west config {section_key}={unparsed}') |
| 85 | return fallback if unparsed is None else shlex.split(unparsed) |
| 86 | |
| 87 | |
| 88 | def config_get(west_config, section_key, fallback=None): |
| 89 | words = config_get_words(west_config, section_key) |
| 90 | if words is None: |
| 91 | return fallback |
| 92 | if len(words) != 1: |
| 93 | log.die(f'Single word expected for: {section_key}={words}. Use quotes?') |
| 94 | return words[0] |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 95 | |
| 96 | |
| 97 | class ToggleAction(argparse.Action): |
| 98 | |
| 99 | def __call__(self, parser, args, ignored, option): |
| 100 | setattr(args, self.dest, not option.startswith('--no-')) |
| 101 | |
| 102 | |
| 103 | class Sign(Forceable): |
| 104 | def __init__(self): |
| 105 | super(Sign, self).__init__( |
| 106 | 'sign', |
| 107 | # Keep this in sync with the string in west-commands.yml. |
| 108 | 'sign a Zephyr binary for bootloader chain-loading', |
| 109 | SIGN_DESCRIPTION, |
| 110 | accepts_unknown_args=False) |
| 111 | |
| 112 | def do_add_parser(self, parser_adder): |
| 113 | parser = parser_adder.add_parser( |
| 114 | self.name, |
| 115 | epilog=SIGN_EPILOG, |
| 116 | help=self.help, |
| 117 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| 118 | description=self.description) |
| 119 | |
Marti Bolivar | 3bd07a2 | 2019-06-12 11:48:50 -0600 | [diff] [blame] | 120 | parser.add_argument('-d', '--build-dir', |
| 121 | help=FIND_BUILD_DIR_DESCRIPTION) |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 122 | parser.add_argument('-q', '--quiet', action='store_true', |
| 123 | help='suppress non-error output') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 124 | self.add_force_arg(parser) |
| 125 | |
| 126 | # general options |
| 127 | group = parser.add_argument_group('tool control options') |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 128 | group.add_argument('-t', '--tool', choices=['imgtool', 'rimage'], |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 129 | help='''image signing tool name; imgtool and rimage |
| 130 | are currently supported''') |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 131 | group.add_argument('-p', '--tool-path', default=None, |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 132 | help='''path to the tool itself, if needed''') |
Anas Nashif | b553166 | 2021-01-25 13:57:20 -0500 | [diff] [blame] | 133 | group.add_argument('-D', '--tool-data', default=None, |
Marc Herbert | efb8551 | 2023-02-24 02:24:35 +0000 | [diff] [blame] | 134 | help='''path to a tool-specific data/configuration directory, if needed''') |
Marc Herbert | 2c80c4d | 2023-03-03 01:45:45 +0000 | [diff] [blame] | 135 | group.add_argument('--if-tool-available', action='store_true', |
Iuliana Prodan | 4cf9d67 | 2023-08-22 18:58:44 +0300 | [diff] [blame] | 136 | help='''Do not fail if the rimage tool is not found or the rimage signing |
| 137 | schema (rimage "target") is not defined in board.cmake.''') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 138 | group.add_argument('tool_args', nargs='*', metavar='tool_opt', |
| 139 | help='extra option(s) to pass to the signing tool') |
| 140 | |
| 141 | # bin file options |
| 142 | group = parser.add_argument_group('binary (.bin) file options') |
| 143 | group.add_argument('--bin', '--no-bin', dest='gen_bin', nargs=0, |
| 144 | action=ToggleAction, |
| 145 | help='''produce a signed .bin file? |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 146 | (default: yes, if supported and unsigned bin |
| 147 | exists)''') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 148 | group.add_argument('-B', '--sbin', metavar='BIN', |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 149 | help='''signed .bin file name |
Marti Bolivar | 33cbba3 | 2019-06-12 10:29:01 -0600 | [diff] [blame] | 150 | (default: zephyr.signed.bin in the build |
| 151 | directory, next to zephyr.bin)''') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 152 | |
| 153 | # hex file options |
| 154 | group = parser.add_argument_group('Intel HEX (.hex) file options') |
| 155 | group.add_argument('--hex', '--no-hex', dest='gen_hex', nargs=0, |
| 156 | action=ToggleAction, |
| 157 | help='''produce a signed .hex file? |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 158 | (default: yes, if supported and unsigned hex |
| 159 | exists)''') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 160 | group.add_argument('-H', '--shex', metavar='HEX', |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 161 | help='''signed .hex file name |
Marti Bolivar | 33cbba3 | 2019-06-12 10:29:01 -0600 | [diff] [blame] | 162 | (default: zephyr.signed.hex in the build |
| 163 | directory, next to zephyr.hex)''') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 164 | |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 165 | return parser |
| 166 | |
| 167 | def do_run(self, args, ignored): |
Marti Bolivar | f13fa53 | 2019-02-14 10:01:00 -0700 | [diff] [blame] | 168 | self.args = args # for check_force |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 169 | |
| 170 | # Find the build directory and parse .config and DT. |
| 171 | build_dir = find_build_dir(args.build_dir) |
Marti Bolivar | 06c9f8e | 2019-06-12 11:49:02 -0600 | [diff] [blame] | 172 | self.check_force(os.path.isdir(build_dir), |
| 173 | 'no such build directory {}'.format(build_dir)) |
| 174 | self.check_force(is_zephyr_build(build_dir), |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 175 | "build directory {} doesn't look like a Zephyr build " |
Marti Bolivar | 06c9f8e | 2019-06-12 11:49:02 -0600 | [diff] [blame] | 176 | 'directory'.format(build_dir)) |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 177 | build_conf = BuildConfiguration(build_dir) |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 178 | |
Marc Herbert | 5831164 | 2023-02-24 03:23:30 +0000 | [diff] [blame] | 179 | if not args.tool: |
| 180 | args.tool = config_get(self.config, 'sign.tool') |
| 181 | |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 182 | # Decide on output formats. |
| 183 | formats = [] |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 184 | bin_exists = build_conf.getboolean('CONFIG_BUILD_OUTPUT_BIN') |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 185 | if args.gen_bin: |
| 186 | self.check_force(bin_exists, |
| 187 | '--bin given but CONFIG_BUILD_OUTPUT_BIN not set ' |
| 188 | "in build directory's ({}) .config". |
| 189 | format(build_dir)) |
| 190 | formats.append('bin') |
| 191 | elif args.gen_bin is None and bin_exists: |
| 192 | formats.append('bin') |
| 193 | |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 194 | hex_exists = build_conf.getboolean('CONFIG_BUILD_OUTPUT_HEX') |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 195 | if args.gen_hex: |
| 196 | self.check_force(hex_exists, |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 197 | '--hex given but CONFIG_BUILD_OUTPUT_HEX not set ' |
| 198 | "in build directory's ({}) .config". |
| 199 | format(build_dir)) |
| 200 | formats.append('hex') |
| 201 | elif args.gen_hex is None and hex_exists: |
| 202 | formats.append('hex') |
| 203 | |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 204 | # Delegate to the signer. |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 205 | if args.tool == 'imgtool': |
Marc Herbert | 2c80c4d | 2023-03-03 01:45:45 +0000 | [diff] [blame] | 206 | if args.if_tool_available: |
| 207 | log.die('imgtool does not support --if-tool-available') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 208 | signer = ImgtoolSigner() |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 209 | elif args.tool == 'rimage': |
| 210 | signer = RimageSigner() |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 211 | # (Add support for other signers here in elif blocks) |
| 212 | else: |
Marc Herbert | 5831164 | 2023-02-24 03:23:30 +0000 | [diff] [blame] | 213 | if args.tool is None: |
| 214 | log.die('one --tool is required') |
| 215 | else: |
| 216 | log.die(f'invalid tool: {args.tool}') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 217 | |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 218 | signer.sign(self, build_dir, build_conf, formats) |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 219 | |
| 220 | |
| 221 | class Signer(abc.ABC): |
| 222 | '''Common abstract superclass for signers. |
| 223 | |
| 224 | To add support for a new tool, subclass this and add support for |
| 225 | it in the Sign.do_run() method.''' |
| 226 | |
| 227 | @abc.abstractmethod |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 228 | def sign(self, command, build_dir, build_conf, formats): |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 229 | '''Abstract method to perform a signature; subclasses must implement. |
| 230 | |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 231 | :param command: the Sign instance |
Marti Bolivar | 06c9f8e | 2019-06-12 11:49:02 -0600 | [diff] [blame] | 232 | :param build_dir: the build directory |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 233 | :param build_conf: BuildConfiguration for build directory |
Marti Bolivar | d371c54 | 2019-06-12 11:39:09 -0600 | [diff] [blame] | 234 | :param formats: list of formats to generate ('bin', 'hex') |
Marti Bolivar | d1780aa | 2019-01-30 20:30:42 -0700 | [diff] [blame] | 235 | ''' |
| 236 | |
| 237 | |
| 238 | class ImgtoolSigner(Signer): |
| 239 | |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 240 | def sign(self, command, build_dir, build_conf, formats): |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 241 | if not formats: |
| 242 | return |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 243 | |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 244 | args = command.args |
| 245 | b = pathlib.Path(build_dir) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 246 | |
Martí Bolívar | b4903d4 | 2021-02-02 12:05:58 -0800 | [diff] [blame] | 247 | imgtool = self.find_imgtool(command, args) |
Torsten Rasmussen | 49389b5 | 2023-03-23 11:02:49 +0100 | [diff] [blame] | 248 | # The vector table offset and application version are set in Kconfig: |
| 249 | appver = self.get_cfg(command, build_conf, 'CONFIG_MCUBOOT_IMGTOOL_SIGN_VERSION') |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 250 | vtoff = self.get_cfg(command, build_conf, 'CONFIG_ROM_START_OFFSET') |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 251 | # Flash device write alignment and the partition's slot size |
| 252 | # come from devicetree: |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 253 | flash = self.edt_flash_node(b, args.quiet) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 254 | align, addr, size = self.edt_flash_params(flash) |
| 255 | |
Arvin Farahmand | 2de6bf9 | 2021-05-06 14:49:07 -0400 | [diff] [blame] | 256 | if not build_conf.getboolean('CONFIG_BOOTLOADER_MCUBOOT'): |
Martí Bolívar | 7492997 | 2020-08-07 15:40:05 -0700 | [diff] [blame] | 257 | log.wrn("CONFIG_BOOTLOADER_MCUBOOT is not set to y in " |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 258 | f"{build_conf.path}; this probably won't work") |
Martí Bolívar | 7492997 | 2020-08-07 15:40:05 -0700 | [diff] [blame] | 259 | |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 260 | kernel = build_conf.get('CONFIG_KERNEL_BIN_NAME', 'zephyr') |
Martí Bolívar | 7492997 | 2020-08-07 15:40:05 -0700 | [diff] [blame] | 261 | |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 262 | if 'bin' in formats: |
Martí Bolívar | 7492997 | 2020-08-07 15:40:05 -0700 | [diff] [blame] | 263 | in_bin = b / 'zephyr' / f'{kernel}.bin' |
| 264 | if not in_bin.is_file(): |
| 265 | log.die(f"no unsigned .bin found at {in_bin}") |
| 266 | in_bin = os.fspath(in_bin) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 267 | else: |
| 268 | in_bin = None |
| 269 | if 'hex' in formats: |
Martí Bolívar | 7492997 | 2020-08-07 15:40:05 -0700 | [diff] [blame] | 270 | in_hex = b / 'zephyr' / f'{kernel}.hex' |
| 271 | if not in_hex.is_file(): |
| 272 | log.die(f"no unsigned .hex found at {in_hex}") |
| 273 | in_hex = os.fspath(in_hex) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 274 | else: |
| 275 | in_hex = None |
| 276 | |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 277 | if not args.quiet: |
| 278 | log.banner('image configuration:') |
| 279 | log.inf('partition offset: {0} (0x{0:x})'.format(addr)) |
| 280 | log.inf('partition size: {0} (0x{0:x})'.format(size)) |
| 281 | log.inf('rom start offset: {0} (0x{0:x})'.format(vtoff)) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 282 | |
| 283 | # Base sign command. |
Martí Bolívar | b4903d4 | 2021-02-02 12:05:58 -0800 | [diff] [blame] | 284 | sign_base = imgtool + ['sign', |
Torsten Rasmussen | 49389b5 | 2023-03-23 11:02:49 +0100 | [diff] [blame] | 285 | '--version', str(appver), |
Martí Bolívar | b4903d4 | 2021-02-02 12:05:58 -0800 | [diff] [blame] | 286 | '--align', str(align), |
| 287 | '--header-size', str(vtoff), |
| 288 | '--slot-size', str(size)] |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 289 | sign_base.extend(args.tool_args) |
| 290 | |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 291 | if not args.quiet: |
| 292 | log.banner('signing binaries') |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 293 | if in_bin: |
| 294 | out_bin = args.sbin or str(b / 'zephyr' / 'zephyr.signed.bin') |
| 295 | sign_bin = sign_base + [in_bin, out_bin] |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 296 | if not args.quiet: |
| 297 | log.inf(f'unsigned bin: {in_bin}') |
| 298 | log.inf(f'signed bin: {out_bin}') |
| 299 | log.dbg(quote_sh_list(sign_bin)) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 300 | subprocess.check_call(sign_bin) |
| 301 | if in_hex: |
| 302 | out_hex = args.shex or str(b / 'zephyr' / 'zephyr.signed.hex') |
| 303 | sign_hex = sign_base + [in_hex, out_hex] |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 304 | if not args.quiet: |
| 305 | log.inf(f'unsigned hex: {in_hex}') |
| 306 | log.inf(f'signed hex: {out_hex}') |
| 307 | log.dbg(quote_sh_list(sign_hex)) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 308 | subprocess.check_call(sign_hex) |
| 309 | |
| 310 | @staticmethod |
| 311 | def find_imgtool(command, args): |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 312 | if args.tool_path: |
Martí Bolívar | 698db69 | 2021-02-02 12:20:47 -0800 | [diff] [blame] | 313 | imgtool = args.tool_path |
| 314 | if not os.path.isfile(imgtool): |
| 315 | log.die(f'--tool-path {imgtool}: no such file') |
| 316 | else: |
| 317 | imgtool = shutil.which('imgtool') or shutil.which('imgtool.py') |
| 318 | if not imgtool: |
| 319 | log.die('imgtool not found; either install it', |
| 320 | '(e.g. "pip3 install imgtool") or provide --tool-path') |
Martí Bolívar | b4903d4 | 2021-02-02 12:05:58 -0800 | [diff] [blame] | 321 | |
Martí Bolívar | 698db69 | 2021-02-02 12:20:47 -0800 | [diff] [blame] | 322 | if platform.system() == 'Windows' and imgtool.endswith('.py'): |
| 323 | # Windows users may not be able to run .py files |
| 324 | # as executables in subprocesses, regardless of |
| 325 | # what the mode says. Always run imgtool as |
| 326 | # 'python path/to/imgtool.py' instead of |
| 327 | # 'path/to/imgtool.py' in these cases. |
| 328 | # https://github.com/zephyrproject-rtos/zephyr/issues/31876 |
| 329 | return [sys.executable, imgtool] |
| 330 | |
Martí Bolívar | b4903d4 | 2021-02-02 12:05:58 -0800 | [diff] [blame] | 331 | return [imgtool] |
Marti Bolivar | 2f839da | 2019-06-12 11:25:23 -0600 | [diff] [blame] | 332 | |
Ulf Magnusson | bb63416 | 2019-09-04 16:28:50 +0200 | [diff] [blame] | 333 | @staticmethod |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 334 | def get_cfg(command, build_conf, item): |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 335 | try: |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 336 | return build_conf[item] |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 337 | except KeyError: |
| 338 | command.check_force( |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 339 | False, "build .config is missing a {} value".format(item)) |
Marti Bolivar | 4a0f1f2 | 2019-02-14 14:49:03 -0700 | [diff] [blame] | 340 | return None |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 341 | |
| 342 | @staticmethod |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 343 | def edt_flash_node(b, quiet=False): |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 344 | # Get the EDT Node corresponding to the zephyr,flash chosen DT |
Martí Bolívar | 9c92baa | 2020-07-08 14:43:07 -0700 | [diff] [blame] | 345 | # node; 'b' is the build directory as a pathlib object. |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 346 | |
| 347 | # Ensure the build directory has a compiled DTS file |
| 348 | # where we expect it to be. |
Martí Bolívar | 9c92baa | 2020-07-08 14:43:07 -0700 | [diff] [blame] | 349 | dts = b / 'zephyr' / 'zephyr.dts' |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 350 | if not quiet: |
| 351 | log.dbg('DTS file:', dts, level=log.VERBOSE_VERY) |
Martí Bolívar | 9c92baa | 2020-07-08 14:43:07 -0700 | [diff] [blame] | 352 | edt_pickle = b / 'zephyr' / 'edt.pickle' |
| 353 | if not edt_pickle.is_file(): |
| 354 | log.die("can't load devicetree; expected to find:", edt_pickle) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 355 | |
Martí Bolívar | 9c92baa | 2020-07-08 14:43:07 -0700 | [diff] [blame] | 356 | # Load the devicetree. |
| 357 | with open(edt_pickle, 'rb') as f: |
| 358 | edt = pickle.load(f) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 359 | |
| 360 | # By convention, the zephyr,flash chosen node contains the |
| 361 | # partition information about the zephyr image to sign. |
| 362 | flash = edt.chosen_node('zephyr,flash') |
| 363 | if not flash: |
| 364 | log.die('devicetree has no chosen zephyr,flash node;', |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 365 | "can't infer flash write block or slot0_partition slot sizes") |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 366 | |
| 367 | return flash |
| 368 | |
| 369 | @staticmethod |
| 370 | def edt_flash_params(flash): |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 371 | # Get the flash device's write alignment and offset from the |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 372 | # slot0_partition and the size from slot1_partition , out of the |
| 373 | # build directory's devicetree. slot1_partition size is used, |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 374 | # when available, because in swap-move mode it can be one sector |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 375 | # smaller. When not available, fallback to slot0_partition (single slot dfu). |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 376 | |
| 377 | # The node must have a "partitions" child node, which in turn |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 378 | # must have child nodes with label slot0_partition and may have a child node |
| 379 | # with label slot1_partition. By convention, the slots for consumption by |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 380 | # imgtool are linked into these partitions. |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 381 | if 'partitions' not in flash.children: |
| 382 | log.die("DT zephyr,flash chosen node has no partitions,", |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 383 | "can't find partitions for MCUboot slots") |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 384 | |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 385 | partitions = flash.children['partitions'] |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 386 | slots = { |
| 387 | label: node for node in partitions.children.values() |
| 388 | for label in node.labels |
| 389 | if label in set(['slot0_partition', 'slot1_partition']) |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 390 | } |
| 391 | |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 392 | if 'slot0_partition' not in slots: |
| 393 | log.die("DT zephyr,flash chosen node has no slot0_partition partition,", |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 394 | "can't determine its address") |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 395 | |
| 396 | # Die on missing or zero alignment or slot_size. |
| 397 | if "write-block-size" not in flash.props: |
| 398 | log.die('DT zephyr,flash node has no write-block-size;', |
| 399 | "can't determine imgtool write alignment") |
| 400 | align = flash.props['write-block-size'].val |
| 401 | if align == 0: |
| 402 | log.die('expected nonzero flash alignment, but got ' |
| 403 | 'DT flash device write-block-size {}'.format(align)) |
Martí Bolívar | d8f459a | 2019-11-12 14:55:03 -0800 | [diff] [blame] | 404 | |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 405 | # The partitions node, and its subnode, must provide |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 406 | # the size of slot1_partition or slot0_partition partition via the regs property. |
| 407 | slot_key = 'slot0_partition' if 'slot1_partition' in slots else 'slot0_partition' |
| 408 | if not slots[slot_key].regs: |
| 409 | log.die(f'{slot_key} flash partition has no regs property;', |
| 410 | "can't determine size of slot") |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 411 | |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 412 | # always use addr of slot0_partition, which is where slots are run |
| 413 | addr = slots['slot0_partition'].regs[0].addr |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 414 | |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 415 | size = slots[slot_key].regs[0].size |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 416 | if size == 0: |
Dominik Ermel | 86c4b4c | 2022-11-16 16:18:54 +0000 | [diff] [blame] | 417 | log.die('expected nonzero slot size for {}'.format(slot_key)) |
Fabio Utzig | 716ab47 | 2020-08-17 08:59:36 -0300 | [diff] [blame] | 418 | |
| 419 | return (align, addr, size) |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 420 | |
| 421 | class RimageSigner(Signer): |
| 422 | |
Martí Bolívar | 250b213 | 2021-04-28 16:20:38 -0700 | [diff] [blame] | 423 | def sign(self, command, build_dir, build_conf, formats): |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 424 | args = command.args |
| 425 | |
Marc Herbert | 5bdb146 | 2023-03-03 01:42:05 +0000 | [diff] [blame] | 426 | b = pathlib.Path(build_dir) |
| 427 | cache = CMakeCache.from_build_dir(build_dir) |
| 428 | |
Iuliana Prodan | 4cf9d67 | 2023-08-22 18:58:44 +0300 | [diff] [blame] | 429 | # Warning: RIMAGE_TARGET in Zephyr is a duplicate of |
| 430 | # CONFIG_RIMAGE_SIGNING_SCHEMA in SOF. |
Marc Herbert | 5bdb146 | 2023-03-03 01:42:05 +0000 | [diff] [blame] | 431 | target = cache.get('RIMAGE_TARGET') |
Iuliana Prodan | dc49a31 | 2023-07-07 02:24:21 +0300 | [diff] [blame] | 432 | |
Marc Herbert | 5bdb146 | 2023-03-03 01:42:05 +0000 | [diff] [blame] | 433 | if not target: |
Iuliana Prodan | 4cf9d67 | 2023-08-22 18:58:44 +0300 | [diff] [blame] | 434 | msg = 'rimage target not defined in board.cmake' |
| 435 | if args.if_tool_available: |
| 436 | log.inf(msg) |
| 437 | sys.exit(0) |
| 438 | else: |
| 439 | log.die(msg) |
| 440 | |
| 441 | kernel_name = build_conf.get('CONFIG_KERNEL_BIN_NAME', 'zephyr') |
Marc Herbert | 5bdb146 | 2023-03-03 01:42:05 +0000 | [diff] [blame] | 442 | |
Marc Herbert | e1f36c4 | 2023-06-23 19:14:40 +0000 | [diff] [blame] | 443 | # TODO: make this a new sign.py --bootloader option. |
Marc Herbert | 5bdb146 | 2023-03-03 01:42:05 +0000 | [diff] [blame] | 444 | if target in ('imx8', 'imx8m'): |
Marc Herbert | e1f36c4 | 2023-06-23 19:14:40 +0000 | [diff] [blame] | 445 | bootloader = None |
Iuliana Prodan | dc49a31 | 2023-07-07 02:24:21 +0300 | [diff] [blame] | 446 | kernel = str(b / 'zephyr' / f'{kernel_name}.elf') |
| 447 | out_bin = str(b / 'zephyr' / f'{kernel_name}.ri') |
| 448 | out_xman = str(b / 'zephyr' / f'{kernel_name}.ri.xman') |
| 449 | out_tmp = str(b / 'zephyr' / f'{kernel_name}.rix') |
Marc Herbert | 5bdb146 | 2023-03-03 01:42:05 +0000 | [diff] [blame] | 450 | else: |
| 451 | bootloader = str(b / 'zephyr' / 'boot.mod') |
| 452 | kernel = str(b / 'zephyr' / 'main.mod') |
Iuliana Prodan | dc49a31 | 2023-07-07 02:24:21 +0300 | [diff] [blame] | 453 | out_bin = str(b / 'zephyr' / f'{kernel_name}.ri') |
| 454 | out_xman = str(b / 'zephyr' / f'{kernel_name}.ri.xman') |
| 455 | out_tmp = str(b / 'zephyr' / f'{kernel_name}.rix') |
Marc Herbert | 5bdb146 | 2023-03-03 01:42:05 +0000 | [diff] [blame] | 456 | |
Marc Herbert | 5c4319d | 2023-03-03 01:44:35 +0000 | [diff] [blame] | 457 | # Clean any stale output. This is especially important when using --if-tool-available |
| 458 | # (but not just) |
| 459 | for o in [ out_bin, out_xman, out_tmp ]: |
| 460 | pathlib.Path(o).unlink(missing_ok=True) |
| 461 | |
Marc Herbert | 66ac625 | 2023-02-24 03:29:39 +0000 | [diff] [blame] | 462 | tool_path = ( |
| 463 | args.tool_path if args.tool_path else |
| 464 | config_get(command.config, 'rimage.path', None) |
| 465 | ) |
| 466 | err_prefix = '--tool-path' if args.tool_path else 'west config' |
| 467 | |
| 468 | if tool_path: |
| 469 | command.check_force(shutil.which(tool_path), |
| 470 | f'{err_prefix} {tool_path}: not an executable') |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 471 | else: |
| 472 | tool_path = shutil.which('rimage') |
| 473 | if not tool_path: |
Marc Herbert | 2c80c4d | 2023-03-03 01:45:45 +0000 | [diff] [blame] | 474 | err_msg = 'rimage not found; either install it or provide --tool-path' |
| 475 | if args.if_tool_available: |
| 476 | log.wrn(err_msg) |
| 477 | log.wrn('zephyr binary _not_ signed!') |
| 478 | return |
| 479 | else: |
| 480 | log.die(err_msg) |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 481 | |
Marc Herbert | 2fdc551 | 2022-02-19 07:29:03 +0000 | [diff] [blame] | 482 | #### -c sof/rimage/config/signing_schema.toml #### |
| 483 | |
Marc Herbert | 2fdc551 | 2022-02-19 07:29:03 +0000 | [diff] [blame] | 484 | cmake_toml = target + '.toml' |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 485 | |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 486 | if not args.quiet: |
| 487 | log.inf('Signing with tool {}'.format(tool_path)) |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 488 | |
Marc Herbert | efb8551 | 2023-02-24 02:24:35 +0000 | [diff] [blame] | 489 | try: |
| 490 | sof_proj = command.manifest.get_projects(['sof'], allow_paths=False) |
| 491 | sof_src_dir = pathlib.Path(sof_proj[0].abspath) |
| 492 | except ValueError: # sof is the manifest |
| 493 | sof_src_dir = pathlib.Path(manifest.manifest_path()).parent |
| 494 | |
Marc Herbert | 2fdc551 | 2022-02-19 07:29:03 +0000 | [diff] [blame] | 495 | if '-c' in args.tool_args: |
Marc Herbert | dedb002 | 2023-02-10 08:30:15 +0000 | [diff] [blame] | 496 | # Precedence to the arguments passed after '--': west sign ... -- -c ... |
Marc Herbert | 2fdc551 | 2022-02-19 07:29:03 +0000 | [diff] [blame] | 497 | if args.tool_data: |
Marc Herbert | dedb002 | 2023-02-10 08:30:15 +0000 | [diff] [blame] | 498 | log.wrn('--tool-data ' + args.tool_data + ' ignored, overridden by: -- -c ... ') |
| 499 | conf_dir = None |
Anas Nashif | fee9af2 | 2021-01-25 13:59:57 -0500 | [diff] [blame] | 500 | elif args.tool_data: |
| 501 | conf_dir = pathlib.Path(args.tool_data) |
Marc Herbert | 2fdc551 | 2022-02-19 07:29:03 +0000 | [diff] [blame] | 502 | elif cache.get('RIMAGE_CONFIG_PATH'): |
Marc Herbert | dedb002 | 2023-02-10 08:30:15 +0000 | [diff] [blame] | 503 | conf_dir = pathlib.Path(cache['RIMAGE_CONFIG_PATH']) |
Anas Nashif | fee9af2 | 2021-01-25 13:59:57 -0500 | [diff] [blame] | 504 | else: |
Daniel Leung | 4201978 | 2023-10-23 15:26:22 -0700 | [diff] [blame] | 505 | conf_dir = sof_src_dir / 'tools' / 'rimage' / 'config' |
Marc Herbert | 2fdc551 | 2022-02-19 07:29:03 +0000 | [diff] [blame] | 506 | |
Marc Herbert | dedb002 | 2023-02-10 08:30:15 +0000 | [diff] [blame] | 507 | conf_path_cmd = ['-c', str(conf_dir / cmake_toml)] if conf_dir else [] |
| 508 | |
| 509 | log.inf('Signing for SOC target ' + target) |
Marc Herbert | 2fdc551 | 2022-02-19 07:29:03 +0000 | [diff] [blame] | 510 | |
Marc Herbert | 7249594 | 2023-02-24 02:03:12 +0000 | [diff] [blame] | 511 | # FIXME: deprecate --no-manifest and replace it with a much |
| 512 | # simpler and more direct `-- -e` which the user can _already_ |
| 513 | # pass today! With unclear consequences right now... |
Jian Kang | 8c9b06a | 2021-02-03 17:05:24 +0800 | [diff] [blame] | 514 | if '--no-manifest' in args.tool_args: |
| 515 | no_manifest = True |
| 516 | args.tool_args.remove('--no-manifest') |
| 517 | else: |
| 518 | no_manifest = False |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 519 | |
Daniel Leung | 3be5732 | 2023-10-23 15:24:31 -0700 | [diff] [blame] | 520 | # Non-SOF build does not have extended manifest data for |
| 521 | # rimage to process, which might result in rimage error. |
| 522 | # So skip it when not doing SOF builds. |
| 523 | is_sof_build = build_conf.getboolean('CONFIG_SOF') |
| 524 | if not is_sof_build: |
| 525 | no_manifest = True |
| 526 | |
Daniel Leung | 10eab23 | 2021-09-21 13:37:33 -0700 | [diff] [blame] | 527 | if no_manifest: |
Adrian Bonislawski | 30e4a4b | 2022-10-26 09:37:47 +0200 | [diff] [blame] | 528 | extra_ri_args = [ ] |
Daniel Leung | 10eab23 | 2021-09-21 13:37:33 -0700 | [diff] [blame] | 529 | else: |
Adrian Bonislawski | 30e4a4b | 2022-10-26 09:37:47 +0200 | [diff] [blame] | 530 | extra_ri_args = ['-e'] |
Daniel Leung | 10eab23 | 2021-09-21 13:37:33 -0700 | [diff] [blame] | 531 | |
Marc Herbert | 29fd182 | 2022-03-05 00:05:31 +0000 | [diff] [blame] | 532 | sign_base = [tool_path] |
| 533 | |
| 534 | # Sub-command arg '-q' takes precedence over west '-v' |
| 535 | if not args.quiet and args.verbose: |
| 536 | sign_base += ['-v'] * args.verbose |
| 537 | |
Marc Herbert | e1f36c4 | 2023-06-23 19:14:40 +0000 | [diff] [blame] | 538 | components = [ ] if bootloader is None else [ bootloader ] |
Iuliana Prodan | 602e675 | 2021-10-01 19:10:57 +0300 | [diff] [blame] | 539 | components += [ kernel ] |
Marc Herbert | 2fbcdb5 | 2023-01-28 02:27:17 +0000 | [diff] [blame] | 540 | |
| 541 | sign_config_extra_args = config_get_words(command.config, 'rimage.extra-args', []) |
| 542 | |
| 543 | if '-k' not in sign_config_extra_args + args.tool_args: |
Marc Herbert | 07f2c7a | 2023-05-27 01:32:32 +0000 | [diff] [blame] | 544 | # rimage requires a key argument even when it does not sign |
| 545 | cmake_default_key = cache.get('RIMAGE_SIGN_KEY', 'key placeholder from sign.py') |
Marc Herbert | 2fbcdb5 | 2023-01-28 02:27:17 +0000 | [diff] [blame] | 546 | extra_ri_args += [ '-k', str(sof_src_dir / 'keys' / cmake_default_key) ] |
| 547 | |
Marc Herbert | 6697c5a | 2023-05-11 05:56:52 +0000 | [diff] [blame] | 548 | if '-c' not in sign_config_extra_args + args.tool_args: |
| 549 | extra_ri_args += conf_path_cmd |
| 550 | |
Marc Herbert | 2fbcdb5 | 2023-01-28 02:27:17 +0000 | [diff] [blame] | 551 | # Warning: while not officially supported (yet?), the rimage --option that is last |
| 552 | # on the command line currently wins in case of duplicate options. So pay |
| 553 | # attention to the _args order below. |
Marc Herbert | 6697c5a | 2023-05-11 05:56:52 +0000 | [diff] [blame] | 554 | sign_base += (['-o', out_bin] + sign_config_extra_args + |
Marc Herbert | 2fbcdb5 | 2023-01-28 02:27:17 +0000 | [diff] [blame] | 555 | extra_ri_args + args.tool_args + components) |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 556 | |
Martí Bolívar | 9b67367 | 2020-08-19 15:29:37 -0700 | [diff] [blame] | 557 | if not args.quiet: |
| 558 | log.inf(quote_sh_list(sign_base)) |
Andrei Emeltchenko | d44d986 | 2019-11-19 12:35:49 +0200 | [diff] [blame] | 559 | subprocess.check_call(sign_base) |
Guennadi Liakhovetski | 3de40b4 | 2020-10-27 12:48:36 +0100 | [diff] [blame] | 560 | |
Jian Kang | 8c9b06a | 2021-02-03 17:05:24 +0800 | [diff] [blame] | 561 | if no_manifest: |
| 562 | filenames = [out_bin] |
| 563 | else: |
| 564 | filenames = [out_xman, out_bin] |
Marc Herbert | 7249594 | 2023-02-24 02:03:12 +0000 | [diff] [blame] | 565 | if not args.quiet: |
| 566 | log.inf('Prefixing ' + out_bin + ' with manifest ' + out_xman) |
Guennadi Liakhovetski | 3de40b4 | 2020-10-27 12:48:36 +0100 | [diff] [blame] | 567 | with open(out_tmp, 'wb') as outfile: |
| 568 | for fname in filenames: |
| 569 | with open(fname, 'rb') as infile: |
| 570 | outfile.write(infile.read()) |
| 571 | |
| 572 | os.remove(out_bin) |
| 573 | os.rename(out_tmp, out_bin) |