|
13 | 13 | import sys
|
14 | 14 |
|
15 | 15 | from elftools.elf.elffile import ELFFile
|
16 |
| - |
| 16 | +# custom tool signer |
| 17 | +from west.configuration import config |
17 | 18 | from west import manifest
|
18 | 19 | from west.commands import Verbosity
|
19 | 20 | from west.util import quote_sh_list
|
@@ -112,10 +113,10 @@ def do_add_parser(self, parser_adder):
|
112 | 113 |
|
113 | 114 | # general options
|
114 | 115 | group = parser.add_argument_group('tool control options')
|
115 |
| - group.add_argument('-t', '--tool', choices=['imgtool', 'rimage'], |
| 116 | + group.add_argument('-t', '--tool', choices=['imgtool', 'rimage', 'customtool'], |
116 | 117 | help='''image signing tool name; imgtool and rimage
|
117 | 118 | are currently supported (imgtool is deprecated)''')
|
118 |
| - group.add_argument('-p', '--tool-path', default=None, |
| 119 | + group.add_argument('-p', '--tool-path', default='/zephyr/scripts/west_commands/sign_rps.py', |
119 | 120 | help='''path to the tool itself, if needed''')
|
120 | 121 | group.add_argument('-D', '--tool-data', default=None,
|
121 | 122 | help='''path to a tool-specific data/configuration directory, if needed''')
|
@@ -195,6 +196,8 @@ def do_run(self, args, ignored):
|
195 | 196 | signer = ImgtoolSigner()
|
196 | 197 | elif args.tool == 'rimage':
|
197 | 198 | signer = RimageSigner()
|
| 199 | + elif args.tool == 'customtool': |
| 200 | + signer = CustomToolSigner() |
198 | 201 | # (Add support for other signers here in elif blocks)
|
199 | 202 | else:
|
200 | 203 | if args.tool is None:
|
@@ -633,3 +636,48 @@ def sign(self, command, build_dir, build_conf, formats):
|
633 | 636 |
|
634 | 637 | os.remove(out_bin)
|
635 | 638 | os.rename(out_tmp, out_bin)
|
| 639 | +class CustomToolSigner(Signer): |
| 640 | + def sign(self, command, build_dir, build_conf, formats): |
| 641 | + if not formats: |
| 642 | + return |
| 643 | + args = command.args |
| 644 | + b = pathlib.Path(build_dir) |
| 645 | + kernel_name = 'zephyr' # Default if build_conf is None |
| 646 | + if build_conf: |
| 647 | + kernel_name = build_conf.get('CONFIG_KERNEL_BIN_NAME', 'zephyr') |
| 648 | + in_bin = b / 'zephyr' / f'{kernel_name}.bin.rps' |
| 649 | + out_bin = args.sbin or str(b / 'zephyr' / 'zephyr.bin.rps') |
| 650 | + if not in_bin.is_file(): |
| 651 | + command.die(f"no unsigned .bin found at {in_bin}") |
| 652 | + # Retrieve values from .west/config [sign.customtool] |
| 653 | + m4_ota_key = config.get('sign.customtool', 'm4-ota-key', fallback=None) |
| 654 | + m4_private_key = config.get('sign.customtool', 'm4-private-key', fallback=None) |
| 655 | + tool_path_rel = config.get('sign.customtool', 'tool-path', fallback=None) |
| 656 | + # Validate required values |
| 657 | + if not m4_ota_key: |
| 658 | + command.die("Missing 'm4-ota-key' in .west/config [sign.customtool] section") |
| 659 | + if not m4_private_key: |
| 660 | + command.die("Missing 'm4-private-key' in .west/config [sign.customtool] section") |
| 661 | + if not tool_path_rel: |
| 662 | + command.die("Missing 'tool-path' in .west/config [sign.customtool] section") |
| 663 | + # Resolve tool-path relative to workspace root (directory containing .west/) |
| 664 | + tool_path = os.path.abspath(os.path.join(os.environ['PWD'], tool_path_rel)) |
| 665 | + # Debug output to verify path |
| 666 | + if not args.quiet: |
| 667 | + command.inf(f"Resolved tool_path: {tool_path}") |
| 668 | + # Ensure tool_path is executable |
| 669 | + if not os.path.isfile(tool_path) or not os.access(tool_path, os.X_OK): |
| 670 | + command.die(f"Tool path {tool_path} is not a valid executable file") |
| 671 | + load_rps_command = [ |
| 672 | + sys.executable, tool_path, |
| 673 | + '--input', str(in_bin), |
| 674 | + '--output', out_bin, |
| 675 | + '--m4_ota_key', m4_ota_key, |
| 676 | + '--m4_private_key', m4_private_key, |
| 677 | + ] + args.tool_args |
| 678 | + if not args.quiet: |
| 679 | + command.inf(f"Running signing command: {' '.join(load_rps_command)}") |
| 680 | + try: |
| 681 | + subprocess.check_call(load_rps_command, stdout=subprocess.PIPE if args.quiet else None) |
| 682 | + except subprocess.CalledProcessError as e: |
| 683 | + command.die(f"Signing failed with exit code {e.returncode}") |
0 commit comments