def program(self, hexf=None, print_info=True, disable_bootloader=False): """Do a sequence of commands to program the hexf file (codified in Intel HEX format) to the flash memory. If hexf is not supplied, only read the bootinfo. If print_info is True, print bootinfo to standard output. Use disable_bootloader with caution. """ import devkit, hexfile bootinfo = self.cmd_info() if print_info: print(repr(bootinfo)) if hexf: self.cmd_boot() self.cmd_sync() kit = devkit.factory(bootinfo) hexfile.load(hexf, kit) kit.fix_bootloader(disable_bootloader) kit.transfer(self) self.cmd_reboot()
def update_psu(addr, filename): pause_monitoring() fwimg = hexfile.load(filename) enter_bootloader(addr) start_programming(addr) challenge = get_challenge(addr) send_key(addr, delta_seccalckey(challenge)) erase_flash(addr) send_image(addr, fwimg) verify_flash(addr) reset_psu(addr)
def program_mcs(self, filename): f = hexfile.load(filename) # Figure out what sectors we need to erase. sector_size = 0 total_size = 0 page_size = 256 if self.memory_capacity == 2**24: sector_size = 256 * 1024 total_size = self.memory_capacity elif self.memory_capacity == 2**25: sector_size = 256 * 1024 total_size = self.memory_capacity elif self.memory_capacity == 2**20: sector_size = 64 * 1024 total_size = self.memory_capacity else: print "Don't know how to program flash with capacity %d" % self.memory_capacity return erase_sectors = [0] * (total_size / sector_size) sector_list = [] for seg in f.segments: print "Segment %s starts at %d" % (seg, seg.start_address) start_sector = seg.start_address / sector_size print "This is sector %d" % start_sector if erase_sectors[start_sector] == 0: erase_sectors[start_sector] = 1 sector_list.append(start_sector) end_address = seg.end_address end_sector = start_sector + 1 while end_sector * sector_size < seg.end_address: if erase_sectors[end_sector] == 0: erase_sectors[end_sector] = 1 sector_list.append(end_sector) end_sector = end_sector + 1 for erase in sector_list: print "I think I should erase sector %d" % erase self.erase(erase * sector_size) for seg in f.segments: start = seg.start_address end = 0 while start < seg.size: end = start + page_size if end > seg.end_address: end = seg.end_address data = seg[start:end].data print "Programming %d-%d" % (start, end) self.page_program(start, data) start = end self.write_disable() print "Complete!"
def program_mcs(self, filename, sector_size=0): f = hexfile.load(filename) # Figure out what sectors we need to erase. sector_size = 0 total_size = self.memory_capacity page_size = 256 if sector_size == 0: sector_size = self.find_erase_sector_size() print "Sector size is %d" % sector_size erase_sectors = [0] * (total_size / sector_size) sector_list = [] for seg in f.segments: start_sector = seg.start_address / sector_size if erase_sectors[start_sector] == 0: erase_sectors[start_sector] = 1 sector_list.append(start_sector) end_address = seg.end_address end_sector = start_sector + 1 while end_sector * sector_size < seg.end_address: if erase_sectors[end_sector] == 0: erase_sectors[end_sector] = 1 sector_list.append(end_sector) end_sector = end_sector + 1 count = 0 total = len(sector_list) print "Erasing %d sectors." % total SPI.update_progress(0) for erase in sector_list: self.erase(erase * sector_size) count = count + 1 SPI.update_progress(float(count) / float(total)) seg_count = 0 for seg in f.segments: start = seg.start_address end = 0 print "Programming segment %d/%d." % (seg_count + 1, len( f.segments)) SPI.update_progress(0) while start < seg.size: end = start + page_size if end > seg.end_address: end = seg.end_address data = seg[start:end].data self.page_program(start, data) start = end SPI.update_progress(float(start) / float(seg.size)) self.write_disable() print "Complete!"
def update_psu(addr, filename): status_state('pausing_monitoring') pause_monitoring() status_state('parsing_fw_file') fwimg = hexfile.load(filename) status_state('bootloader_handshake') enter_bootloader(addr) start_programming(addr) challenge = get_challenge(addr) send_key(addr, delta_seccalckey(challenge)) status_state('erase_flash') erase_flash(addr) status_state('flashing') send_image(addr, fwimg) status_state('verifying') verify_flash(addr) status_state('resetting') reset_psu(addr) status_state('done')
def update_psu(addr, filename): status_state("pausing_monitoring") pause_monitoring() status_state("parsing_fw_file") fwimg = hexfile.load(filename) status_state("bootloader_handshake") enter_bootloader(addr) start_programming(addr) challenge = get_challenge(addr) send_key(addr, delta_seccalckey(challenge)) status_state("erase_flash") erase_flash(addr) status_state("flashing") send_image(addr, fwimg) status_state("verifying") verify_flash(addr) status_state("resetting") reset_psu(addr) status_state("done")
def microboot_from_hexfile(filename): import hexfile hexf = hexfile.load(filename) # Work out the number of bytes needed totalsize = ctypes.sizeof(MicrobootConfig) for i, segment in enumerate(hexf.segments): start = 0 while True: totalsize += ctypes.sizeof(MicrobootSegment) partsize = min(MicrobootSegment.MAX_LEN, segment.size - start) start += partsize if start >= segment.size: break totalsize += segment.size totalsize += ctypes.sizeof(MicrobootSegment) backbuffer = bytearray(totalsize+100) # FX2 header mb2cfg = MicrobootConfig.from_buffer(backbuffer) mb2cfg.buffer = backbuffer # FX2 data segments mb2seg = mb2cfg for i, segment in enumerate(hexf.segments): start = 0 while True: mb2seg = mb2seg.next() partsize = min(mb2seg.MAX_LEN, segment.size - start) mb2seg.addr = segment.start_address + start mb2seg._len = partsize mb2seg.data[:] = segment.data[start:start+partsize] start += partsize if start >= segment.size: break mb2seg = mb2seg.next() mb2seg.make_last() assert totalsize == mb2cfg.totalsize return mb2cfg
def microboot_from_hexfile(filename): import hexfile hexf = hexfile.load(filename) # Work out the number of bytes needed totalsize = ctypes.sizeof(MicrobootConfig) for i, segment in enumerate(hexf.segments): start = 0 while True: totalsize += ctypes.sizeof(MicrobootSegment) partsize = min(MicrobootSegment.MAX_LEN, segment.size - start) start += partsize if start >= segment.size: break totalsize += segment.size totalsize += ctypes.sizeof(MicrobootSegment) backbuffer = bytearray(totalsize + 100) # FX2 header mb2cfg = MicrobootConfig.from_buffer(backbuffer) mb2cfg.buffer = backbuffer # FX2 data segments mb2seg = mb2cfg for i, segment in enumerate(hexf.segments): start = 0 while True: mb2seg = mb2seg.next() partsize = min(mb2seg.MAX_LEN, segment.size - start) mb2seg.addr = segment.start_address + start mb2seg._len = partsize mb2seg.data[:] = segment.data[start:start + partsize] start += partsize if start >= segment.size: break mb2seg = mb2seg.next() mb2seg.make_last() assert totalsize == mb2cfg.totalsize return mb2cfg
def update_psu(addr, filename): status_state("pausing_monitoring") pause_monitoring() status_state("parsing_fw_file") fwimg = hexfile.load(filename) status_state("pre_handshake_reset") # This brings us back to the top of the bootloader state machine if we were # in bootloader, and should do nothing otherwise reset_psu(addr) time.sleep(5.0) status_state("bootloader_handshake") enter_bootloader(addr) start_programming(addr) challenge = get_challenge(addr) send_key(addr, delta_seccalckey(challenge)) status_state("erase_flash") erase_flash(addr) status_state("flashing") send_image(addr, fwimg) status_state("verifying") verify_flash(addr) status_state("resetting") reset_psu(addr) status_state("done")
def patch_rjmp(dest, base): offset = (dest - base) / 2 - 1 return struct.pack('<H', 0xc000 | (offset & 0xfff)) def patch_jmp(dest): return struct.pack('<HH', 0x940c, dest / 2) # Hardcoded bootloader_start = 0xec0 flash_end = (bootloader_start & ~4095) + 4096 pagesize = 0x40 f = hexfile.load(sys.argv[1]) if len(f.segments) != 1: raise Exception('Can only handle continuous hexfiles') seg = f.segments[0] if not 0 in seg: raise Exception('Hexfile must contain vector table') if seg.size > bootloader_start - 4: raise Exception('Too large') dev = cec_flasher() dev.enter() dev.ping() print 'Erasing' dev.erase() print 'Programming %d bytes' % seg.size