diff --git a/doc/develop/west/zephyr-cmds.rst b/doc/develop/west/zephyr-cmds.rst index f4b039fa03882..47e1739051ff7 100644 --- a/doc/develop/west/zephyr-cmds.rst +++ b/doc/develop/west/zephyr-cmds.rst @@ -252,6 +252,10 @@ You can dump all of the descriptors in an image using:: west bindesc dump build/zephyr/zephyr.bin +You can extract the descriptor data area of the image to a file using:: + + west bindesc extract + You can list all known standard descriptor names using:: west bindesc list diff --git a/scripts/west_commands/bindesc.py b/scripts/west_commands/bindesc.py index 378072b2f610b..38c56477e7604 100644 --- a/scripts/west_commands/bindesc.py +++ b/scripts/west_commands/bindesc.py @@ -120,6 +120,16 @@ def do_add_parser(self, parser_adder): help='Target CPU is big endian') dump_parser.set_defaults(subcmd='dump', big_endian=False) + extract_parser = subparsers.add_parser('extract', + help='Extract the binary descriptor blob to a file') + extract_parser.add_argument('file', type=str, help='Executable file') + extract_parser.add_argument('out_file', type=str, help='Bindesc binary dump file') + extract_parser.add_argument('--file-type', type=str, choices=self.EXTENSIONS, + help='Input file type') + extract_parser.add_argument('-b', '--big-endian', action='store_true', + help='Target CPU is big endian') + extract_parser.set_defaults(subcmd='extract', big_endian=False) + search_parser = subparsers.add_parser('search', help='Search for a specific descriptor') search_parser.add_argument('descriptor', type=str, help='Descriptor name') search_parser.add_argument('file', type=str, help='Executable file') @@ -204,6 +214,29 @@ def get_offset(self, args): self.die('Could not find binary descriptor magic') self.inf(f'{index} {hex(index)}') + def extract(self, args): + image = self.get_image_data(args.file) + + magic = struct.pack('>Q' if self.is_big_endian else 'Q', self.MAGIC) + index = image.find(magic) + if index == -1: + self.die('Could not find binary descriptor magic') + + index += len(magic) # index points to first descriptor + block_start = index + current_tag = self.bytes_to_short(image[index:index+2]) + while current_tag != self.DESCRIPTORS_END: + index += 2 # index points to length + length = self.bytes_to_short(image[index:index+2]) + # go to next tag + index = self.align(index + 2 + length, 4) + current_tag = self.bytes_to_short(image[index:index+2]) + block_len = index - block_start + + with open(args.out_file, 'wb') as out_file: + out_file.write(image[block_start:index]) + self.inf(f'{block_start}+{block_len} {hex(block_start)}+{hex(block_len)}') + def do_run(self, args, _): if MISSING_REQUIREMENTS: raise RuntimeError('one or more Python dependencies were missing; '