def main():
    args = parser.parse_args()
    base_hex = IntelHex()
    # Merge in hex files
    for file_name in args.hex:
        file_name = os.path.expanduser(file_name)
        new_hex_data = IntelHex()
        print "opening file %s" % file_name
        new_hex_data.fromfile(file_name, format='hex')
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Merge in binary files
    for file_name, addr_str in args.bin:
        file_name = os.path.expanduser(file_name)
        offset = int(addr_str, 0)
        new_hex_data = IntelHex()
        new_hex_data.loadbin(file_name, offset=offset)
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Write out data
    print_hex_info(os.path.expanduser(args.output_file), base_hex)
    with open(os.path.expanduser(args.output_file), 'wb') as output_file:
        base_hex.tofile(output_file, 'hex')
    if args.output_bin_file is not None:
        with open(os.path.expanduser(args.output_bin_file), 'wb') as output_file:
            base_hex.tofile(output_file, 'bin')
Example #2
0
    def binary_hook(t_self, resources, _, binf):
        """Hook that merges the soft device with the bin file"""
        # Scan to find the actual paths of soft device
        sdf = None
        for softdevice_and_offset_entry\
            in t_self.target.EXPECTED_SOFTDEVICES_WITH_OFFSETS:
            for hexf in resources.hex_files:
                if hexf.find(softdevice_and_offset_entry['name']) != -1:
                    t_self.notify.debug("SoftDevice file found %s." %
                                        softdevice_and_offset_entry['name'])
                    sdf = hexf

                if sdf is not None:
                    break
            if sdf is not None:
                break

        if sdf is None:
            t_self.notify.debug("Hex file not found. Aborting.")
            return

        # Look for bootloader file that matches this soft device or bootloader
        # override image
        blf = None
        if t_self.target.MERGE_BOOTLOADER is True:
            for hexf in resources.hex_files:
                if hexf.find(t_self.target.OVERRIDE_BOOTLOADER_FILENAME) != -1:
                    t_self.notify.debug(
                        "Bootloader file found %s." %
                        t_self.target.OVERRIDE_BOOTLOADER_FILENAME)
                    blf = hexf
                    break
                elif hexf.find(softdevice_and_offset_entry['boot']) != -1:
                    t_self.notify.debug("Bootloader file found %s." %
                                        softdevice_and_offset_entry['boot'])
                    blf = hexf
                    break

        # Merge user code with softdevice
        from intelhex import IntelHex
        binh = IntelHex()
        _, ext = os.path.splitext(binf)
        if ext == ".hex":
            binh.loadhex(binf)
        elif ext == ".bin":
            binh.loadbin(binf, softdevice_and_offset_entry['offset'])

        if t_self.target.MERGE_SOFT_DEVICE is True:
            t_self.notify.debug("Merge SoftDevice file %s" %
                                softdevice_and_offset_entry['name'])
            sdh = IntelHex(sdf)
            binh.merge(sdh)

        if t_self.target.MERGE_BOOTLOADER is True and blf is not None:
            t_self.notify.debug("Merge BootLoader file %s" % blf)
            blh = IntelHex(blf)
            binh.merge(blh)

        with open(binf.replace(".bin", ".hex"), "w") as fileout:
            binh.write_hex_file(fileout, write_start_addr=False)
Example #3
0
    def binary_hook(t_self, resources, elf, binf):
        # Scan to find the actual paths of soft device and bootloader files
        sdf = None
        blf = None
        for hexf in resources.hex_files:
            if hexf.find(t_self.target.EXPECTED_BOOTLOADER_FILENAME) != -1:
                blf = hexf
            else:
                for softdeviceAndOffsetEntry in t_self.target.EXPECTED_SOFTDEVICES_WITH_OFFSETS:
                    if hexf.find(softdeviceAndOffsetEntry['name']) != -1:
                        sdf = hexf
                        break

        if sdf is None:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Merge user code with softdevice
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=softdeviceAndOffsetEntry['offset'])

        if t_self.target.MERGE_SOFT_DEVICE is True:
            t_self.debug("Merge SoftDevice file %s" % softdeviceAndOffsetEntry['name'])
            sdh = IntelHex(sdf)
            binh.merge(sdh)

        if t_self.target.MERGE_BOOTLOADER is True and blf is not None:
            t_self.debug("Merge BootLoader file %s" % t_self.target.EXPECTED_BOOTLOADER_FILENAME)
            blh = IntelHex(blf)
            binh.merge(blh)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            binh.tofile(f, format='hex')
Example #4
0
    def binary_hook(t_self, resources, elf, binf):
        for hexf in resources.hex_files:
            found = False
            for softdeviceAndOffsetEntry in NRF51822.EXPECTED_SOFTDEVICES_WITH_OFFSETS:
                if hexf.find(softdeviceAndOffsetEntry['name']) != -1:
                    found = True
                    break
            if found:
                break
        else:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Merge user code with softdevice
        t_self.debug("Patching Hex file %s" % softdeviceAndOffsetEntry['name'])
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=softdeviceAndOffsetEntry['offset'])

        if t_self.target.MERGE_SOFT_DEVICE is True:
            sdh = IntelHex(hexf)
            binh.merge(sdh)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            binh.tofile(f, format='hex')
Example #5
0
def main(file, port, baud, start, delay, run, entry, compact):
    """
    Send a code file to an ELF computer with MAX binary loader.

    The specified file is sent to an attached ELF computer over
    the named serial port. The input file can be an Intel 8-bit
    HEX file or a binary file. For a binary file, the starting
    address may be specified by the 'start' option.
    """
    intel_hex = IntelHex()
    try:
        intel_hex.loadhex(file)
    except (IntelHexError, UnicodeDecodeError):
        intel_hex.loadbin(file, offset=start)

    delay /= 1000

    with serial.serial_for_url(port) as ser:
        ser.baudrate = baud

        send_segments(intel_hex, ser, delay, compact)

        if run:
            if entry is None:
                entry = intel_hex.segments()[0][0]
            run_program(ser, entry, delay)
        else:
            end_transfer(ser)
Example #6
0
    def binary_hook(t_self, resources, elf, binf):
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=0)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            binh.tofile(f, format='hex')
Example #7
0
    def binary_hook(t_self, resources, elf, binf):
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset = 0)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            binh.tofile(f, format='hex')
Example #8
0
def main():
    args = parser.parse_args()
    base_hex = IntelHex()
    # Merge in hex files
    for file_name in args.hex:
        file_name = os.path.expanduser(file_name)
        new_hex_data = IntelHex()
        print "opening file %s" % file_name
        new_hex_data.fromfile(file_name, format='hex')
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Merge in binary files
    for file_name, addr_str in args.bin:
        file_name = os.path.expanduser(file_name)
        offset = int(addr_str, 0)
        new_hex_data = IntelHex()
        new_hex_data.loadbin(file_name, offset=offset)
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Write out data
    print_hex_info(os.path.expanduser(args.output_file), base_hex)
    with open(os.path.expanduser(args.output_file), 'wb') as output_file:
        base_hex.tofile(output_file, 'hex')
    if args.output_bin_file is not None:
        with open(os.path.expanduser(args.output_bin_file),
                  'wb') as output_file:
            base_hex.tofile(output_file, 'bin')
