예제 #1
0
    def generate(self, arch, app_file, app_ver, bl_ver, bl_sett_ver, custom_bl_sett_addr):
        """
        Populates the settings object based on the given parameters.

        :param arch: Architecture family string, e.g. NRF51
        :param app_file: Path to application file
        :param app_ver: Application version number
        :param bl_ver: Bootloader version number
        :param bl_sett_ver: Bootloader settings version number
        :param custom_bl_sett_addr: Custom start address for the settings page
        :return:
        """

        # Set the architecture
        self.set_arch(arch)

        if custom_bl_sett_addr is not None:
            self.bl_sett_addr = custom_bl_sett_addr

        if bl_sett_ver == 1:
            self.setts = BLDFUSettingsStructV1()
        else:
            raise NordicSemiException("Unknown bootloader settings version")

        self.bl_sett_ver = bl_sett_ver & 0xffffffff
        self.bl_ver = bl_ver & 0xffffffff

        if app_ver is not None:
            self.app_ver = app_ver & 0xffffffff
        else:
            self.app_ver = 0x0 & 0xffffffff

        if app_file is not None:
            # load application to find out size and CRC
            self.temp_dir = tempfile.mkdtemp(prefix="nrf_dfu_bl_sett_")
            self.app_bin = Package.normalize_firmware_to_bin(self.temp_dir, app_file)

            # calculate application size and CRC32
            self.app_sz = int(Package.calculate_file_size(self.app_bin)) & 0xffffffff
            self.app_crc = int(Package.calculate_crc(32, self.app_bin)) & 0xffffffff
            self.bank0_bank_code = 0x1 & 0xffffffff
        else:
            self.app_sz = 0x0 & 0xffffffff
            self.app_crc = 0x0 & 0xffffffff
            self.bank0_bank_code = 0x0 & 0xffffffff

        # build the uint32_t array
        arr = [0x0] * self.setts.uint32_count

        # additional harcoded values
        self.bank_layout = 0x0 & 0xffffffff
        self.bank_current = 0x0 & 0xffffffff

        # fill in the settings
        arr[self.setts.offs_sett_ver] = self.bl_sett_ver
        arr[self.setts.offs_app_ver] = self.app_ver
        arr[self.setts.offs_bl_ver] = self.bl_ver
        arr[self.setts.offs_bank_layout] = self.bank_layout
        arr[self.setts.offs_bank_current] = self.bank_current
        arr[self.setts.offs_bank0_img_sz] = self.app_sz
        arr[self.setts.offs_bank0_img_crc] = self.app_crc
        arr[self.setts.offs_bank0_bank_code] = self.bank0_bank_code

        # calculate the CRC32 from the filled-in settings
        crc_format_str = '<' + ('I' * (self.setts.uint32_count - 1))
        crc_arr = arr[1:]
        crc_data = struct.pack(crc_format_str, *crc_arr)
        self.crc = binascii.crc32(crc_data) & 0xffffffff

        # fill in the calculated CRC32
        arr[self.setts.offs_crc] = self.crc

        format_str = '<' + ('I' * self.setts.uint32_count)

        # Get the packed data to insert into the hex instance
        data = struct.pack(format_str, *arr)

        # insert the data at the correct address
        self.ihex.puts(self.bl_sett_addr, data)
