def sign_and_append_validation_data(pem_file, input_file, offset, output_file, magic_value, pk_hash_len): ih = IntelHex(input_file) ih.start_addr = None # OBJCOPY incorrectly inserts x86 specific records, remove the start_addr as it is wrong. minimum_offset = ((ih.maxaddr() // 4) + 1) * 4 if offset != 0 and offset < minimum_offset: raise RuntimeError("Incorrect offset, must be bigger than %x" % minimum_offset) # Parse comma-separated string of uint32s into hex string. Each in is encoded # in little-endian byte order parsed_magic_value = b''.join( [struct.pack("<I", int(m, 0)) for m in magic_value.split(",")]) validation_data = get_validation_data(pem_file=pem_file, input_hex=ih, magic_value=parsed_magic_value, pk_hash_len=pk_hash_len) validation_data_hex = IntelHex() # If no offset is given, append metadata right after input hex file (word aligned). if offset == 0: offset = minimum_offset validation_data_hex.frombytes(validation_data, offset) ih.merge(validation_data_hex) ih.write_hex_file(output_file)
def save_image(self, path): if self.data_buffer: if path.lower().endswith('.bin'): with open(path, "wb") as f: f.write(self.data_buffer) f.close() elif path.lower().endswith('.hex'): ihex = IntelHex() ihex.frombytes(self.data_buffer, 0) ihex.start_addr = self.FlashStartAddress try: ihex.tofile(path, format='hex') except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), 'ERROR', wx.OK | wx.ICON_ERROR) elif path.lower().endswith(('.s19', '.srec')): srec = SRecFile() srec.header = "KBOOT" srec.start_addr = self.FlashStartAddress srec.data = self.data_buffer try: srec.save(path) except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), 'ERROR', wx.OK | wx.ICON_ERROR) else: wx.MessageBox('Not supported file Type !', 'ERROR', wx.OK | wx.ICON_ERROR) else: wx.MessageBox('No data to save', 'INFO', wx.OK | wx.ICON_INFORMATION)
def save_image(self, path): if self.data_buffer: if path.lower().endswith(".bin"): with open(path, "wb") as f: f.write(self.data_buffer) f.close() elif path.lower().endswith(".hex"): ihex = IntelHex() ihex.frombytes(self.data_buffer, 0) ihex.start_addr = self.FlashStartAddress try: ihex.tofile(path, format="hex") except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), "ERROR", wx.OK | wx.ICON_ERROR ) elif path.lower().endswith((".s19", ".srec")): srec = SRecFile() srec.header = "KBOOT" srec.start_addr = self.FlashStartAddress srec.data = self.data_buffer try: srec.save(path) except Exception as e: wx.MessageBox( "Could not write into file: %s\n\n%s" % (path, str(e)), "ERROR", wx.OK | wx.ICON_ERROR ) else: wx.MessageBox("Not supported file Type !", "ERROR", wx.OK | wx.ICON_ERROR) else: wx.MessageBox("No data to save", "INFO", wx.OK | wx.ICON_INFORMATION)
def append_validation_data(signature, input_file, public_key, offset, output_hex, output_bin, magic_value): ih = IntelHex(input_file) ih.start_addr = None # OBJCOPY incorrectly inserts x86 specific records, remove the start_addr as it is wrong. minimum_offset = ((ih.maxaddr() // 4) + 1) * 4 if offset != 0 and offset < minimum_offset: raise RuntimeError( f'Incorrect offset, must be bigger than {hex(minimum_offset)}') # Parse comma-separated string of uint32s into hex string. Each is encoded in little-endian byte order parsed_magic_value = b''.join( [struct.pack('<I', int(m, 0)) for m in magic_value.split(',')]) validation_data = get_validation_data(signature_bytes=signature, input_hex=ih, public_key=public_key, magic_value=parsed_magic_value) validation_data_hex = IntelHex() # If no offset is given, append metadata right after input hex file (word aligned). if offset == 0: offset = minimum_offset validation_data_hex.frombytes(validation_data, offset) ih.merge(validation_data_hex) ih.write_hex_file(output_hex) if output_bin: ih.tofile(output_bin.name, format='bin')
def merge_hex_files(output, input_hex_files): ih = IntelHex() for hex_file_path in input_hex_files: to_merge = IntelHex(hex_file_path) # Since 'arm-none-eabi-objcopy' incorrectly inserts record type '03 - Start Segment Address', we need to remove # the start_addr to avoid conflicts when merging. to_merge.start_addr = None ih.merge(to_merge) ih.write_hex_file(output)
def merge_hex_files(output, input_hex_files, overlap): ih = IntelHex() for hex_file_path in input_hex_files: to_merge = IntelHex(hex_file_path) # Since 'arm-none-eabi-objcopy' incorrectly inserts record # type '03 - Start Segment Address', we need to remove the # start_addr to avoid conflicts when merging. to_merge.start_addr = None try: ih.merge(to_merge, overlap=overlap) except AddressOverlapError: raise AddressOverlapError("{} has merge issues".format(hex_file_path)) ih.write_hex_file(output)
def merge_secure(t_self, resources, ns_elf, ns_hex): t_self.notify.info("Merging non-secure image with secure image") configured_secure_image_filename = t_self.target.secure_image_filename t_self.notify.info("Non-secure elf image %s" % ns_elf) t_self.notify.info("Non-secure hex image %s" % ns_hex) t_self.notify.info("Finding secure image %s" % configured_secure_image_filename) s_hex = find_secure_image( t_self.notify, resources, ns_hex, configured_secure_image_filename, FileType.HEX ) t_self.notify.info("Found secure image %s" % s_hex) _, ext = os.path.splitext(s_hex) if ext != ".hex": t_self.notify.debug("Secure image %s must be in Intel HEX format" % s_hex) return if not os.path.isfile(s_hex): t_self.notify.debug("Secure image %s must be regular file" % s_hex) return ns_main, ext = os.path.splitext(ns_hex) if ext != ".hex": t_self.notify.debug("Non-secure image %s must be in Intel HEX format" % s_hex) return if not os.path.isfile(ns_hex): t_self.notify.debug("Non-secure image %s must be regular file" % s_hex) return # Keep original non-secure before merge with secure ns_nosecure_hex = ns_main + "_no-secure-merge" + ext t_self.notify.info("Keep no-secure-merge image %s" % ns_nosecure_hex) shutil.copy2(ns_hex, ns_nosecure_hex) # Merge secure and non-secure and save to non-secure (override it) from intelhex import IntelHex s_ih = IntelHex() s_ih.loadhex(s_hex) ns_ih = IntelHex() ns_ih.loadhex(ns_hex) ns_ih.start_addr = None s_ih.merge(ns_ih) s_ih.tofile(ns_hex, 'hex')
def merge_hex_executables(target, source, env): """Combine all hex files into a singular executable file.""" output_name = str(target[0]) hex_final = IntelHex() for image in source: file = str(image) root, ext = os.path.splitext(file) file_format = ext[1:] if file_format == 'elf': file = root + '.hex' hex_data = IntelHex(file) # merge will throw errors on mismatched Start Segment Addresses, which we don't need # See <https://stackoverflow.com/questions/26295776/what-are-the-intel-hex-records-type-03-or-05-doing-in-ihex-program-for-arm> hex_data.start_addr = None hex_final.merge(hex_data, overlap='error') with open(output_name, 'w') as outfile: hex_final.write_hex_file(outfile)
def _test_write(self, hexstr, data, start_addr, write_start_addr=True): # prepare ih = IntelHex(None) ih._buf = data ih.start_addr = start_addr # write sio = StringIO() self.assertTrue(ih.writefile(sio, write_start_addr)) s = sio.getvalue() sio.close() # check self.assertEquals( hexstr, s, """Written data is incorrect Should be: %s Written: %s """ % (hexstr, s), )
def read(addr, length, compress, file): click.echo("\n Reading from MCU memory, please wait !\n") # Call KBoot flash erase all function data = KBOOT.read_memory(addr, length) # Disconnect KBoot Device KBOOT.disconnect() if file is None: click.echo(hexdump(data, addr, compress)) else: if file.lower().endswith('.bin'): with open(file, "wb") as f: f.write(data) f.close() elif file.lower().endswith('.hex'): ihex = IntelHex() ihex.frombytes(data, 0) ihex.start_addr = addr try: ihex.tofile(file, format='hex') except Exception as e: raise Exception('Could not write to file: %s \n [%s]' % (file, str(e))) else: srec = kboot.SRecFile() srec.header = "pyKBoot" srec.start_addr = addr srec.data = data try: srec.save(file) except Exception as e: raise Exception('Could not write to file: %s \n [%s]' % (file, str(e))) click.secho(" Successfully saved into: %s. \n" % file)
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 sd_with_offsets = t_self.target.EXPECTED_SOFTDEVICES_WITH_OFFSETS for softdevice_and_offset_entry in sd_with_offsets: for hexf in resources.get_file_paths(FileType.HEX): 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.get_file_paths(FileType.HEX): 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) sdh.start_addr = None 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) blh.start_addr = None binh.merge(blh) with open(binf.replace(".bin", ".hex"), "w") as fileout: binh.write_hex_file(fileout, write_start_addr=False)
ihexf = sys.argv[1] sections = [] for i in range(2, len(sys.argv), 2): start = int(sys.argv[i], 0) end = int(sys.argv[i + 1], 0) sections.append([start, end + 1]) ih = IntelHex() iho = IntelHex() ih.loadhex(ihexf) all_sections = ih.segments() print("input hex file sections:") for sec in all_sections: print("0x%08X 0x%08X" % (sec[0], sec[1] - 1)) #copy all regular sections for sec in sections: for i in range(sec[0], sec[1]): iho[i] = ih[i] #copy start address #print("start address: ",ih.start_addr) iho.start_addr = ih.start_addr iho.write_hex_file(ihexf + ".phy.ihex") all_sections = iho.segments() print("output hex file sections:") for sec in all_sections: print("0x%08X 0x%08X" % (sec[0], sec[1] - 1))
sys.exit(1) if not os.path.exists(sys.argv[1]): sys.exit("Unable open build %s" % sys.argv[1]) if not os.path.exists(sys.argv[2]): sys.exit("Unable open build %s" % sys.argv[2]) build_filename = sys.argv[1] prog_filename = sys.argv[2] # open the build and prog # note open build via StringIO so we can add to it build = IntelHex(StringIO.StringIO(open(build_filename, "r").read())) prog = IntelHex(prog_filename) # merge program into build prog_header_addr = prog.minaddr() prog.start_addr = build.start_addr # we need this to make the merge work smoothly build.merge(prog) # add pointer to program header to the bootstrap header_tbl_addr = 0x08000204 header_tbl_len = 2 #@todo get this from 0x0800200 as uint32_t header_tbl_format = "<LL" header_tbl = list( struct.unpack(header_tbl_format, build.gets(header_tbl_addr, header_tbl_len * 4))) k = 0 while header_tbl[k] != 0xffffffff: if k > header_tbl_len: sys.exit("bootstrap program table full [you have too many programs]!") k += 1 header_tbl[k] = prog_header_addr
def main(): if len(sys.argv) < 3: print("Usage: %s <bin file> <cyad file>") sys.exit() bin_file = sys.argv[1] cyad_file = sys.argv[2] if not os.path.isfile(bin_file): print("bin file path %s does not exist. Exiting..." % (bin_file)) sys.exit() else: print("bin file: " + bin_file) if not os.path.isfile(cyad_file): print("cyad path %s does not exist. Exiting..." % (cyad_file)) sys.exit() else: print("cyad file: " + cyad_file) with open(bin_file, mode='rb') as bfp: b = bytearray(bfp.read()) print("binary loade, len %d" % len(b)) # Now merge in the cyad bdata = bytearray() # default deviceid = int(CYPD2104_20FNXI, 16) with open(cyad_file) as cyfp: cnt = 0 for line in cyfp: if cnt == 0: if CYPD2104_20FNXI in line: deviceid = int(CYPD2104_20FNXI, 16) print("device is CYPD2104_20FNXI") elif CYPD2122_20FNXIT in line: deviceid = int(CYPD2122_20FNXIT, 16) print("device is CYPD2122_20FNXIT") else: print("unk device: %s" % (line)) else: line = line.strip() if cnt == 1: cyad_addr = int(line[1:9], 16) >> 1 print("addr: %x" % cyad_addr) data = line[11:len(line) - 2] bdata.extend(binascii.unhexlify(data)) cnt += 1 # merge cyad with program data bend = b[cyad_addr + len(bdata):] b = b[:cyad_addr] b.extend(bdata) b.extend(bend) # update csums updateCfgCsum(cyad_addr, b) # calculate the binary checksum csum = calcChecksum(b) csum_short = csum & 0xFFFF # Create the device record meta data DiDR = createDeviceIdRecord(csum, deviceid) # create the hex file string sio = StringIO() ihex = IntelHex() ihex.start_addr = None ihex.padding = 0x00 # ihex failed to decode a character, so doing it one by one for i, c in enumerate(b): ihex[i] = c # write out the ihex string ihex.write_hex_file(sio) hexstr = sio.getvalue() sio.close() # remove the EOF so we can add the cypress metadata hexstr = hexstr[:hexstr.rfind(ihex_eof)] # metadata stoarge suffix = [] # add checksum short suffix.append(":0200000490303A") suffix.append(makedataline(csum_short.to_bytes(2, byteorder='big'), 0, 0)) # metadata suffix.append(":0200000490402A") suffix.append( ":200000000000000000000000000000000000000000000000000000000000000000000000E0" ) # Device id record suffix.append(":0200000490501A") suffix.append(makedataline(DiDR, 0, 0)) # chip level protection suffix.append(":0200000490600A") suffix.append(":0100000001FE") # EOF suffix.append(ihex_eof) tail = '\n'.join(suffix) hexstr = hexstr + tail with open("out.hex", mode='w') as ofp: ofp.write(hexstr)
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) sdh.start_addr = None 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) blh.start_addr = None binh.merge(blh) with open(binf.replace(".bin", ".hex"), "w") as fileout: binh.write_hex_file(fileout, write_start_addr=False)
ih = IntelHex(hexfn) blih = IntelHex(bootfn) ih.padding = 0xff code = ih.tobinstr(start=fw_offset, end=fw_offset+fw_length-1) res = ih.tobinstr(start=res_offset, end=res_offset+res_length-1) ver_data_offset = code.index(verdatastart) + len(verdatastart) model, version, subversion, litera, assmcode =\ struct.unpack_from('<HHHcB', code, ver_data_offset) ver = str(model) + '.' + str(version) + '.' + str(subversion) + '.' + litera + '-' + str(assmcode) print 'Extracted version data:', ver print 'Merging bootloader file...', ih.start_addr = None # program start addr record will be from BL part try: ih.merge(blih, overlap='error') print 'Ok' except AddressOverlapError: print ' probably already merged, data overlap! CHECK THIS!' finally: hx_fn = 'DKSF_' + ver + '_HX.hex' print 'Writing', hx_fn, '...', ih.write_hex_file(hx_fn) print 'Ok' npf = '' npf += fwstart npf += code npf += fwend
sys.exit(1) if not os.path.exists(sys.argv[1]): sys.exit("Unable open build %s" % sys.argv[1]) if not os.path.exists(sys.argv[2]): sys.exit("Unable open build %s" % sys.argv[2]) build_filename = sys.argv[1] prog_filename = sys.argv[2] # open the build and prog # note open build via StringIO so we can add to it build = IntelHex(StringIO.StringIO(open(build_filename, "r").read())) prog = IntelHex(prog_filename) # merge program into build prog_header_addr = prog.minaddr() prog.start_addr = build.start_addr # we need this to make the merge work smoothly build.merge(prog) # add pointer to program header to the bootstrap header_tbl_addr = 0x08000204 header_tbl_len = 2 #@todo get this from 0x0800200 as uint32_t header_tbl_format = "<LL" header_tbl = list(struct.unpack(header_tbl_format, build.gets(header_tbl_addr, header_tbl_len * 4))) k = 0 while header_tbl[k] != 0xffffffff: if k > header_tbl_len: sys.exit("bootstrap program table full [you have too many programs]!"); k += 1 header_tbl[k] = prog_header_addr build.puts(header_tbl_addr, struct.pack(header_tbl_format, *header_tbl))