Example #9
0
    def binary_hook(t_self, resources, elf, binf):
        # Scan to find the actual paths of soft device and bootloader files
        sdf = None
        blf = None
        for hexf in resources.hex_files:
            if hexf.find(t_self.target.EXPECTED_BOOTLOADER_FILENAME) != -1:
                blf = hexf
            else:
                for softdeviceAndOffsetEntry in t_self.target.EXPECTED_SOFTDEVICES_WITH_OFFSETS:
                    if hexf.find(softdeviceAndOffsetEntry['name']) != -1:
                        sdf = hexf
                        break

        if sdf is None:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Merge user code with softdevice
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=softdeviceAndOffsetEntry['offset'])

        if t_self.target.MERGE_SOFT_DEVICE is True:
            t_self.debug("Merge SoftDevice file %s" % softdeviceAndOffsetEntry['name'])
            sdh = IntelHex(sdf)
            binh.merge(sdh)

        if t_self.target.MERGE_BOOTLOADER is True and blf is not None:
            t_self.debug("Merge BootLoader file %s" % t_self.target.EXPECTED_BOOTLOADER_FILENAME)
            blh = IntelHex(blf)
            binh.merge(blh)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            binh.tofile(f, format='hex')
Example #10
0
def load_hex():
    """
    Load hex or binary file.
    :return:    intelhex object
    """
    if args.verbose:
        print("Loading %s..." % args.source)

    try:
        ih = IntelHex()

        if args.format == "hex":
            ih.loadhex(args.source)
        else:
            ih.loadbin(args.source, args.start_addr)

    except Exception as e:
        print(e)
        exit(1)

    if args.verbose:
        print("  Start: 0x%08x" % ih.minaddr())
        print("  End  : 0x%08x" % ih.maxaddr())

    return ih
Example #11
0
    def binary_hook(t_self, resources, elf, binf):
        for hexf in resources.hex_files:
            found = False
            for softdeviceAndOffsetEntry in NRF51822.EXPECTED_SOFTDEVICES_WITH_OFFSETS:
                if hexf.find(softdeviceAndOffsetEntry['name']) != -1:
                    found = True
                    break
            if found:
                break
        else:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Merge user code with softdevice
        t_self.debug("Patching Hex file %s" % softdeviceAndOffsetEntry['name'])
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=softdeviceAndOffsetEntry['offset'])

        if t_self.target.MERGE_SOFT_DEVICE is True:
            sdh = IntelHex(hexf)
            binh.merge(sdh)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            binh.tofile(f, format='hex')
Example #12
0
    def binary_hook(t_self, resources, _, binf):
        """Hook that merges the soft device with the bin file"""
        # Scan to find the actual paths of soft device
        sdf = None
        for softdevice_and_offset_entry\
            in t_self.target.EXPECTED_SOFTDEVICES_WITH_OFFSETS:
            for hexf in resources.hex_files:
                if hexf.find(softdevice_and_offset_entry['name']) != -1:
                    t_self.debug("SoftDevice file found %s."
                                 % softdevice_and_offset_entry['name'])
                    sdf = hexf

                if sdf is not None:
                    break
            if sdf is not None:
                break

        if sdf is None:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Look for bootloader file that matches this soft device or bootloader
        # override image
        blf = None
        if t_self.target.MERGE_BOOTLOADER is True:
            for hexf in resources.hex_files:
                if hexf.find(t_self.target.OVERRIDE_BOOTLOADER_FILENAME) != -1:
                    t_self.debug("Bootloader file found %s."
                                 % t_self.target.OVERRIDE_BOOTLOADER_FILENAME)
                    blf = hexf
                    break
                elif hexf.find(softdevice_and_offset_entry['boot']) != -1:
                    t_self.debug("Bootloader file found %s."
                                 % softdevice_and_offset_entry['boot'])
                    blf = hexf
                    break

        # Merge user code with softdevice
        from intelhex import IntelHex
        binh = IntelHex()
        _, ext = os.path.splitext(binf)
        if ext == ".hex":
            binh.loadhex(binf)
        elif ext == ".bin":
            binh.loadbin(binf, softdevice_and_offset_entry['offset'])

        if t_self.target.MERGE_SOFT_DEVICE is True:
            t_self.debug("Merge SoftDevice file %s"
                         % softdevice_and_offset_entry['name'])
            sdh = IntelHex(sdf)
            binh.merge(sdh)

        if t_self.target.MERGE_BOOTLOADER is True and blf is not None:
            t_self.debug("Merge BootLoader file %s" % blf)
            blh = IntelHex(blf)
            binh.merge(blh)

        with open(binf.replace(".bin", ".hex"), "w") as fileout:
            binh.write_hex_file(fileout, write_start_addr=False)
Example #13
0
    def binary_hook(t_self, resources, elf, binf):
        """Hook that is run after elf is generated"""
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=0)

        with open(binf.replace(".bin", ".hex"), "w") as file_desc:
            binh.tofile(file_desc, format='hex')
    def binary_hook(t_self, resources, elf, binf):
        """Hook that is run after elf is generated"""
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=0)

        with open(binf.replace(".bin", ".hex"), "w") as file_desc:
            binh.tofile(file_desc, format='hex')
Example #15
0
class FormatIntelHex(FormatReader, FormatWriter):
    def __init__(self):
        self.hexinstance = IntelHex()


    def load_file(self, filename=None):
        if filename is None:
            raise FormatError("Filename not specified.")

        file_extension = os.path.splitext(filename)[1][1 : ].lower()

        try:
            if file_extension == "bin":
                self.hexinstance.loadbin(filename)
            else:
                self.hexinstance.loadhex(filename)
        except:
            raise FormatError("Could not open %s file \"%s\"." %
                              (file_extension.upper(), filename))


    def save_file(self, filename):
        if filename is None:
            raise FormatError("Filename not specified.")

        file_extension = os.path.splitext(filename)[1][1 : ].lower()

        try:
            if file_extension == "bin":
                self.hexinstance.tofile(filename, format="bin")
            else:
                self.hexinstance.tofile(filename, format="hex")
        except:
            raise FormatError("Could not save %s file \"%s\"." %
                              (file_extension.upper(), filename))


    def add_section(self, start, data):
        self.hexinstance[start : start + len(data)] = data


    def get_sections(self):
        sections = dict()

        if self.hexinstance.minaddr() is not None:
            sections[None] = FormatIntelHex_Section(self.hexinstance)

        return sections


    @staticmethod
    def get_name():
        return "Intel HEX File Parser"


    @staticmethod
    def get_extensions():
        return ["hex", "eep"]
Example #16
0
def lpc55s69_complete(t_self, non_secure_bin, secure_bin):
    assert os.path.isfile(secure_bin)
    assert os.path.isfile(non_secure_bin)

    ns_hex = IntelHex(non_secure_bin)
    s_hex = IntelHex()
    s_hex.loadbin(secure_bin)

    s_hex.merge(ns_hex, overlap='ignore')
    s_hex.tofile(non_secure_bin, 'hex')
Example #17
0
File: utils.py Project: sg-/mbed-os
def intelhex_offset(filename, offset):
    """Load a hex or bin file at a particular offset"""
    _, inteltype = splitext(filename)
    ih = IntelHex()
    if inteltype == ".bin":
        ih.loadbin(filename, offset=offset)
    elif inteltype == ".hex":
        ih.loadhex(filename)
    else:
        raise ToolException("File %s does not have a known binary file type"
                            % filename)
    return ih
Example #18
0
def intelhex_offset(filename, offset):
    """Load a hex or bin file at a particular offset"""
    _, inteltype = splitext(filename)
    ih = IntelHex()
    if inteltype == ".bin":
        ih.loadbin(filename, offset=offset)
    elif inteltype == ".hex":
        ih.loadhex(filename)
    else:
        raise ToolException("File %s does not have a known binary file type" %
                            filename)
    return ih