예제 #2
0
    def generate(self, arch, app_file, app_ver, bl_ver, bl_sett_ver):
    
        # Set the architecture
        self.set_arch(arch)

        if bl_sett_ver == 1:
            self.setts = BLDFUSettingsStructV1()
        else:
            raise NordicSemiException("Unknown bootloader settings version")
        
        self.bl_sett_ver = bl_sett_ver & 0xffffffff
        self.bl_ver = bl_ver & 0xffffffff

        if app_ver is not None:
            self.app_ver = app_ver & 0xffffffff
        else:
            self.app_ver = 0x0 & 0xffffffff

        if app_file is not None:
            # load application to find out size and CRC
            self.temp_dir = tempfile.mkdtemp(prefix="nrf_dfu_bl_sett_")
            self.app_bin = Package.normalize_firmware_to_bin(self.temp_dir, app_file)

            # calculate application size and CRC32
            self.app_sz = int(Package.calculate_file_size(self.app_bin)) & 0xffffffff
            self.app_crc = int(Package.calculate_crc(32, self.app_bin)) & 0xffffffff
        else:
            self.app_sz = 0x0 & 0xffffffff
            self.app_crc = 0x0 & 0xffffffff

        # build the uint32_t array
        arr = [0x0] * self.setts.uint32_count

        # additional harcoded values
        self.bank_layout = 0x0 & 0xffffffff
        self.bank_current = 0x0 & 0xffffffff
        self.bank0_bank_code = 0x1 & 0xffffffff

        # fill in the settings
        arr[self.setts.offs_sett_ver] = self.bl_sett_ver
        arr[self.setts.offs_app_ver] = self.app_ver
        arr[self.setts.offs_bl_ver] = self.bl_ver
        arr[self.setts.offs_bank_layout] = self.bank_layout
        arr[self.setts.offs_bank_current] = self.bank_current
        arr[self.setts.offs_bank0_img_sz] = self.app_sz
        arr[self.setts.offs_bank0_img_crc] = self.app_crc
        arr[self.setts.offs_bank0_bank_code] = self.bank0_bank_code 

        # calculate the CRC32 from the filled-in settings
        crc_format_str = '<' + ('I' * (self.setts.uint32_count - 1)) 
        crc_arr = arr[1:]
        crc_data = struct.pack(crc_format_str, *crc_arr)
        self.crc = binascii.crc32(crc_data) & 0xffffffff

        # fill in the calculated CRC32
        arr[self.setts.offs_crc] = self.crc

        format_str = '<' + ('I' * self.setts.uint32_count) 

        # Get the packed data to insert into the hex instance
        data = struct.pack(format_str, *arr)
        
        # insert the data at the correct address
        self.ihex.puts(self.bl_sett_addr, data)