Example #19
0
    def build_target_firmware(self, parent_test):
        """
        Build test firmware for the board

        Login credentials must have been set with set_build_login.
        """
        prebuilt = self._target_dir is not None
        build_login = (self._username is not None and
                       self._password is not None)
        assert prebuilt or build_login
        if prebuilt:
            destdir = self._target_dir
        else:
            destdir = 'tmp'
        build_name = board_id_to_build_target[self.get_board_id()]
        name_base = os.path.normpath(destdir + os.sep + build_name)
        self._target_hex_path = name_base + '.hex'
        self._target_bin_path = name_base + '.bin'
        # Build target test image if a prebuild location is not specified
        if not prebuilt:
            test_info = parent_test.create_subtest('build_target_test_firmware')
            if not os.path.isdir(destdir):
                os.mkdir(destdir)
            # Remove previous build files
            if os.path.isfile(self._target_hex_path):
                os.remove(self._target_hex_path)
            if os.path.isfile(self._target_bin_path):
                os.remove(self._target_bin_path)
            test_info.info('Starting remote build')
            start = time.time()
            built_file = mbedapi.build_repo(self._username, self._password,
                                            TEST_REPO, build_name, destdir)
            stop = time.time()
            test_info.info("Build took %s seconds" % (stop - start))
            extension = os.path.splitext(built_file)[1].lower()
            assert extension == '.hex' or extension == '.bin'
            if extension == '.hex':
                intel_hex = IntelHex(built_file)
                # Only supporting devices with the starting
                # address at 0 currently
                assert intel_hex.minaddr() == 0
                intel_hex.tobinfile(self._target_bin_path)
                os.rename(built_file, self._target_hex_path)
            if extension == '.bin':
                intel_hex = IntelHex()
                intel_hex.loadbin(built_file, offset=0)
                intel_hex.tofile(self._target_hex_path, 'hex')
                os.rename(built_file, self._target_bin_path)
        # Assert that required files are present
        assert os.path.isfile(self._target_hex_path)
        assert os.path.isfile(self._target_bin_path)
        self._target_firmware_present = True
Example #20
0
    def binary_hook(t_self, resources, elf, binf):

        # Scan to find the actual paths of soft device
        sdf = None
        for softdeviceAndOffsetEntry in t_self.target.EXPECTED_SOFTDEVICES_WITH_OFFSETS:
            for hexf in resources.hex_files:
                if hexf.find(softdeviceAndOffsetEntry["name"]) != -1:
                    t_self.debug("SoftDevice file found %s." % softdeviceAndOffsetEntry["name"])
                    sdf = hexf

                if sdf is not None:
                    break
            if sdf is not None:
                break

        if sdf is None:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Look for bootloader file that matches this soft device or bootloader override image
        blf = None
        if t_self.target.MERGE_BOOTLOADER is True:
            for hexf in resources.hex_files:
                if hexf.find(t_self.target.OVERRIDE_BOOTLOADER_FILENAME) != -1:
                    t_self.debug("Bootloader file found %s." % t_self.target.OVERRIDE_BOOTLOADER_FILENAME)
                    blf = hexf
                    break
                elif hexf.find(softdeviceAndOffsetEntry["boot"]) != -1:
                    t_self.debug("Bootloader file found %s." % softdeviceAndOffsetEntry["boot"])
                    blf = hexf
                    break

        # Merge user code with softdevice
        from intelhex import IntelHex

        binh = IntelHex()
        binh.loadbin(binf, offset=softdeviceAndOffsetEntry["offset"])

        if t_self.target.MERGE_SOFT_DEVICE is True:
            t_self.debug("Merge SoftDevice file %s" % softdeviceAndOffsetEntry["name"])
            sdh = IntelHex(sdf)
            binh.merge(sdh)

        if t_self.target.MERGE_BOOTLOADER is True and blf is not None:
            t_self.debug("Merge BootLoader file %s" % blf)
            blh = IntelHex(blf)
            binh.merge(blh)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            binh.tofile(f, format="hex")
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr,
            output_fn, version, no_bootloader):
    # read bootloader
    bootloader_format = bootloader_fn.split('.')[-1]
    bootloader = IntelHex()
    if not no_bootloader:
        if bootloader_format == 'hex':
            bootloader.fromfile(bootloader_fn, bootloader_format)
        elif bootloader_format == 'bin':
            bootloader.loadbin(bootloader_fn, bootloader_addr)
        else:
            print('Bootloader format can only be .bin or .hex')
            exit(-1)

    # read application
    app_format = app_fn.split('.')[-1]
    app = IntelHex()
    if app_format == 'hex':
        app.fromfile(app_fn, app_format)
    elif app_format == 'bin':
        app.loadbin(app_fn, app_addr)
    else:
        print('Application format can only be .bin or .hex')
        exit(-1)

    # create firmware header
    header = IntelHex()
    fw_header = create_header(app.tobinstr(), version)
    header.puts(hdr_addr, fw_header)

    # combine
    output_format = output_fn.split('.')[-1]
    output = IntelHex()
    if not no_bootloader:
        print("Writing bootloader to address 0x%08x-0x%08x." %
              (bootloader.addresses()[0], bootloader.addresses()[-1]))
        output.merge(bootloader, overlap='error')
    print("Writing header to address 0x%08x-0x%08x." %
          (header.addresses()[0], header.addresses()[-1]))
    output.merge(header, overlap='error')
    print("Writing application to address 0x%08x-0x%08x." %
          (app.addresses()[0], app.addresses()[-1]))
    output.merge(app, overlap='error')

    # write output file
    output.tofile(output_fn, format=output_format)
Example #22
0
def build_target_bundle(directory, username, password, parent_test=None):
    """Build target firmware package"""
    if parent_test is None:
        parent_test = TestInfoStub()
    target_names = info.TARGET_NAME_TO_BOARD_ID.keys()
    for build_name in target_names:
        name_base = os.path.normpath(directory + os.sep + build_name)
        target_hex_path = name_base + '.hex'
        target_bin_path = name_base + '.bin'

        # Build target test image
        test_info = parent_test.create_subtest('Building target %s' %
                                               build_name)
        if not os.path.isdir(directory):
            os.mkdir(directory)
        # Remove previous build files
        if os.path.isfile(target_hex_path):
            os.remove(target_hex_path)
        if os.path.isfile(target_bin_path):
            os.remove(target_bin_path)
        test_info.info('Starting remote build')
        start = time.time()
        built_file = mbedapi.build_repo(username, password,
                                        TEST_REPO, build_name,
                                        directory)
        stop = time.time()
        test_info.info("Build took %s seconds" % (stop - start))
        extension = os.path.splitext(built_file)[1].lower()
        assert extension == '.hex' or extension == '.bin'
        if extension == '.hex':
            intel_hex = IntelHex(built_file)
            # Only supporting devices with the starting
            # address at 0 currently
            assert intel_hex.minaddr() == 0
            intel_hex.tobinfile(target_bin_path)
            os.rename(built_file, target_hex_path)
        if extension == '.bin':
            intel_hex = IntelHex()
            intel_hex.loadbin(built_file, offset=0)
            intel_hex.tofile(target_hex_path, 'hex')
            os.rename(built_file, target_bin_path)

        # Assert that required files are present
        assert os.path.isfile(target_hex_path)
        assert os.path.isfile(target_bin_path)