예제 #3
0
    def generate(self, arch, app_file, app_ver, bl_ver, bl_sett_ver,
                 custom_bl_sett_addr, no_backup, backup_address,
                 app_boot_validation_type, sd_boot_validation_type, sd_file,
                 key_file):

        self.set_arch(arch)

        if custom_bl_sett_addr is not None:
            self.bl_sett_addr = custom_bl_sett_addr

        if bl_sett_ver == 1:
            self.setts = BLDFUSettingsStructV1(self.bl_sett_addr)
        elif bl_sett_ver == 2:
            self.setts = BLDFUSettingsStructV2(self.bl_sett_addr)
        else:
            raise NordicSemiException("Unknown bootloader settings version")

        self.bl_sett_ver = bl_sett_ver & 0xffffffff
        self.bl_ver = bl_ver & 0xffffffff

        if app_ver is not None:
            self.app_ver = app_ver & 0xffffffff
        else:
            self.app_ver = 0x0 & 0xffffffff

        if app_file is not None:
            # load application to find out size and CRC
            self.temp_dir = tempfile.mkdtemp(prefix="nrf_dfu_bl_sett_")
            self.app_bin = Package.normalize_firmware_to_bin(
                self.temp_dir, app_file)

            # calculate application size and CRC32
            self.app_sz = int(Package.calculate_file_size(
                self.app_bin)) & 0xffffffff
            self.app_crc = int(Package.calculate_crc(
                32, self.app_bin)) & 0xffffffff
            self.bank0_bank_code = 0x1 & 0xffffffff

            # Calculate Boot validation fields for app
            if app_boot_validation_type == 'VALIDATE_GENERATED_CRC':
                self.app_boot_validation_type = 1 & 0xffffffff
                self.app_boot_validation_bytes = struct.pack(
                    '<I', self.app_crc)
            elif app_boot_validation_type == 'VALIDATE_GENERATED_SHA256':
                self.app_boot_validation_type = 2 & 0xffffffff
                sha256 = Package.calculate_sha256_hash(self.app_bin)
                self.app_boot_validation_bytes = bytearray([
                    int(binascii.hexlify(i), 16) for i in list(sha256)
                ][31::-1])
            elif app_boot_validation_type == 'VALIDATE_ECDSA_P256_SHA256':
                self.app_boot_validation_type = 3 & 0xffffffff
                ecdsa = Package.sign_firmware(key_file, self.app_bin)
                self.app_boot_validation_bytes = bytearray(
                    [int(binascii.hexlify(i), 16) for i in list(ecdsa)])
            else:  # This also covers 'NO_VALIDATION' case
                self.app_boot_validation_type = 0 & 0xffffffff
                self.app_boot_validation_bytes = bytearray(0)
        else:
            self.app_sz = 0x0 & 0xffffffff
            self.app_crc = 0x0 & 0xffffffff
            self.bank0_bank_code = 0x0 & 0xffffffff
            self.app_boot_validation_type = 0x0 & 0xffffffff
            self.app_boot_validation_bytes = bytearray(0)

        if sd_file is not None:
            # Load SD to calculate CRC
            self.temp_dir = tempfile.mkdtemp(prefix="nrf_dfu_bl_sett")
            temp_sd_file = os.path.join(os.getcwd(), 'temp_sd_file.hex')

            # Load SD hex file and remove MBR before calculating keys
            ih_sd = intelhex.IntelHex(sd_file)
            ih_sd_no_mbr = intelhex.IntelHex()
            ih_sd_no_mbr.merge(ih_sd[0x1000:], overlap='error')
            ih_sd_no_mbr.write_hex_file(temp_sd_file)

            self.sd_bin = Package.normalize_firmware_to_bin(
                self.temp_dir, temp_sd_file)
            os.remove(temp_sd_file)

            self.sd_sz = int(Package.calculate_file_size(
                self.sd_bin)) & 0xffffffff

            # Calculate Boot validation fields for SD
            if sd_boot_validation_type == 'VALIDATE_GENERATED_CRC':
                self.sd_boot_validation_type = 1 & 0xffffffff
                sd_crc = int(Package.calculate_crc(32,
                                                   self.sd_bin)) & 0xffffffff
                self.sd_boot_validation_bytes = struct.pack('<I', sd_crc)
            elif sd_boot_validation_type == 'VALIDATE_GENERATED_SHA256':
                self.sd_boot_validation_type = 2 & 0xffffffff
                sha256 = Package.calculate_sha256_hash(self.sd_bin)
                self.sd_boot_validation_bytes = bytearray([
                    int(binascii.hexlify(i), 16) for i in list(sha256)
                ][31::-1])
            elif sd_boot_validation_type == 'VALIDATE_ECDSA_P256_SHA256':
                self.sd_boot_validation_type = 3 & 0xffffffff
                ecdsa = Package.sign_firmware(key_file, self.sd_bin)
                self.sd_boot_validation_bytes = bytearray(
                    [int(binascii.hexlify(i), 16) for i in list(ecdsa)])
            else:  # This also covers 'NO_VALIDATION_CASE'
                self.sd_boot_validation_type = 0 & 0xffffffff
                self.sd_boot_validation_bytes = bytearray(0)
        else:
            self.sd_sz = 0x0 & 0xffffffff
            self.sd_boot_validation_type = 0 & 0xffffffff
            self.sd_boot_validation_bytes = bytearray(0)

        # additional harcoded values
        self.bank_layout = 0x0 & 0xffffffff
        self.bank_current = 0x0 & 0xffffffff

        # Fill the entire settings page with 0's
        for offset in range(0, self.setts.bytes_count):
            self.ihex[self.bl_sett_addr + offset] = 0x00

        self._add_value_tohex(self.setts.sett_ver, self.bl_sett_ver)
        self._add_value_tohex(self.setts.app_ver, self.app_ver)
        self._add_value_tohex(self.setts.bl_ver, self.bl_ver)
        self._add_value_tohex(self.setts.bank_layout, self.bank_layout)
        self._add_value_tohex(self.setts.bank_current, self.bank_current)
        self._add_value_tohex(self.setts.bank0_img_sz, self.app_sz)
        self._add_value_tohex(self.setts.bank0_img_crc, self.app_crc)
        self._add_value_tohex(self.setts.bank0_bank_code, self.bank0_bank_code)
        self._add_value_tohex(self.setts.sd_sz, self.sd_sz)

        self.boot_validation_crc = 0x0 & 0xffffffff
        if self.bl_sett_ver == 2:
            self._add_value_tohex(self.setts.sd_validation_type,
                                  self.sd_boot_validation_type, '<b')
            self.ihex.puts(self.setts.sd_validation_bytes,
                           self.sd_boot_validation_bytes)

            self._add_value_tohex(self.setts.app_validation_type,
                                  self.app_boot_validation_type, '<b')
            self.ihex.puts(self.setts.app_validation_bytes,
                           self.app_boot_validation_bytes)

            self.boot_validation_crc = self._calculate_crc32_from_hex(
                self.ihex,
                start_addr=self.setts.sd_validation_type,
                end_addr=self.setts.last_addr) & 0xffffffff
            self._add_value_tohex(self.setts.boot_validataion_crc,
                                  self.boot_validation_crc)

        self.crc = self._calculate_crc32_from_hex(
            self.ihex,
            start_addr=self.bl_sett_addr + 4,
            end_addr=self.setts.init_cmd - 1) & 0xffffffff
        self._add_value_tohex(self.setts.crc, self.crc)

        if backup_address is None:
            self.backup_address = self.bl_sett_addr - self.bl_sett_backup_offset
        else:
            self.backup_address = backup_address

        if not no_backup:
            for offset in range(0, self.setts.bytes_count):
                self.ihex[self.backup_address +
                          offset] = self.ihex[self.bl_sett_addr + offset]