Example #23
0
def build_target_bundle(directory, username, password, parent_test=None):
    """Build target firmware package"""
    if parent_test is None:
        parent_test = TestInfoStub()
    target_names = info.TARGET_WITH_COMPILE_API_LIST
    for build_name in target_names:
        name_base = os.path.normpath(directory + os.sep + build_name)
        target_hex_path = name_base + '.hex'
        target_bin_path = name_base + '.bin'

        # Build target test image
        test_info = parent_test.create_subtest('Building target %s' %
                                               build_name)
        if not os.path.isdir(directory):
            os.mkdir(directory)
        # Remove previous build files
        if os.path.isfile(target_hex_path):
            os.remove(target_hex_path)
        if os.path.isfile(target_bin_path):
            os.remove(target_bin_path)
        test_info.info('Starting remote build')
        start = time.time()
        built_file = mbedapi.build_repo(username, password,
                                        TEST_REPO, build_name,
                                        directory)
        stop = time.time()
        test_info.info("Build took %s seconds" % (stop - start))
        extension = os.path.splitext(built_file)[1].lower()
        assert extension == '.hex' or extension == '.bin'
        if extension == '.hex':
            intel_hex = IntelHex(built_file)
            # Only supporting devices with the starting
            # address at 0 currently
            assert intel_hex.minaddr() == 0
            intel_hex.tobinfile(target_bin_path)
            os.rename(built_file, target_hex_path)
        if extension == '.bin':
            intel_hex = IntelHex()
            intel_hex.loadbin(built_file, offset=0)
            intel_hex.tofile(target_hex_path, 'hex')
            os.rename(built_file, target_bin_path)

        # Assert that required files are present
        assert os.path.isfile(target_hex_path)
        assert os.path.isfile(target_bin_path)
Example #24
0
    def binary_hook(t_self, resources, elf, binf):
        for hexf in resources.hex_files:
            if hexf.find(NRF51822.EXPECTED_SOFTDEVICE) != -1:
                break
        else:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Merge user code with softdevice
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset = NRF51822.APPCODE_OFFSET)

        sdh = IntelHex(hexf)
        sdh.merge(binh)

        with open(binf.replace(".bin", ".hex"), "w") as f:
           sdh.tofile(f, format = 'hex')
Example #25
0
    def binary_hook(t_self, resources, elf, binf):
        for hexf in resources.hex_files:
            if hexf.find(NRF51822.EXPECTED_SOFTDEVICE) != -1:
                break
        else:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Merge user code with softdevice
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=NRF51822.APPCODE_OFFSET)

        sdh = IntelHex(hexf)
        sdh.merge(binh)

        with open(binf.replace(".bin", ".hex"), "w") as f:
            sdh.tofile(f, format='hex')
Example #26
0
def load_hex():
    """
    Load hex or binary file.
    :return:    intelhex object
    """
    if args.verbose:
        print "Loading %s..." % args.source

    try:
        ih = IntelHex()

        if args.format == "hex":
            ih.loadhex(args.source)
        else:
            ih.loadbin(args.source, args.start_addr)

    except Exception, e:
        print e
        exit(1)
Example #27
0
def load_hex():
    """
    Load hex or binary file.
    :return:    intelhex object
    """
    if args.verbose:
        print "Loading %s..." % args.source

    try:
        ih = IntelHex()

        if args.format == "hex":
            ih.loadhex(args.source)
        else:
            ih.loadbin(args.source, args.start_addr)

    except Exception, e:
        print e
        exit(1)
Example #28
0
def combine(bootloader_fn, app_fn, app_addr, hdr_addr, bootloader_addr,
            output_fn, version, no_bootloader):
    ih = IntelHex()

    bootloader_format = bootloader_fn.split('.')[-1]

    # write the bootloader
    if not no_bootloader:
        print("Using bootloader %s" % bootloader_fn)
        if bootloader_format == 'hex':
            print("Loading bootloader from hex file.")
            ih.fromfile(bootloader_fn, format=bootloader_format)
        elif bootloader_format == 'bin':
            print("Loading bootloader to address 0x%08x." % bootloader_addr)
            ih.loadbin(bootloader_fn, offset=bootloader_addr)
        else:
            print('Bootloader format can only be .bin or .hex')
            exit(-1)

    # write firmware header
    app_format = app_fn.split('.')[-1]
    if app_format == 'bin':
        with open(app_fn, 'rb') as fd:
            app_blob = fd.read()
    elif app_format == 'hex':
        application = IntelHex(app_fn)
        app_blob = application.tobinstr()
    FirmwareHeader = create_header(app_blob, version)
    print("Writing header to address 0x%08x." % hdr_addr)
    ih.puts(hdr_addr, FirmwareHeader)

    # write the application
    if app_format == 'bin':
        print("Loading application to address 0x%08x." % app_addr)
        ih.loadbin(app_fn, offset=app_addr)
    elif app_format == 'hex':
        print("Loading application from hex file")
        ih.fromfile(app_fn, format=app_format)

    # output to file
    ih.tofile(output_fn, format=output_fn.split('.')[-1])
Example #29
0
def main():
    args = parser.parse_args()
    base_hex = IntelHex()
    # Merge in hex files
    for file_name in args.hex:
        new_hex_data = IntelHex()
        print "opening file %s" % file_name
        new_hex_data.fromfile(file_name, format='hex')
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Merge in binary files
    for file_name, addr_str in args.bin:
        offset = int(addr_str, 0)
        new_hex_data = IntelHex()
        new_hex_data.loadbin(file_name, offset=offset)
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Write out data
    print_hex_info(args.output_file, base_hex)
    with open(args.output_file, 'wb') as output_file:
        base_hex.tofile(output_file, 'hex')
Example #30
0
 def binary_hook(t_self, resources, elf, binf):
     for hexf in resources.hex_files:
         if hexf.find(NRF51822.EXPECTED_SOFTDEVICE) != -1:
             break
     else:
         t_self.debug("Hex file not found. Aborting.")
         return
     
     # Merge user code with softdevice
     from intelhex import IntelHex
     binh = IntelHex()
     binh.loadbin(binf, offset = NRF51822.APPCODE_OFFSET)
     
     sdh = IntelHex(hexf)
     sdh.merge(binh)
     
     # Remove UICR section
     del sdh[NRF51822.UICR_START:NRF51822.UICR_END+1]
     
     with open(binf, "wb") as f:
         sdh.tofile(f, format = 'bin')
Example #31
0
def main():
    args = parser.parse_args()
    base_hex = IntelHex()
    # Merge in hex files
    for file_name in args.hex:
        new_hex_data = IntelHex()
        print "opening file %s" % file_name
        new_hex_data.fromfile(file_name, format='hex')
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Merge in binary files
    for file_name, addr_str in args.bin:
        offset = int(addr_str, 0)
        new_hex_data = IntelHex()
        new_hex_data.loadbin(file_name, offset=offset)
        print_hex_info(file_name, new_hex_data)
        base_hex = merge_hex(base_hex, new_hex_data)
    # Write out data
    print_hex_info(args.output_file, base_hex)
    with open(args.output_file, 'wb') as output_file:
        base_hex.tofile(output_file, 'hex')
Example #32
0
    def binary_hook(t_self, resources, elf, binf):
        for hexf in resources.hex_files:
            if hexf.find(NRF51822.EXPECTED_SOFTDEVICE) != -1:
                break
        else:
            t_self.debug("Hex file not found. Aborting.")
            return

        # Merge user code with softdevice
        from intelhex import IntelHex
        binh = IntelHex()
        binh.loadbin(binf, offset=NRF51822.APPCODE_OFFSET)

        sdh = IntelHex(hexf)
        sdh.merge(binh)

        # Remove UICR section
        del sdh[NRF51822.UICR_START:NRF51822.UICR_END + 1]

        with open(binf, "wb") as f:
            sdh.tofile(f, format='bin')
# Sanity checks, very important
if ih.maxaddr() < 0x1004 or ih.maxaddr() > 32767:
    print "Insane hexfile: min=0x%x max=0x%x" % (ih.minaddr(), ih.maxaddr())
    sys.exit(2)
print "Length: %d / 28672" % (ih.maxaddr() - 4096 + 1)
print "Free: %d" % (28672 - (ih.maxaddr() - 4096 + 1))

# Hack to force tobinstr() to write data from addres 0. IntelHex will
# only write data from the first location with initialized data, skipping
# over any uninitialized data beforehand. This initializes address 0,
# forcing IntelHex to do what I want.
ih[0] = ih[0]

sumdata = (ih.tobinstr())[0x1004:]
sumdata += '\xff' * (0x6ffc - len(sumdata))
cksum = binascii.crc32(sumdata) & 0xffffffff
print "Checksum: 0x%08x" % cksum
ih.puts(0x1000, struct.pack('<L', cksum))

# Rather than using IntelHex.tobinfile(), i'm writing to a file this way
# to ensure that the file ends up at exactly 32768 bytes.
binfw = ih.tobinstr()
binfw += '\xff' * (0x8000 - len(binfw))
out.write(binfw)
out.close()

# Testing only.
a = IntelHex()
a.loadbin(sys.argv[2])
a.write_hex_file(sys.argv[2] + '.hex')
                      ('SD_VERSION', 0x14, _read_sd_version))


if ("__main__" == __name__):
    if (2 == len(sys.argv)):
        file_name = sys.argv[1]
    else:
        print "ERROR: Usage is 'python sd_info_struct.py <file_name>'."
        sys.exit(-1)

    ih = IntelHex()
    try:
        if (file_name.lower().endswith('.hex')):
            ih.loadhex(file_name)
        else:
            ih.loadbin(file_name)
    except:
        print "ERROR: Could not open the data file."
        sys.exit(-1)

    magic_number = _read_u32(ih, (SOFTDEVICE_INFO_STRUCT_ADDRESS + SD_MAGIC_NUMBER_OFFSET))
    if (SD_MAGIC_NUMBER_VALUE != magic_number):
        print "ERROR: SD magic number not found."
        sys.exit(-1)

    print "\nSoftDevice information structure for '%s':" % os.path.basename(file_name)
    for t in INFO_STRUCT_TUPLES:
        print '  {0:<12}{1}'.format(t[0] + ':', t[2](ih, (SOFTDEVICE_INFO_STRUCT_ADDRESS + t[1])))

    sys.exit(0)
Example #35
0
import numpy as np
from intelhex import IntelHex
from datetime import datetime

# -----------------------------------------------------------------------------
if __name__ == '__main__':

    # ...
    sp = serial.Serial(port=sys.argv[1], baudrate=999999999, timeout=0.0001)
    if (sp.isOpen() == True):
        sp.close()
    sp.open()

    # ..
    ih = IntelHex()
    ih.loadbin(sys.argv[2])
    binbuff = ih.todict()

    # ...
    TEST_LEN = 128
    buf = [0] * TEST_LEN
    tmpbuf = [0] * TEST_LEN
    buf = bytearray(buf)
    tmpbuf = bytearray(tmpbuf)

    # Start the process
    tmpbuf[0] = 2
    sp.write(tmpbuf)
    rbuf = sp.read(64)

    # ...
Example #36
0
# Sanity checks, very important
if ih.maxaddr() < 0x1004 or ih.maxaddr() > 32767:
    print "Insane hexfile: min=0x%x max=0x%x" % (ih.minaddr(), ih.maxaddr())
    sys.exit(2)
print "Length: %d / 28672" % (ih.maxaddr() - 4096 + 1)
print "Free: %d" % (28672 - (ih.maxaddr() - 4096 + 1))

# Hack to force tobinstr() to write data from addres 0. IntelHex will 
# only write data from the first location with initialized data, skipping
# over any uninitialized data beforehand. This initializes address 0,
# forcing IntelHex to do what I want.
ih[0]=ih[0]

sumdata = (ih.tobinstr())[0x1004:]
sumdata += '\xff' * (0x6ffc - len(sumdata))
cksum = binascii.crc32(sumdata) & 0xffffffff
print "Checksum: 0x%08x" % cksum
ih.puts(0x1000, struct.pack('<L', cksum))

# Rather than using IntelHex.tobinfile(), i'm writing to a file this way
# to ensure that the file ends up at exactly 32768 bytes.
binfw = ih.tobinstr()
binfw += '\xff' * (0x8000 - len(binfw))
out.write(binfw)
out.close()