예제 #4
0
    def generate(self, arch, app_file, app_ver, bl_ver, bl_sett_ver, custom_bl_sett_addr, no_backup,
                 backup_address, app_boot_validation_type, sd_boot_validation_type, sd_file, key_file):

        self.set_arch(arch)

        if custom_bl_sett_addr is not None:
            self.bl_sett_addr = custom_bl_sett_addr

        if bl_sett_ver == 1:
            self.setts = BLDFUSettingsStructV1(self.bl_sett_addr)
        elif bl_sett_ver == 2:
            self.setts = BLDFUSettingsStructV2(self.bl_sett_addr)
        else:
            raise NordicSemiException("Unknown bootloader settings version")

        self.bl_sett_ver = bl_sett_ver & 0xffffffff
        self.bl_ver = bl_ver & 0xffffffff

        if app_ver is not None:
            self.app_ver = app_ver & 0xffffffff
        else:
            self.app_ver = 0x0 & 0xffffffff

        if app_file is not None:
            # load application to find out size and CRC
            self.temp_dir = tempfile.mkdtemp(prefix="nrf_dfu_bl_sett_")
            self.app_bin = Package.normalize_firmware_to_bin(self.temp_dir, app_file)

            # calculate application size and CRC32
            self.app_sz = int(Package.calculate_file_size(self.app_bin)) & 0xffffffff
            self.app_crc = int(Package.calculate_crc(32, self.app_bin)) & 0xffffffff
            self.bank0_bank_code = 0x1 & 0xffffffff

            # Calculate Boot validation fields for app
            if app_boot_validation_type == 'VALIDATE_GENERATED_CRC':
                self.app_boot_validation_type = 1 & 0xffffffff
                self.app_boot_validation_bytes = struct.pack('<I', self.app_crc)
            elif app_boot_validation_type == 'VALIDATE_GENERATED_SHA256':
                self.app_boot_validation_type = 2 & 0xffffffff
                sha256 = Package.calculate_sha256_hash(self.app_bin)
                self.app_boot_validation_bytes = bytearray([int(binascii.hexlify(i), 16) for i in list(sha256)][31::-1])
            elif app_boot_validation_type == 'VALIDATE_ECDSA_P256_SHA256':
                self.app_boot_validation_type = 3 & 0xffffffff
                ecdsa = Package.sign_firmware(key_file, self.app_bin)
                self.app_boot_validation_bytes = bytearray([int(binascii.hexlify(i), 16) for i in list(ecdsa)])
            else:  # This also covers 'NO_VALIDATION' case
                self.app_boot_validation_type = 0 & 0xffffffff
                self.app_boot_validation_bytes = bytearray(0)
        else:
            self.app_sz = 0x0 & 0xffffffff
            self.app_crc = 0x0 & 0xffffffff
            self.bank0_bank_code = 0x0 & 0xffffffff
            self.app_boot_validation_type = 0x0 & 0xffffffff
            self.app_boot_validation_bytes = bytearray(0)

        if sd_file is not None:
            # Load SD to calculate CRC
            self.temp_dir = tempfile.mkdtemp(prefix="nrf_dfu_bl_sett")
            temp_sd_file = os.path.join(os.getcwd(), 'temp_sd_file.hex')

            # Load SD hex file and remove MBR before calculating keys
            ih_sd = intelhex.IntelHex(sd_file)
            ih_sd_no_mbr = intelhex.IntelHex()
            ih_sd_no_mbr.merge(ih_sd[0x1000:], overlap='error')
            ih_sd_no_mbr.write_hex_file(temp_sd_file)

            self.sd_bin = Package.normalize_firmware_to_bin(self.temp_dir, temp_sd_file)
            os.remove(temp_sd_file)

            self.sd_sz = int(Package.calculate_file_size(self.sd_bin)) & 0xffffffff

            # Calculate Boot validation fields for SD
            if sd_boot_validation_type == 'VALIDATE_GENERATED_CRC':
                self.sd_boot_validation_type = 1 & 0xffffffff
                sd_crc = int(Package.calculate_crc(32, self.sd_bin)) & 0xffffffff
                self.sd_boot_validation_bytes = struct.pack('<I', sd_crc)
            elif sd_boot_validation_type == 'VALIDATE_GENERATED_SHA256':
                self.sd_boot_validation_type = 2 & 0xffffffff
                sha256 = Package.calculate_sha256_hash(self.sd_bin)
                self.sd_boot_validation_bytes = bytearray([int(binascii.hexlify(i), 16) for i in list(sha256)][31::-1])
            elif sd_boot_validation_type == 'VALIDATE_ECDSA_P256_SHA256':
                self.sd_boot_validation_type = 3 & 0xffffffff
                ecdsa = Package.sign_firmware(key_file, self.sd_bin)
                self.sd_boot_validation_bytes = bytearray([int(binascii.hexlify(i), 16) for i in list(ecdsa)])
            else:  # This also covers 'NO_VALIDATION_CASE'
                self.sd_boot_validation_type = 0 & 0xffffffff
                self.sd_boot_validation_bytes = bytearray(0)
        else:
            self.sd_sz = 0x0 & 0xffffffff
            self.sd_boot_validation_type = 0 & 0xffffffff
            self.sd_boot_validation_bytes = bytearray(0)

        # additional harcoded values
        self.bank_layout = 0x0 & 0xffffffff
        self.bank_current = 0x0 & 0xffffffff

        # Fill the entire settings page with 0's
        for offset in range(0, self.setts.bytes_count):
            self.ihex[self.bl_sett_addr + offset] = 0x00

        self._add_value_tohex(self.setts.sett_ver, self.bl_sett_ver)
        self._add_value_tohex(self.setts.app_ver, self.app_ver)
        self._add_value_tohex(self.setts.bl_ver, self.bl_ver)
        self._add_value_tohex(self.setts.bank_layout, self.bank_layout)
        self._add_value_tohex(self.setts.bank_current, self.bank_current)
        self._add_value_tohex(self.setts.bank0_img_sz, self.app_sz)
        self._add_value_tohex(self.setts.bank0_img_crc, self.app_crc)
        self._add_value_tohex(self.setts.bank0_bank_code, self.bank0_bank_code)
        self._add_value_tohex(self.setts.sd_sz, self.sd_sz)

        self.boot_validation_crc = 0x0 & 0xffffffff
        if self.bl_sett_ver == 2:
            self._add_value_tohex(self.setts.sd_validation_type, self.sd_boot_validation_type, '<b')
            self.ihex.puts(self.setts.sd_validation_bytes, self.sd_boot_validation_bytes)

            self._add_value_tohex(self.setts.app_validation_type, self.app_boot_validation_type, '<b')
            self.ihex.puts(self.setts.app_validation_bytes, self.app_boot_validation_bytes)

            self.boot_validation_crc = self._calculate_crc32_from_hex(self.ihex,
                                                                      start_addr=self.setts.sd_validation_type,
                                                                      end_addr=self.setts.last_addr) & 0xffffffff
            self._add_value_tohex(self.setts.boot_validataion_crc, self.boot_validation_crc)

        self.crc = self._calculate_crc32_from_hex(self.ihex,
                                                  start_addr=self.bl_sett_addr+4,
                                                  end_addr=self.setts.init_cmd - 1) & 0xffffffff
        self._add_value_tohex(self.setts.crc, self.crc)

        if backup_address is None:
            self.backup_address = self.bl_sett_addr - self.bl_sett_backup_offset
        else:
            self.backup_address = backup_address

        if not no_backup:
            for offset in range(0, self.setts.bytes_count):
                self.ihex[self.backup_address + offset] = self.ihex[self.bl_sett_addr + offset]