# Testing only.
a=IntelHex()
a.loadbin(sys.argv[2])
a.write_hex_file(sys.argv[2] + '.hex')
Example #37
0
def m2354_tfm_bin(t_self, non_secure_image, secure_bin):

    assert os.path.isfile(secure_bin)
    assert os.path.isfile(non_secure_image)

    secure_bin = abspath(secure_bin)
    non_secure_image = abspath(non_secure_image)

    build_dir = dirname(non_secure_image)
    tempdir = path_join(build_dir, 'temp')
    if not isdir(tempdir):
        os.makedirs(tempdir)

    flash_layout = path_join(SECURE_ROOT, 'partition', 'flash_layout.h')

    bl2_bin = path_join(SECURE_ROOT, 'bl2.bin')
    s_bin_basename = splitext(basename(secure_bin))[0]
    ns_bin_basename, output_ext = splitext(basename(non_secure_image))

    # Convert NS image to BIN format if it is HEX
    if output_ext == ".hex":
        non_secure_bin = abspath(path_join(tempdir, ns_bin_basename + ".bin"))
        ns_ih = IntelHex(non_secure_image)
        ns_ih.tobinfile(non_secure_bin)
    else:
        non_secure_bin = non_secure_image

    signing_key = path_join(SCRIPT_DIR, 'nuvoton_m2354-root-rsa-3072.pem')
    assert os.path.isfile(signing_key)

    # Find Python 3 command name across platforms
    python3_cmd = "python3" if shutil.which(
        "python3") is not None else "python"

    # Specify image version
    #
    # MCUboot image version format: Major.Minor.Revision+Build
    #
    # Requirements for image version:
    # 1. Major.Minor.Revision must be non-decremental when used to derive security
    #    counter (-s 'auto').
    # 2. Make Major.Minor.Revision+Build incremental to identify the firmware
    #    itself uniquely through psa_fwu_query().
    # 3. Get around MCUboot failure with:
    #    [INF] Starting bootloader
    #    [INF] Swap type: none
    #    [ERR] Failed to add Image 0 data to shared memory area
    #    [ERR] Unable to find bootable image
    #    This is because TF-M underestimates MAX_BOOT_RECORD_SZ for boot record
    #    where Major.Minor.Revision will pack into during signing. The more digits
    #    of the Major.Minor.Revision, the larger the needed boot record size. And
    #    then MCUboot errors in boot_save_boot_status().
    #
    # To meet all the above requirements, we apply the following policy:
    # 1. To not change MAX_BOOT_RECORD_SZ in TF-M, specify Major.Minor.Revision
    #    with TF-M version instead of modified Unix timestamp. This needs less digits to
    #    fit into MAX_BOOT_RECORD_SZ.
    # 2. To make Major.Minor.Revision+Build incremental, specify the Build part with
    #    modified Unix timestamp.
    # 3. To make security counter non-decremental, we can derive it from
    #    Major.Minor.Revision (-s 'auto') or explicitly specify it with modified
    #    Unix timestamp, depending on security consideration.
    #
    # NOTE: To get around Y2038 problem, we modify Unix timestamp by setting new base
    #       point. Using 32-bit unsigned integer to hold the modified Unix timestamp,
    #       it will break (wrap around) after Y2156 (2106 + 2020 - 1970).
    #       https://en.wikipedia.org/wiki/Year_2038_problem
    #
    modified_timestamp = int(datetime.now().timestamp()) - int(
        datetime(2020, 1, 1).timestamp())
    img_ver_major = 1  # Instead of (modified_timestamp >> 24) & 0xFF
    img_ver_minor = 4  # Instead of (modified_timestamp >> 16) & 0xFF
    img_ver_revision = 0  # Instead of modified_timestamp & 0xFFFF
    img_ver_build = modified_timestamp

    # wrapper.py command template
    cmd_wrapper = [
        python3_cmd,
        path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils",
                  "wrapper.py"),
        "-v",
        "{}.{}.{}+{}".format(img_ver_major, img_ver_minor, img_ver_revision,
                             img_ver_build),
        "-k",
        "SIGNING_KEY_PATH",
        "--layout",
        "IMAGE_MACRO_PATH",
        "--public-key-format",
        'full',
        "--align",
        '1',
        # Reasons for removing padding and boot magic option "--pad":
        # 1. PSA FWU API psa_fwu_install() will be responsible for writing boot magic to enable upgradeable.
        # 2. The image size gets smaller instead of slot size.
        #"--pad",
        "--pad-header",
        "-H",
        '0x400',
        "--overwrite-only",
        "-s",
        'auto',  # Or modified_timestamp
        "-d",
        '(IMAGE_ID,MAJOR.MINOR.REVISION+BUILD)',
        "RAW_BIN_PATH",
        "SIGNED_BIN_PATH",
    ]
    pos_wrapper_signing_key = cmd_wrapper.index("-k") + 1
    pos_wrapper_layout = cmd_wrapper.index("--layout") + 1
    pos_wrapper_dependency = cmd_wrapper.index("-d") + 1
    pos_wrapper_raw_bin = len(cmd_wrapper) - 2
    pos_wrapper_signed_bin = len(cmd_wrapper) - 1

    # assemble.py command template
    cmd_assemble = [
        python3_cmd,
        path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils",
                  "assemble.py"),
        "--layout",
        "IMAGE_MACRO_PATH",
        "-s",
        "SECURE_BIN_PATH",
        "-n",
        "NONSECURE_BIN_PATH",
        "-o",
        "CONCATENATED_BIN_PATH",
    ]
    pos_assemble_layout = cmd_assemble.index("--layout") + 1
    pos_assemble_secure_bin = cmd_assemble.index("-s") + 1
    pos_assemble_nonsecure_bin = cmd_assemble.index("-n") + 1
    pos_assemble_concat_bin = cmd_assemble.index("-o") + 1

    # If second signing key is passed down, go signing separately; otherwise, go signing together.
    if os.path.isfile(
            path_join(SECURE_ROOT, 'partition',
                      'signing_layout_ns_preprocessed.h')):
        signing_key_1 = 'nuvoton_m2354-root-rsa-3072_1.pem'
    else:
        signing_key_1 = None

    if signing_key_1 is not None:
        signing_key_1 = path_join(SCRIPT_DIR, signing_key_1)
        assert os.path.isfile(signing_key_1)

        image_macros_s = path_join(SECURE_ROOT, 'partition',
                                   'signing_layout_s_preprocessed.h')
        image_macros_ns = path_join(SECURE_ROOT, 'partition',
                                    'signing_layout_ns_preprocessed.h')
        assert os.path.isfile(image_macros_s)
        assert os.path.isfile(image_macros_ns)

        s_signed_bin = abspath(path_join(tempdir, 'tfm_s_signed' + '.bin'))
        ns_signed_bin = abspath(
            path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed' + '.bin'))
        signed_concat_bin = abspath(
            path_join(
                tempdir,
                'tfm_s_signed_' + ns_bin_basename + '_signed_concat' + '.bin'))
        s_update_bin = abspath(
            path_join(build_dir, s_bin_basename + '_update' + '.bin'))
        ns_update_bin = abspath(
            path_join(build_dir, ns_bin_basename + '_update' + '.bin'))

        #1. Run wrapper to sign the secure TF-M binary
        cmd_wrapper[pos_wrapper_signing_key] = signing_key
        cmd_wrapper[pos_wrapper_layout] = image_macros_s
        cmd_wrapper[
            pos_wrapper_dependency] = '(1,0.0.0+0)'  # Minimum version of non-secure image required for upgrading to the secure image
        cmd_wrapper[pos_wrapper_raw_bin] = secure_bin
        cmd_wrapper[pos_wrapper_signed_bin] = s_signed_bin

        retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to sign " + "TF-M Secure" +
                            " binary, Error code: " + str(retcode))
            return

        #2. Run wrapper to sign the non-secure mbed binary
        cmd_wrapper[pos_wrapper_signing_key] = signing_key_1
        cmd_wrapper[pos_wrapper_layout] = image_macros_ns
        cmd_wrapper[
            pos_wrapper_dependency] = '(0,0.0.0+0)'  # Minimum version of secure image required for upgrading to the non-secure image
        cmd_wrapper[pos_wrapper_raw_bin] = non_secure_bin
        cmd_wrapper[pos_wrapper_signed_bin] = ns_signed_bin

        retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to sign " + "TF-M Secure" +
                            " binary, Error code: " + str(retcode))
            return

        #3. Concatenate signed secure TF-M binary and signed non-secure mbed binary
        cmd_assemble[pos_assemble_layout] = image_macros_s
        cmd_assemble[pos_assemble_secure_bin] = s_signed_bin
        cmd_assemble[pos_assemble_nonsecure_bin] = ns_signed_bin
        cmd_assemble[pos_assemble_concat_bin] = signed_concat_bin

        retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to concatenate " +
                            "Secure TF-M (signed)/Non-secure Mbed (signed)" +
                            " binaries, Error code: " + str(retcode))
            return

        #4. Concatenate MCUboot and concatenated signed secure TF-M binary/signed non-secure mbed binary
        flash_area_0_offset = find_flash_area_0_offset(flash_layout)
        out_ih = IntelHex()
        out_ih.loadbin(bl2_bin)
        out_ih.loadbin(signed_concat_bin, flash_area_0_offset)
        out_ih.tofile(non_secure_image,
                      'hex' if output_ext == ".hex" else "bin")

        # Generate firmware update file for PSA Firmware Update
        shutil.copy(s_signed_bin, s_update_bin)
        shutil.copy(ns_signed_bin, ns_update_bin)
    else:
        image_macros_s_ns = path_join(SECURE_ROOT, 'partition',
                                      'signing_layout_preprocessed.h')
        assert os.path.isfile(image_macros_s_ns)

        concat_bin = abspath(
            path_join(tempdir, 'tfm_s_' + ns_bin_basename + ".bin"))
        concat_signed_bin = abspath(
            path_join(tempdir,
                      'tfm_s_' + ns_bin_basename + '_signed' + ".bin"))
        update_bin = abspath(
            path_join(build_dir, ns_bin_basename + '_update' + '.bin'))

        #1. Concatenate secure TFM and non-secure mbed binaries
        cmd_assemble[pos_assemble_layout] = image_macros_s_ns
        cmd_assemble[pos_assemble_secure_bin] = secure_bin
        cmd_assemble[pos_assemble_nonsecure_bin] = non_secure_bin
        cmd_assemble[pos_assemble_concat_bin] = concat_bin

        retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to concatenate " +
                            "Secure TF-M/Non-secure Mbed" +
                            " binaries, Error code: " + str(retcode))
            return

        #2. Run wrapper to sign the concatenated binary
        cmd_wrapper[pos_wrapper_signing_key] = signing_key
        cmd_wrapper[pos_wrapper_layout] = image_macros_s_ns
        cmd_wrapper[
            pos_wrapper_dependency] = '(1,0.0.0+0)'  # No effect for single image boot
        cmd_wrapper[pos_wrapper_raw_bin] = concat_bin
        cmd_wrapper[pos_wrapper_signed_bin] = concat_signed_bin

        retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to sign " + "concatenated" +
                            " binary, Error code: " + str(retcode))
            return

        #3. Concatenate MCUboot and signed binary
        flash_area_0_offset = find_flash_area_0_offset(flash_layout)
        out_ih = IntelHex()
        out_ih.loadbin(bl2_bin)
        out_ih.loadbin(concat_signed_bin, flash_area_0_offset)
        out_ih.tofile(non_secure_image,
                      'hex' if output_ext == ".hex" else "bin")

        # Generate firmware update file for PSA Firmware Update
        shutil.copy(concat_signed_bin, update_bin)
Example #38
0
#!/usr/bin/env python
#coding: utf-8

from intelhex import IntelHex
import sys

args=sys.argv
if (len(args)!=3):
    print("Usage python bin2ihx.py [binfile] [offset]")

filename=sys.argv[1]
offset=eval(sys.argv[2])

data = IntelHex()

data.loadbin(filename,offset=offset)
outname=filename.replace(".bin",".ihx")

with open(outname,"w") as fw:
    data.write_hex_file(fw)

Example #39
0
def tfm_sign_image_tgt(tfm_import_path, signing_key, non_secure_bin):

    SECURE_ROOT = abspath(tfm_import_path)

    secure_bin = path_join(SECURE_ROOT, 'tfm_s.bin') 
    assert os.path.isfile(secure_bin)

    non_secure_bin = abspath(non_secure_bin)
    assert os.path.isfile(non_secure_bin)

    build_dir = dirname(non_secure_bin)
    tempdir = path_join(build_dir, 'temp')
    if not isdir(tempdir):
        os.makedirs(tempdir)

    flash_layout = path_join(SECURE_ROOT, 'partition', 'flash_layout.h')

    bl2_bin = path_join(SECURE_ROOT, 'bl2.bin')
    image_macros_s_ns = path_join(SECURE_ROOT, 'partition', 'signing_layout_preprocessed.h')
    ns_bin_basename = splitext(basename(non_secure_bin))[0]
    concatenated_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + ".bin"))
    signed_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed' + ".bin"))
    signed_nopad_bin = abspath(path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed_nopad' + ".bin"))

    assert os.path.isfile(image_macros_s_ns)

    signing_key = path_join(SECURE_ROOT, 'signing_key', signing_key)
    assert os.path.isfile(signing_key)

    # Find Python 3 command name across platforms
    python3_cmd = "python3" if shutil.which("python3") is not None else "python"

    #1. Concatenate secure TFM and non-secure mbed binaries
    cmd = [
        python3_cmd,
        path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils", "assemble.py"),
        "--layout",
        image_macros_s_ns,
        "-s",
        secure_bin,
        "-n",
        non_secure_bin,
        "-o",
        concatenated_bin,
    ]

    retcode = run_cmd(cmd, MBED_OS_ROOT)
    if retcode:
        raise Exception("Unable to concatenate " + "TF-M Secure/Mbed Non-secure" +
                            " binaries, Error code: " + str(retcode))
        return

    #2.1 Run wrapper to sign the concatenated binary with padding ("--pad"), so upgradeable by mcuboot
    cmd = [
        python3_cmd,
        path_join(MBED_OS_ROOT, "tools", "psa","tfm", "bin_utils", "wrapper.py"),
        "-v",
        '1.2.0',
        "-k",
        signing_key,
        "--layout",
        image_macros_s_ns,
        "--public-key-format",
        'full',
        "--align",
        '1',
        "--pad",
        "--pad-header",
        "-H",
        '0x400',
        "--overwrite-only",
        "-s",
        'auto',
        "-d",
        '(0,0.0.0+0)',
        concatenated_bin,
        signed_bin,
    ]

    retcode = run_cmd(cmd, MBED_OS_ROOT)
    if retcode:
        raise Exception("Unable to sign " + "concatenated" +
                            " binary, Error code: " + str(retcode))
        return

    #2.2. Re-run above but without padding ("--pad"), so non-upgradeable by mcuboot
    cmd.remove("--pad")
    cmd.pop()
    cmd.append(signed_nopad_bin)

    retcode = run_cmd(cmd, MBED_OS_ROOT)
    if retcode:
        raise Exception("Unable to sign " + "concatenated" +
                            " binary, Error code: " + str(retcode))
        return

    #3. Concatenate mcuboot and signed binary and overwrite mbed built bin/hex file
    flash_area_0_offset = find_flash_area_0_offset(flash_layout)
    out_ih = IntelHex()
    out_ih.loadbin(bl2_bin)
    out_ih.loadbin(signed_nopad_bin, flash_area_0_offset)
    out_ih.tofile(splitext(non_secure_bin)[0] + ".hex", 'hex')
    out_ih.tobinfile(non_secure_bin)
Example #40
0
def tfm_sign_image(tfm_import_path, signing_key, signing_key_1,
                   non_secure_bin):
    SECURE_ROOT = abspath(tfm_import_path)

    secure_bin = path_join(SECURE_ROOT, 'tfm_s.bin')
    assert os.path.isfile(secure_bin)

    non_secure_bin = abspath(non_secure_bin)
    assert os.path.isfile(non_secure_bin)

    build_dir = dirname(non_secure_bin)
    tempdir = path_join(build_dir, 'temp')
    if not isdir(tempdir):
        os.makedirs(tempdir)

    flash_layout = path_join(SECURE_ROOT, 'partition', 'flash_layout.h')

    bl2_bin = path_join(SECURE_ROOT, 'bl2.bin')
    s_bin_basename = splitext(basename(secure_bin))[0]
    ns_bin_basename = splitext(basename(non_secure_bin))[0]

    signing_key = path_join(SECURE_ROOT, 'signing_key', signing_key)
    assert os.path.isfile(signing_key)

    # Find Python 3 command name across platforms
    python3_cmd = "python3" if shutil.which(
        "python3") is not None else "python"

    img_ver_major = 1
    img_ver_minor = 3
    img_ver_revision = 0
    img_ver_build = 0

    # wrapper.py command template
    cmd_wrapper = [
        python3_cmd,
        path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils",
                  "wrapper.py"),
        "-v",
        "{}.{}.{}+{}".format(img_ver_major, img_ver_minor, img_ver_revision,
                             img_ver_build),
        "-k",
        "SIGNING_KEY_PATH",
        "--layout",
        "IMAGE_MACRO_PATH",
        "--public-key-format",
        'full',
        "--align",
        '1',
        # Reasons for removing padding and boot magic option "--pad":
        # 1. PSA FWU API psa_fwu_install() will be responsible for writing boot magic to enable upgradeable.
        # 2. The image size gets smaller instead of slot size.
        #"--pad",
        "--pad-header",
        "-H",
        '0x400',
        "--overwrite-only",
        "-s",
        'auto',
        "-d",
        '(IMAGE_ID,MAJOR.MINOR.REVISION+BUILD)',
        "RAW_BIN_PATH",
        "SIGNED_BIN_PATH",
    ]
    pos_wrapper_signing_key = cmd_wrapper.index("-k") + 1
    pos_wrapper_layout = cmd_wrapper.index("--layout") + 1
    pos_wrapper_dependency = cmd_wrapper.index("-d") + 1
    pos_wrapper_raw_bin = len(cmd_wrapper) - 2
    pos_wrapper_signed_bin = len(cmd_wrapper) - 1

    # assemble.py command template
    cmd_assemble = [
        python3_cmd,
        path_join(MBED_OS_ROOT, "tools", "psa", "tfm", "bin_utils",
                  "assemble.py"),
        "--layout",
        "IMAGE_MACRO_PATH",
        "-s",
        "SECURE_BIN_PATH",
        "-n",
        "NONSECURE_BIN_PATH",
        "-o",
        "CONCATENATED_BIN_PATH",
    ]
    pos_assemble_layout = cmd_assemble.index("--layout") + 1
    pos_assemble_secure_bin = cmd_assemble.index("-s") + 1
    pos_assemble_nonsecure_bin = cmd_assemble.index("-n") + 1
    pos_assemble_concat_bin = cmd_assemble.index("-o") + 1

    # If second signing key is passed down, go signing separately; otherwise, go signing together.
    if signing_key_1 is not None:
        signing_key_1 = path_join(SECURE_ROOT, 'signing_key', signing_key_1)
        assert os.path.isfile(signing_key_1)

        image_macros_s = path_join(SECURE_ROOT, 'partition',
                                   'signing_layout_s_preprocessed.h')
        image_macros_ns = path_join(SECURE_ROOT, 'partition',
                                    'signing_layout_ns_preprocessed.h')
        assert os.path.isfile(image_macros_s)
        assert os.path.isfile(image_macros_ns)

        s_signed_bin = abspath(path_join(tempdir, 'tfm_s_signed' + '.bin'))
        ns_signed_bin = abspath(
            path_join(tempdir, 'tfm_' + ns_bin_basename + '_signed' + '.bin'))
        signed_concat_bin = abspath(
            path_join(
                tempdir,
                'tfm_s_signed_' + ns_bin_basename + '_signed_concat' + '.bin'))
        s_update_bin = abspath(
            path_join(build_dir, s_bin_basename + '_update' + '.bin'))
        ns_update_bin = abspath(
            path_join(build_dir, ns_bin_basename + '_update' + '.bin'))

        #1. Run wrapper to sign the secure TF-M binary
        cmd_wrapper[pos_wrapper_signing_key] = signing_key
        cmd_wrapper[pos_wrapper_layout] = image_macros_s
        cmd_wrapper[
            pos_wrapper_dependency] = '(1,0.0.0+0)'  # Minimum version of non-secure image required for upgrading to the secure image
        cmd_wrapper[pos_wrapper_raw_bin] = secure_bin
        cmd_wrapper[pos_wrapper_signed_bin] = s_signed_bin

        retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to sign " + "TF-M Secure" +
                            " binary, Error code: " + str(retcode))
            return

        #2. Run wrapper to sign the non-secure mbed binary
        cmd_wrapper[pos_wrapper_signing_key] = signing_key_1
        cmd_wrapper[pos_wrapper_layout] = image_macros_ns
        cmd_wrapper[
            pos_wrapper_dependency] = '(0,0.0.0+0)'  # Minimum version of secure image required for upgrading to the non-secure image
        cmd_wrapper[pos_wrapper_raw_bin] = non_secure_bin
        cmd_wrapper[pos_wrapper_signed_bin] = ns_signed_bin

        retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to sign " + "TF-M Secure" +
                            " binary, Error code: " + str(retcode))
            return

        #3. Concatenate signed secure TF-M binary and signed non-secure mbed binary
        cmd_assemble[pos_assemble_layout] = image_macros_s
        cmd_assemble[pos_assemble_secure_bin] = s_signed_bin
        cmd_assemble[pos_assemble_nonsecure_bin] = ns_signed_bin
        cmd_assemble[pos_assemble_concat_bin] = signed_concat_bin

        retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to concatenate " +
                            "Secure TF-M (signed)/Non-secure Mbed (signed)" +
                            " binaries, Error code: " + str(retcode))
            return

        #4. Concatenate MCUboot and concatenated signed secure TF-M binary/signed non-secure mbed binary
        flash_area_0_offset = find_flash_area_0_offset(flash_layout)
        out_ih = IntelHex()
        out_ih.loadbin(bl2_bin)
        out_ih.loadbin(signed_concat_bin, flash_area_0_offset)
        out_ih.tofile(splitext(non_secure_bin)[0] + ".hex", 'hex')
        out_ih.tobinfile(non_secure_bin)

        # Generate firmware update file for PSA Firmware Update
        shutil.copy(s_signed_bin, s_update_bin)
        shutil.copy(ns_signed_bin, ns_update_bin)
    else:
        image_macros_s_ns = path_join(SECURE_ROOT, 'partition',
                                      'signing_layout_preprocessed.h')
        assert os.path.isfile(image_macros_s_ns)

        concat_bin = abspath(
            path_join(tempdir, 'tfm_s_' + ns_bin_basename + ".bin"))
        concat_signed_bin = abspath(
            path_join(tempdir,
                      'tfm_s_' + ns_bin_basename + '_signed' + ".bin"))
        update_bin = abspath(
            path_join(build_dir, ns_bin_basename + '_update' + '.bin'))

        #1. Concatenate secure TFM and non-secure mbed binaries
        cmd_assemble[pos_assemble_layout] = image_macros_s_ns
        cmd_assemble[pos_assemble_secure_bin] = secure_bin
        cmd_assemble[pos_assemble_nonsecure_bin] = non_secure_bin
        cmd_assemble[pos_assemble_concat_bin] = concat_bin

        retcode = run_cmd(cmd_assemble, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to concatenate " +
                            "Secure TF-M/Non-secure Mbed" +
                            " binaries, Error code: " + str(retcode))
            return

        #2. Run wrapper to sign the concatenated binary
        cmd_wrapper[pos_wrapper_signing_key] = signing_key
        cmd_wrapper[pos_wrapper_layout] = image_macros_s_ns
        cmd_wrapper[
            pos_wrapper_dependency] = '(1,0.0.0+0)'  # No effect for single image boot
        cmd_wrapper[pos_wrapper_raw_bin] = concat_bin
        cmd_wrapper[pos_wrapper_signed_bin] = concat_signed_bin

        retcode = run_cmd(cmd_wrapper, MBED_OS_ROOT)
        if retcode:
            raise Exception("Unable to sign " + "concatenated" +
                            " binary, Error code: " + str(retcode))
            return

        #3. Concatenate MCUboot and signed binary
        flash_area_0_offset = find_flash_area_0_offset(flash_layout)
        out_ih = IntelHex()
        out_ih.loadbin(bl2_bin)
        out_ih.loadbin(concat_signed_bin, flash_area_0_offset)
        out_ih.tofile(splitext(non_secure_bin)[0] + ".hex", 'hex')
        out_ih.tobinfile(non_secure_bin)

        # Generate firmware update file for PSA Firmware Update
        shutil.copy(concat_signed_bin, update_bin)