Example #1
1
def check_fw(path):
    """Check that firmware is valid and return dict with binary data."""
    try:
        intel_hex = IntelHex()
        with open(path, 'r') as file_handle:
            intel_hex.fromfile(file_handle, format='hex')
        bin_string = intel_hex.tobinstr()
    except (IntelHexError, TypeError, ValueError) as exception:
        _LOGGER.error(exception)
        return
    pads = len(bin_string) % 128  # 128 bytes per page for atmega328
    for _ in range(128 - pads):  # pad up to even 128 bytes
        bin_string += b'\xff'
    fware = {
        'path': path,
        'blocks': int(len(bin_string) / FIRMWARE_BLOCK_SIZE),
        'crc': compute_crc(bin_string),
        'data': bin_string,
    }
    return fware
Example #2
0
    def post_process(self):
        logging.info("Processing binaries")
        
        # save original dir
        cwd = os.getcwd()

        # change to target dir
        os.chdir(self.target_dir)

        ih = IntelHex('main.hex')
        
        fwid = uuid.UUID('{' + self.settings["FWID"] + '}')
        
        size = ih.maxaddr() - ih.minaddr() + 1
        
        # get os info
        os_project = get_project_builder(self.settings["OS_PROJECT"])

        # create firmware info structure
        fw_info = struct.pack('<I16s128s16s128s16s', 
                                size, 
                                fwid.bytes, 
                                os_project.proj_name, 
                                os_project.version, 
                                self.proj_name,
                                self.version)
        
        # insert fw info into hex
        ih.puts(0x120, fw_info)

        # compute crc
        crc_func = crcmod.predefined.mkCrcFun('crc-aug-ccitt')

        crc = crc_func(ih.tobinstr())

        logging.info("size: %d" % (size))
        logging.info("fwid: %s" % (fwid))
        logging.info("crc: 0x%x" % (crc))
        logging.info("os name: %s" % (os_project.proj_name))
        logging.info("os version: %s" % (os_project.version))
        logging.info("app name: %s" % (self.proj_name))
        logging.info("app version: %s" % (self.version))

        ih.puts(ih.maxaddr() + 1, struct.pack('>H', crc))

        ih.write_hex_file('main.hex')
        ih.tobinfile('firmware.bin')
        
        # get loader info
        loader_project = get_project_builder(self.settings["LOADER_PROJECT"])

        # create loader image
        loader_hex = os.path.join(loader_project.target_dir, "main.hex")
        self.merge_hex('main.hex', loader_hex, 'loader_image.hex')
        
        # change back to original dir
        os.chdir(cwd)
Example #3
0
    def _write_ihx(self, filename):
        ihx = IntelHex(filename)

        print "Erasing."
        min_sector = rounddown_multiple(ihx.minaddr(), SECTORSIZE)
        max_sector = roundup_multiple(ihx.maxaddr(), SECTORSIZE)
        for addr in range(min_sector, max_sector, SECTORSIZE):
            self._erase_sector(addr)

        print "Writing."
        min_page = rounddown_multiple(ihx.minaddr(), PAGESIZE)
        max_page = roundup_multiple(ihx.maxaddr(), PAGESIZE)
        for addr in range(min_page, max_page, PAGESIZE):
            self._write(addr, ihx.tobinstr(start=addr, size=PAGESIZE))
Example #4
0
    def flash_file(self, filename, addr=0, verify=False):
        hexfile = IntelHex(filename)
        print('Min addr >> ', hexfile.minaddr())
        assert hexfile.minaddr() == 0
        data = hexfile.tobinstr()
        page_size = mcs51.consts.FLASH_PAGE_SIZE

        for i in range(0, len(data), page_size):
            cur = data[i:i + page_size]
            glog.info('Writing page %d of %d', i // page_size,
                      len(data) // page_size)
            self.write_flash_page(addr + i, cur)
            if verify:
                glog.info('Verifying page')
                written = bytes(self.read_flash_page(addr + i))
                written = written[:len(cur)]
                assert cur == written, '%s VS %s' % (cur, written)
Example #5
0
def load_fw(path):
    """Open firmware file and return a binary string."""
    fname = os.path.realpath(path)
    exists = os.path.isfile(fname)
    if not exists or not os.access(fname, os.R_OK):
        _LOGGER.error('Firmware path %s does not exist or is not readable',
                      path)
        return None
    try:
        intel_hex = IntelHex()
        with open(path, 'r') as file_handle:
            intel_hex.fromfile(file_handle, format='hex')
        return intel_hex.tobinstr()
    except (IntelHexError, TypeError, ValueError) as exc:
        _LOGGER.error('Firmware not valid, check the hex file at %s: %s', path,
                      exc)
        return None
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 #7
0
    def slurp(self, filename):
        if filename.endswith('.bit') or filename.endswith('.bin'):
            with open(filename, 'rb') as f:
                return f.read()

        elif filename.endswith('.hex'):
            with open(filename, 'rb') as f:
                return bytes("".join(chr(int(i, 16)) for i in f.read().split()))

        elif filename.endswith('.mcs'):
            ih = IntelHex()
            ih.fromfile(filename, format='hex')
            bitstream = ih.tobinstr(start=0, end=ih.maxaddr())
            bitstream = _mirror_each_byte(bitstream)
            return bitstream

        else:
            raise ValueError('Unknown bitstream extension')
Example #8
0
def read_fw(args, model_a):
    # load the firmware image
    stock = None
    image = None
    if args.stock:
        with open(args.firmware, 'rb') as source:
            stock = firmware.UpdateFile(source.read())
            image = firmware.Firmware(
                stock.a_firmware if model_a else stock.cs_firmware,
                encrypted=True,
            )
    else:
        with open(args.firmware, 'r') as source:
            hexfile = IntelHex(source)
            image = firmware.Firmware(
                hexfile.tobinstr(start=0x1800, end=0x1FBFF),
                encrypted=False,
            )
    return stock, image
Example #9
0
    def add_firmware(self, filename_hex, fw_info):
        ihex = IntelHex(filename_hex)
        # We remove configuration data from TSB firmware (last 16 bytes)
        # beginnin with TSB ...
        fw_data = ihex.tobinstr()
        fw_info.tsb_fwconf = ""

        fw_parts = fw_data.rsplit("TSB", 1)
        if len(fw_parts) == 2:
            fw_data = fw_parts[0]
            fw_info.tsb_fwconf = fw_parts[1]
        
        fw_info.tsb_start = ihex.minaddr()
        fw_md5 = hashlib.md5(fw_data).hexdigest()
        
        if not self.tsbdb.has_key(fw_md5):
            self.tsbdb[fw_md5] = [ fw_data ]
            
        self.add_firmware_info(fw_md5, fw_info)
Example #10
0
    def __init__(self,
                 fw: Union[bytearray, bytes, str, BinaryIO],
                 be: Optional[bool] = None) -> None:
        self.base = None  # type: Optional[int]
        if isinstance(fw, str):
            if fw.lower().endswith('.hex'):
                ih = IntelHex()
                ih.loadhex(fw)
                self.base = ih.minaddr()
                self.fw = bytearray(ih.tobinstr())
            else:
                with open(fw, 'rb') as f:
                    self.fw = bytearray(f.read())
        elif isinstance(fw, bytes):
            self.fw = bytearray(fw)
        elif isinstance(fw, bytearray):
            self.fw = fw
        else:
            self.fw = bytearray(fw.read())

        self.size = len(self.fw)
        if self.size < 8 or (self.size & 3) != 0:
            raise ValueError('invalid firmware length')

        self.crc = crc32(self.fw[8:])

        if be is None:
            (lcrc, lsz) = struct.unpack_from('<II', self.fw)
            (bcrc, bsz) = struct.unpack_from('>II', self.fw)
            if (lcrc == self.crc
                    and lsz == self.size) or lsz == Firmware.SIZE_MAGIC:
                self.be = False
            elif (bcrc == self.crc
                  and bsz == self.size) or bsz == Firmware.SIZE_MAGIC:
                self.be = True
            else:
                raise ValueError('could not determine firmware endianness')
        else:
            self.be = be
        self.ep = '>' if be else '<'

        (self.hcrc, self.hsize) = struct.unpack_from(self.ep + 'II', self.fw)
Example #11
0
def check_fw(path):
    """Check that firmware is valid and return dict with binary data."""
    try:
        intel_hex = IntelHex()
        with open(path, 'r') as file_handle:
            intel_hex.fromfile(file_handle, format='hex')
        bin_string = intel_hex.tobinstr()
    except (IntelHexError, TypeError, ValueError) as exception:
        _LOGGER.error(exception)
        return
    pads = len(bin_string) % 128  # 128 bytes per page for atmega328
    for _ in range(128 - pads):  # pad up to even 128 bytes
        bin_string += b'\xff'
    fware = {
        'path': path,
        'blocks': int(len(bin_string) / FIRMWARE_BLOCK_SIZE),
        'crc': compute_crc(bin_string),
        'data': bin_string,
    }
    return fware
Example #12
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 #13
0
def main(argv):
   if len(argv) != 2:
      print('challenger.py <hexfile> <serialport>')
      sys.exit(2)

   # Check if hexfile exists
   hexfile = argv[0]
   if not os.path.isfile(hexfile):
      print("ERROR: File not found:", hexfile)
      sys.exit(2)
   ih = IntelHex(hexfile)

   ser = serial.Serial(argv[1], 9600)
   time.sleep(1)

   # Generate nonce
   nonce = os.urandom(20)
   print("Nonce: ")
   print(binascii.hexlify(nonce))

   # Send nonce to prover
   ser.write(nonce)

   # Wait for answer 'o' --> OK -- This is only for debugging purposes, to make sure that the nonce is received.
   answer = ser.read()
   while answer != b'o':
       answer = ser.read()
   print(answer)

   #Calc digest
   hmac_gen = hmac.new(key, None, hashlib.sha1)
   hmac_gen.update(ih.tobinstr(0,32*1024-1)) #32*1024-1
   hmac_gen.update(nonce)
   print("Expected response:");
   print(binascii.hexlify(hmac_gen.digest()))

   # Get digest from mote
   mote_digest = ser.read(20)
   print("Prover response:");
   print(binascii.hexlify(mote_digest))
Example #14
0
def program_flash(programmer, in_file, start_address, erase, verify, force_bin,
                  log_function):
    image_array = in_file.read()

    if image_array.startswith(b':') and not force_bin:

        print(
            "File type detected as Intel Hex -- converting to binary before flashing..."
        )
        print("To force flashing as-is, pass --bin.")

        # HACK: The IntelHex class expects a filename or file-like object, but...we've already read the file.
        # So let's wrap it in a file-like object. Normally, we'd use io.BytesIO,
        # except IntelHex wants strings, not bytes objects. So...
        intel_hex = IntelHex(io.StringIO(image_array.decode('ascii')))
        image_array = intel_hex.tobinstr()

    log_function("Writing data to flash...")
    programmer.program_flash(image_array,
                             erase=erase,
                             verify=verify,
                             start=start_address)
Example #15
0
def main():
    parser = argparse.ArgumentParser(description="Bootloader CRC patcher")
    parser.add_argument('filename', help='Intel HEX file to patch')
    args = parser.parse_args()

    if not args.filename.lower().endswith('.hex'):
        print("Not a .hex file?")
        return

    ih = IntelHex()
    ih.loadhex(args.filename)
    data = ih.tobinstr(start=0, size=0x100)
    offset = data.find(b'\xCC\xCC')
    if offset < 0:
        return
    crc = fixcrc16pos(data, offset)
    print('Patching with CRC of %04X' % crc)
    ih[offset] = crc >> 8
    ih[offset + 1] = crc & 255
    #data = ih.tobinstr(start=0, size=0x100)
    #print('Final CRC = %04X' % crc16(data))
    ih.write_hex_file(args.filename)
Example #16
0
	def write_hex_file(self, fname):
		print "Loading input file", fname
		ih = IntelHex(fname)

		input_crc = atmel_crc(ih.tobinstr(start=0, end=self.memsize, pad=0xff))
		print "Size=%s; CRC=%s"%(ih.maxaddr(), hex(input_crc))
		
		print "Erasing...",
		self.erase()
		print "done"
		
		print "Flashing...",
		self.program(ih)
		
		dev_crc = self.app_crc()
		print "Checked CRC is", hex(dev_crc)
		
		if input_crc == dev_crc:
			print "CRC matches"
			print "Resetting"
			self.reset()
		else:
			print "CRC DOES NOT MATCH"
Example #17
0
    def write_hex_file(self, fname):
        print "Loading input file", fname
        ih = IntelHex(fname)

        input_crc = atmel_crc(ih.tobinstr(start=0, end=self.memsize, pad=0xff))
        print "Size=%s; CRC=%s" % (ih.maxaddr(), hex(input_crc))

        print "Erasing...",
        self.erase()
        print "done"

        print "Flashing...",
        self.program(ih)

        dev_crc = self.app_crc()
        print "Checked CRC is", hex(dev_crc)

        if input_crc == dev_crc:
            print "CRC matches"
            print "Resetting"
            self.reset()
        else:
            print "CRC DOES NOT MATCH"
Example #18
0
async def file_service():  # config r/w
    for cfg in os.listdir('configs'):
        if cfg.endswith('.json'):
            csa['cfgs'].append(cfg)

    sock = CDWebSocket(ws_ns, 'file')
    while True:
        dat, src = await sock.recvfrom()
        logger.debug(f'file ser: {dat}')

        if dat['action'] == 'get_cfgs':
            await sock.sendto(csa['cfgs'], src)

        elif dat['action'] == 'get_cfg':
            with open(os.path.join('configs', dat['cfg'])) as c_file:
                c = json5.load(c_file)
                await sock.sendto(c, src)

        elif dat['action'] == 'get_ihex':
            ret = []
            ih = IntelHex()
            try:
                ih.loadhex(dat['path'])
                segs = ih.segments()
                logger.info(
                    f'parse ihex file, segments: {[list(map(hex, l)) for l in segs]} (end addr inclusive)'
                )
                for seg in segs:
                    s = [seg[0], ih.tobinstr(seg[0], size=seg[1] - seg[0])]
                    ret.append(s)
            except Exception as err:
                logger.error(f'parse ihex file error: {err}')
            await sock.sendto(ret, src)

        else:
            await sock.sendto('err: file: unknown cmd', src)
Example #19
0
def main(argv):
    inputfile = ''
    port = ''
    split = 1024
    usage_string = 'huzzah_exotag_firmware.py -i <inputfile> -p <comm port:/dev/ttyUSB or \\\.\COM12>'
    try:
        opts, args = getopt.getopt(argv, "hi:p:s:",
                                   ["file=", "port=", "split="])
    except getopt.GetoptError:
        print()
        sys.exit(2)
    if not opts:
        print("no arguments provided ")
        print(usage_string)
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print(usage_string)
            sys.exit()
        elif opt in ("-i", "--file"):
            inputfile = arg
        elif opt in ("-p", "--port"):
            port = arg
        elif opt in ("-s", "--split"):
            split = int(arg)
        else:
            print("wrong arguments: " + opt)
            print(usage_string)

    print('input file: ' + inputfile)
    print('output port: ' + port)
    print('split in bytes: %d' % split)

    if inputfile.endswith('.hex'):
        ih = IntelHex()  # create empty object
        ih.padding = 0xFF
        ih.fromfile(inputfile, format='hex')  # also load from hex
        ascii_bin = binascii.hexlify(ih.tobinstr())
        #sys.exit()

    elif inputfile.endswith(
            '.bin'
    ):  #reconsider the extension here, the routine actually handles ascii
        with open(inputfile, 'r') as f:
            read_data = f.read()
            f.closed
        read_data = read_data.rstrip('\r\n')
        print(read_data)
        print([n for n in read_data])
        ascii_bin = read_data
        #binascii.unhexlify(read_data)
        #sys.exit()

    #print(ascii_bin)

    crc_result = binascii.crc32(ascii_bin) & 0xffffffff
    print("CRC = %08x" % crc_result)
    #sys.exit()

    exotag_uart = serial.Serial(port, 115200, timeout=1)
    exotag_uart_io = io.TextIOWrapper(
        io.BufferedRWPair(exotag_uart, exotag_uart))

    print('send start update: ' + unicode('exotag=update\r'))
    exotag_uart_io.write(unicode('exotag=update'.rstrip() + '\r'))
    exotag_uart_io.flush()
    time.sleep(1)
    #print (exotag_uart.readline())

    print('write')
    for i in range(0, len(ascii_bin), split):
        print((ascii_bin[i:i + split]))
        exotag_uart.write((ascii_bin[i:i + split]))
        exotag_uart_io.flush()
        time.sleep(1)

    print(binascii.hexlify(struct.pack("<I", crc_result)))
    exotag_uart.write('!'.encode() + struct.pack("<I", crc_result))
    exotag_uart_io.flush()
    #time.sleep(1)
    print('send end of firmware update')
    exotag_uart_io.write(unicode('~'))
    exotag_uart_io.flush()

    print('read exotag messages')
    exotag_string = exotag_uart_io.read()
    print("***********************\r\n" + exotag_string +
          "\r\n***********************")

    if (-1 != exotag_string.find('firmware update: SUCCESS')):

        print('tell huzzah to push update to exotag')
        exotag_uart_io.write(unicode('exotag=program'.rstrip() + '\r'))
        exotag_uart_io.flush()
        #time.sleep(10)

        print('read exotag messages')
        time.sleep(5)
        exotag_string = exotag_uart_io.read()
        print("***********************\r\n" + exotag_string +
              "\r\n***********************")
        if (-1 != exotag_string.find(
                'EFM8 flash write read-back verify success')):
            print(
                'EFM8 flash write read-back verify success - indicates SUCCESS'
            )

        print('reset exotag')
        exotag_uart_io.write(unicode('exotag=reset'.rstrip() + '\r'))
        exotag_uart_io.flush()
        time.sleep(5)
        exotag_string = exotag_uart_io.read()
        print("***********************\r\n" + exotag_string +
              "\r\n***********************")

    exotag_uart.close()
Example #20
0
    def post_process(self):
        logging.info("Processing binaries")

        fw_info_fmt = '<I16s128s16s128s16s'

        fw_info_addr = int(self.settings["FW_INFO_ADDR"], 16)

        # save original dir
        cwd = os.getcwd()

        # change to target dir
        os.chdir(self.target_dir)

        ih = IntelHex('main.hex')

        fwid = uuid.UUID('{' + self.settings["FWID"] + '}')

        # get KV meta start
        kv_meta_addr = fw_info_addr + struct.calcsize(fw_info_fmt)
        kv_meta_len = KVMetaField().size()

        bindata = ih.tobinstr()

        kv_meta_data = []

        while True:
            kv_meta = KVMetaField().unpack(bindata[kv_meta_addr:kv_meta_addr +
                                                   kv_meta_len])

            kv_meta_addr += kv_meta_len

            if kv_meta.param_name == "kvstart":
                continue

            elif kv_meta.param_name == "kvend":
                break

            else:
                kv_meta_data.append(kv_meta)

        kv_meta_by_hash = {}

        logging.info("Hash type: FNV1A_32")

        # create lookups by 32 bit hash
        index = 0
        for kv in kv_meta_data:
            hash32 = fnv1a_32(str(kv.param_name))

            if hash32 in kv_meta_by_hash:
                raise Exception("Hash collision!")

            kv_meta_by_hash[hash32] = (kv, index)

            index += 1

        # sort indexes
        sorted_hashes = sorted(kv_meta_by_hash.keys())

        # create binary look up table
        kv_index = ''
        for a in sorted_hashes:
            kv_index += struct.pack('<LB', a, kv_meta_by_hash[a][1])

        # write to end of hex file
        ih.puts(ih.maxaddr() + 1, kv_index)

        size = ih.maxaddr() - ih.minaddr() + 1

        # get os info
        try:
            os_project = get_project_builder(self.settings["OS_PROJECT"],
                                             target=self.target_type)
        except KeyError:
            os_project = ""

        # create firmware info structure
        fw_info = struct.pack(fw_info_fmt, size, fwid.bytes,
                              os_project.proj_name, os_project.version,
                              str(self.settings['PROJ_NAME']), self.version)

        # insert fw info into hex
        ih.puts(fw_info_addr, fw_info)

        # compute crc
        crc_func = crcmod.predefined.mkCrcFun('crc-aug-ccitt')

        crc = crc_func(ih.tobinstr())

        logging.info("size: %d" % (size))
        logging.info("fwid: %s" % (fwid))
        logging.info("fwinfo: %x" % (fw_info_addr))
        logging.info("kv index len: %d" % (len(kv_index)))
        logging.info("crc: 0x%x" % (crc))
        logging.info("os name: %s" % (os_project.proj_name))
        logging.info("os version: %s" % (os_project.version))
        logging.info("app name: %s" % (self.settings['PROJ_NAME']))
        logging.info("app version: %s" % (self.version))

        ih.puts(ih.maxaddr() + 1, struct.pack('>H', crc))

        ih.write_hex_file('main.hex')
        ih.tobinfile('firmware.bin')

        # get loader info
        loader_project = get_project_builder(self.settings["LOADER_PROJECT"],
                                             target=self.target_type)

        # create loader image
        loader_hex = os.path.join(loader_project.target_dir, "main.hex")
        self.merge_hex('main.hex', loader_hex, 'loader_image.hex')

        # create sha256 of binary
        sha256 = hashlib.sha256(ih.tobinstr())

        # create manifest file
        data = {
            'name': self.settings['FULL_NAME'],
            'timestamp': datetime.utcnow().isoformat(),
            'sha256': sha256.hexdigest(),
            'fwid': self.settings['FWID'],
            'version': self.version
        }

        with open('manifest.txt', 'w+') as f:
            f.write(json.dumps(data))

        # create firmware zip file
        zf = zipfile.ZipFile('chromatron_main_fw.zip', 'w')
        zf.write('manifest.txt')
        zf.write('firmware.bin')
        zf.close()

        # create second, project specific zip
        # we'll remove the first zip after
        # we update the firmware tools
        zf = zipfile.ZipFile('%s.zip' % (self.settings['PROJ_NAME']), 'w')
        zf.write('manifest.txt')
        zf.write('firmware.bin')
        zf.close()

        # change back to original dir
        os.chdir(cwd)

        logging.info("Package dir: %s" % (get_build_package_dir()))

        # make sure we have the firmware package dir
        try:
            os.makedirs(get_build_package_dir())

        except OSError:
            pass

        # copy firmware zip
        try:
            shutil.copy(
                os.path.join(self.target_dir, '%s.zip' % (self.proj_name)),
                get_build_package_dir())

        except IOError:
            raise AppZipNotFound

        # update build date
        with open(
                os.path.join(get_build_package_dir(),
                             firmware_package.PUBLISHED_AT_FILENAME),
                'w') as f:
            f.write(util.now().isoformat())
Example #21
0
 def get_file_buf(self, filename):
     fil = open(filename, 'r')
     hexfile = IntelHex(fil)
     glog.info('Min addr >> ', hexfile.minaddr())
     assert hexfile.minaddr() == 0
     return hexfile.tobinstr()
Example #22
0
                })

        if options.hexfiles:
            for hex in options.hexfiles:
                ih = IntelHex(hex)
                for (address, end) in ih.segments():
                    try:
                        address = address & 0xFFFFFFFF
                    except ValueError:
                        print "Address %s invalid." % address
                        sys.exit(1)
                    target.append({
                        'address':
                        address,
                        'data':
                        ih.tobinstr(start=address, end=end - 1)
                    })

        outfile = args[0]
        device = DEFAULT_DEVICE
        if options.device:
            device = options.device
        try:
            v, d = [int(x, 0) & 0xFFFF for x in device.split(':', 1)]
        except:
            print("Invalid device '%s'." % device)
            sys.exit(1)
        build(outfile, [target], DEFAULT_NAME, device)
    elif options.s19files and len(args) == 1:
        address = 0
        data = ""
Example #23
0
header_addr = prog.minaddr() # all programs require there header to be located at the start

# read out the header
header = ih2header(prog)

# optional updates
if args.pid != None and args.pid >= 0 and args.pid < 256:
	header['pid'] = args.pid
if args.key != None:
	header['key'] = args.key
if args.hw != None:
	header['hw_id'] = args.hw

# update the header len
l = prog.maxaddr() - prog.minaddr() + 1
header['len'] = l
prog = header2ih(prog, header) # put the length back into the intel hex file for crc

# update the header crc (note we do no include the CRC word in the CRC)
crc_start_addr = prog.minaddr() + 4
prog.padding = 0xff
buf = prog.tobinstr(start=crc_start_addr)
crc.crc_init(crc.stm32f10x_crc_h)
crc = crc.crc_buf(crc.stm32f10x_crc_h, buf, len(buf)) & 0xffffffff
header['crc'] = crc
prog = header2ih(prog, header) # put the crc back into the intel hex file so we can write it out

# write header back to hex file
prog.write_hex_file(sys.stdout)

Example #24
0
%prog {-i|--ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu"""

  parser = OptionParser(usage=usage)
  parser.add_option("-i", "--ihex", action="append", dest="hexfiles",
    help="build a DFU file from given HEXFILES", metavar="HEXFILES")
  parser.add_option("-D", "--device", action="store", dest="device",
    help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE")
  (options, args) = parser.parse_args()

  if options.hexfiles and len(args)==1:
    target = []
    
    for h in options.hexfiles:
      ih = IntelHex(h)
      for (s,e) in ih.segments():
        target.append({ 'address': s, 'data': ih.tobinstr(s,e-1) })
    
    outfile = args[0]
    device = DEFAULT_DEVICE
    if options.device:
      device=options.device
    try:
      v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
    except:
      print("Invalid device '%s'." % device)
      sys.exit(1)
    build(outfile,[target],device)
  else:
    parser.print_help()
    sys.exit(1)
    mergedHex.merge(fillHex, 'ignore')
    mergedHex = mergedHex[
        startAddr:endAddr]  # +1 since the last address is not inclusive
    mergedHex.padding = vargs.fill

    #if we are calculating metadata
    #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these
    #All onchip OAD images need metdata placement
    if not (vargs.oadtype == 'offchip' and
            (vargs.imgtype == 'production' or vargs.imgtype == 'np')):
        # Place metadata, onchip production image expects header at 0x600
        if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
            residentHdr = OadHdr._make(
                struct.unpack(
                    OAD_HDR_FMT,
                    mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN,
                                       INT_FL_OAD_IMG_A_META_BEGIN + 15)))
        else:
            residentHdr = OadHdr._make(
                struct.unpack(OAD_HDR_FMT,
                              mergedHex.tobinstr(startAddr, startAddr + 15)))
        metaAddr = vargs.meta
        if metaAddr is None:
            # Try first address, ideally there should be free space at the beginning of the image
            #in the reserved image metadata sector
            #if onchip production image, we must start at imgA start with is 0x600
            if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
                attemptedMetaStart = INT_FL_OAD_IMG_A_META_BEGIN
            else:
                attemptedMetaStart = mergedHex.minaddr()

            beginning = mergedHex.gets(attemptedMetaStart, OAD_METADATA_SIZE)
ih = IntelHex(fw_file)

sig = base64.b64decode(helpers.from_websafe(data["versions"][">2.5.3"]["signature"]).encode())

client = solo.client.find()
client.use_hid()

if not client.is_solo_bootloader():
    print("[!] Please put the SoloKey in bootloader mode")
    exit(1)

# desired_version = b"\x03\x00\x00\x00"    # make the bootloader believe we're flashing 3.0.0.0
# desired_version = b"\x03\x00\x00\x02"    # make the bootloader believe we're flashing 3.0.0.2
desired_version = b"\x03\x00\x25\x00"  # make the bootloader believe we're flashing 3.0.37.0

version_offset = ih.tobinstr().find(desired_version)
correct_version_offset = ih.tobinstr().rfind(b"\x03\x00\x00\x00")
if version_offset == -1:
    print("Cannot find version bytes!")
    exit(1)

print("[+] Using version bytes at offset 0x{:x} instead of 0x{:x}".format(version_offset, correct_version_offset))

print("[+] Flashing firmware...")
chunk_size = 2048
start_address, end_address = ih.segments()[0]
version_bytes_address = start_address + version_offset

for chunk_start in tqdm(range(start_address, end_address, chunk_size)):
    chunk_end = min(chunk_start + chunk_size, end_address)
    data = ih.tobinarray(start=chunk_start, size=chunk_end - chunk_start)
Example #27
0
                except ValueError:
                    print("Address %s invalid." % address)
                    sys.exit(1)
                if not os.path.isfile(binfile):
                    print("Unreadable file '%s'." % binfile)
                    sys.exit(1)
                target.append({
                    'address': address,
                    'data': open(binfile, 'rb').read()
                })

        if options.hexfiles:
            for hex in options.hexfiles:
                ih = IntelHex(hex)
                address = ih.minaddr()
                data = ih.tobinstr()
                try:
                    address = address & 0xFFFFFFFF
                except ValueError:
                    print("Address %s invalid." % address)
                    sys.exit(1)
                target.append({'address': address, 'data': data})

        outfile = args[0]
        device = DEFAULT_DEVICE
        if options.device:
            device = options.device
        try:
            v, d = map(lambda x: int(x, 0) & 0xFFFF, device.split(':', 1))
        except:
            print("Invalid device '%s'." % device)
Example #28
0
			print "    Freqency=%03.02f Mhz (calculated)" % freq
			
		except:	
			print "%s: Cannot decode frequency" % name
		
		
dump=IntelHex(source)

# Unpack fields
# 14 - String - Working station
#  2 = HEX    - Working CRC
# 14 - String - Factory station
#  2 = HEX    - Factory CRC

#payload = list(unpack_from('<14sH14sH17sBB2s13s17s', dump.tobinstr()))
payload = list(unpack_from('<14sH', dump.tobinstr()))

#if not (eyecatcher in payload[9]):
	#print "NOTE:Eyecatcher text string not found"


print "---Working"
dump_freq(payload[0], payload[1])
print "---Factory"
dump_freq(payload[2], payload[3])

print "SN: %s" % payload[4].strip('\000')
print "WW: %d" % payload[5]
print "YY: %d" % payload[6]
print "Station: %s" % payload[7]
print "Campaign: %s" % payload[8].strip('\000')
Example #29
0
# read out the header
header = ih2header(prog)

# optional updates
if args.pid != None and args.pid >= 0 and args.pid < 256:
    header['pid'] = args.pid
if args.key != None:
    header['key'] = args.key
if args.hw != None:
    header['hw_id'] = args.hw

# update the header len
l = prog.maxaddr() - prog.minaddr() + 1
header['len'] = l
prog = header2ih(prog,
                 header)  # put the length back into the intel hex file for crc

# update the header crc (note we do no include the CRC word in the CRC)
crc_start_addr = prog.minaddr() + 4
prog.padding = 0xff
buf = prog.tobinstr(start=crc_start_addr)
crc.crc_init(crc.stm32f10x_crc_h)
crc = crc.crc_buf(crc.stm32f10x_crc_h, buf, len(buf)) & 0xffffffff
header['crc'] = crc
prog = header2ih(
    prog,
    header)  # put the crc back into the intel hex file so we can write it out

# write header back to hex file
prog.write_hex_file(sys.stdout)
Example #30
0
    # if specified, the script will pad the image with the pad value
    fillHex = IntelHex()
    fillHex.puts(startAddr, struct.pack("B", vargs.fill) * (endAddr))
    mergedHex.merge(fillHex, "ignore")
    mergedHex = mergedHex[startAddr:endAddr]  # +1 since the last address is not inclusive
    mergedHex.padding = vargs.fill

    # if we are calculating metadata
    # Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these
    # All onchip OAD images need metdata placement
    if not (vargs.oadtype == "offchip" and (vargs.imgtype == "production" or vargs.imgtype == "np")):
        # Place metadata, onchip production image expects header at 0x600
        if vargs.oadtype == "onchip" and vargs.imgtype == "production":
            residentHdr = OadHdr._make(
                struct.unpack(
                    OAD_HDR_FMT, mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_META_BEGIN + 15)
                )
            )
        else:
            residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(startAddr, startAddr + 15)))
        metaAddr = vargs.meta
        if metaAddr is None:
            # Try first address, ideally there should be free space at the beginning of the image
            # in the reserved image metadata sector
            # if onchip production image, we must start at imgA start with is 0x600
            if vargs.oadtype == "onchip" and vargs.imgtype == "production":
                attemptedMetaStart = INT_FL_OAD_IMG_A_META_BEGIN
            else:
                attemptedMetaStart = mergedHex.minaddr()

            beginning = mergedHex.gets(attemptedMetaStart, OAD_METADATA_SIZE)
Example #31
0
def main():
    platforms = [x.name.lower() for x in Platform]
    functions = [x.name.lower() for x in ModuleFunction]
    flags = [x.name.lower() for x in ModuleFlags]
    parser = argparse.ArgumentParser(
        description='Convert a raw binary into a Particle module binary')
    parser.add_argument('input',
                        metavar='INPUT',
                        type=argparse.FileType('rb'),
                        help='Input raw bin file')
    parser.add_argument('output',
                        metavar='OUTPUT',
                        type=argparse.FileType('wb'),
                        help='Output Particle module bin file')
    parser.add_argument('--address',
                        default=0,
                        type=int,
                        help='Start address of the module')
    parser.add_argument(
        '--version',
        default=0,
        type=int,
        help='Module version (automatically derived for Gen 3 SoftDevice)')
    parser.add_argument('--platform',
                        required=True,
                        help='Module platform name',
                        choices=platforms)
    parser.add_argument('--function',
                        required=True,
                        help='Module function',
                        choices=functions)
    parser.add_argument('--index',
                        default=0,
                        type=int,
                        help='Module index number')
    parser.add_argument('--dependency',
                        default=[],
                        nargs=3,
                        action='append',
                        metavar=('FUNCTION', 'VERSION', 'INDEX'),
                        help='Module dependency')
    parser.add_argument('--mcu', type=int, default=0, help='MCU target')
    parser.add_argument('--flag',
                        default=[],
                        help='Module flag',
                        action='append',
                        choices=flags)

    args = parser.parse_args()

    dependencies = [parse_dependency(x) for x in args.dependency]
    platform = Platform[args.platform.upper()]
    function = ModuleFunction[args.function.upper()]
    flags = reduce(lambda x, y: x | y,
                   [ModuleFlags[x.upper()] for x in args.flag],
                   ModuleFlags.NONE)
    version = args.version

    if not args.input.name.endswith('.hex'):
        bin = args.input.read()
    else:
        try:
            from intelhex import IntelHex
            # Reopen in non-binary mode :|
            name = args.input.name
            args.input.close()
            with open(args.input.name, 'r') as f:
                ihex = IntelHex(f)
                bin = ihex.tobinstr()
        except ImportError:
            print('`intelhex` library is required for hex file support')
            sys.exit(1)
        except:
            raise

    # Special handling for Gen 3 SoftDevice
    if platform in GEN3_PLATFORMS and function == ModuleFunction.RADIO_STACK and args.version == 0:
        (version, ) = struct.unpack_from('<H', bin,
                                         GEN3_RADIO_STACK_VERSION_OFFSET)
        if len(dependencies) == 0:
            dependencies = [
                GEN3_RADIO_STACK_DEPENDENCY, GEN3_RADIO_STACK_DEPENDENCY2
            ]
        if args.address == 0:
            # Skip MBR
            args.address = GEN3_RADIO_STACK_MBR_OFFSET
            bin = bin[GEN3_RADIO_STACK_MBR_OFFSET:]
        if len(args.flag) == 0:
            flags = GEN3_RADIO_STACK_FLAGS

    m = Module(bin,
               args.address,
               platform,
               function,
               version,
               args.index,
               flags,
               dependencies,
               mcu=args.mcu)
    args.output.write(m.dump())
    print(m)
Example #32
0
class ShdlcFirmwareImage(object):
    """
    This class represents a firmware image for an SHDLC device. It is used to
    load and verify Intel-Hex files for performing firmware updates over SHDLC.

    Since the different SHDLC devices use different memory layouts, this class
    needs to know the bootloader base address and application base address (see
    constructor parameters). Drivers for specific SHDLC devices should create a
    subclass to provide a new type which already contains the correct
    addresses, so users don't have to care about these details.

    .. note:: This class is intended only for devices which contain the SHDLC
              bootloader. Devices which support firmware updates with another
              system aren't supported by this class.

    .. note:: The package ``intelhex`` must be installed to use this class. See
              :ref:`firmware-updater-dependencies` for details.
    """

    _PRODUCT_TYPE_SIZE = 4  # Product type size

    def __init__(self,
                 hexfile,
                 bl_start_addr,
                 app_start_addr,
                 signature=b'\x4A\x47\x4F\x4B',
                 bl_version_offset=0x1004):
        """
        Constructor which loads and parses the firmware from a hex file.

        :param str/file hexfile:    The filename or file-like object containing
                                    the firmware in Intel-Hex format (\\*.hex).
        :param int bl_start_addr:   The base address of the bootloader inside
                                    the firmware image.
        :param int app_start_addr:  The base address of the application
                                    inside the firmware image.
        :param bytes signature:     Signature bytes used for the application.
        :param int bl_version_offset: Bootloader version address offset.

        :raise ~sensirion_shdlc_driver.errors.ShdlcFirmwareImageSignatureError:
            If the signature of the image is invalid.
        """
        # Import intelhex here to allow importing the firmware_image module
        # without having the intelhex package installed (it's an optional
        # dependency, so it might be missing).
        from intelhex import IntelHex
        self._bl_start_addr = int(bl_start_addr)
        self._app_start_addr = int(app_start_addr)
        self._signature = bytes(bytearray(signature))
        self._bl_version_offset = int(bl_version_offset)
        self._app_data_index = 0
        self._data = IntelHex(hexfile)
        self._data.padding = 0xFF  # is returned when reading undefined regions
        log.debug(
            "Loaded hex file: {} [minaddr=0x{:08X}, maxaddr=0x{:08X}]".format(
                hexfile, self._data.minaddr(), self._data.maxaddr()))
        self._check_signature()
        log.debug("Signature: OK")
        self._product_type = self._read_product_type()
        log.debug("Product type: 0x{:08X}".format(self._product_type))
        self._bootloader_version = self._read_bootloader_version()
        log.debug("Bootloader version: {}".format(self._bootloader_version))
        self._application_version = self._read_application_version()
        log.debug("Application version: {}".format(self._application_version))
        self._app_data = self._read_application_data()
        log.debug("Application size: {:.2f} kB".format(self.size / 1024))
        self._checksum = self._calc_application_checksum()
        log.debug("Application checksum: 0x{:02X}".format(self._checksum))

    @property
    def product_type(self):
        """
        Get the product type for which the loaded firmware is made.

        :return: Product type as an integer.
        :rtype: int
        """
        return self._product_type

    @property
    def bootloader_version(self):
        """
        Get the bootloader version which is contained in the loaded image.

        :return: Bootloader version (note: debug flag is not supported, it's
                 always False).
        :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion
        """
        return self._bootloader_version

    @property
    def application_version(self):
        """
        Get the application firmware version which is contained in the loaded
        image.

        :return: Application firmware version (note: debug flag is not
                 supported, it's always False).
        :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion
        """
        return self._application_version

    @property
    def checksum(self):
        """
        Get the checksum over the application firmware part of the loaded
        image. This is the checksum which needs to be sent to the product
        bootloader.

        :return: Checksum as a byte.
        :rtype: byte
        """
        return self._checksum

    @property
    def size(self):
        """
        Get the size of the application firmware.

        :return: Size in bytes.
        :rtype: int
        """
        return len(self._app_data)

    @property
    def available_bytes(self):
        """
        Get the count of available bytes left.

        :return: Count of available bytes.
        :rtype: int
        """
        return len(self._app_data) - self._app_data_index

    def read(self, size=-1):
        """
        Read the next bytes of the application firmware.

        :param int size:    Maximum count of bytes to read (-1 reads all
                            available)
        :return:            Firmware data block.
        :rtype: bytes
        """
        if size < 0:
            size = self.available_bytes
        else:
            size = min(size, self.available_bytes)
        data = self._app_data[self._app_data_index:self._app_data_index + size]
        self._app_data_index += len(data)
        return bytes(data)  # immutable type to avoid modifying image data

    def _check_signature(self):
        """
        Check the signature of the loaded image and throw an exception if it's
        invalid.
        """
        signature = self._read_bytes(self._app_start_addr,
                                     len(self._signature))
        if signature != self._signature:
            raise ShdlcFirmwareImageSignatureError(signature)

    def _read_product_type(self):
        """
        Read the product type from the loaded image.

        :return: The read product type.
        :rtype: int
        """
        address = self._app_start_addr + len(self._signature)
        return self._read_uint32(address)

    def _read_bootloader_version(self):
        """
        Read the bootloader version from the loaded image.

        :return: The read bootloader version.
        :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion
        """
        addr_major = self._bl_start_addr + self._bl_version_offset + 1
        addr_minor = self._bl_start_addr + self._bl_version_offset
        return FirmwareVersion(major=self._data[addr_major],
                               minor=self._data[addr_minor],
                               debug=False)

    def _read_application_version(self):
        """
        Read the application version from the loaded image.

        :return: The read application version.
        :rtype: ~sensirion_shdlc_driver.types.FirmwareVersion
        """
        addr_major = self._app_start_addr + len(self._signature) + \
            self._PRODUCT_TYPE_SIZE + 1
        addr_minor = self._app_start_addr + len(self._signature) + \
            self._PRODUCT_TYPE_SIZE
        return FirmwareVersion(major=self._data[addr_major],
                               minor=self._data[addr_minor],
                               debug=False)

    def _read_application_data(self):
        """
        Read the application data block from the loaded image.

        :return: The read application data block.
        :rtype: bytearray
        """
        # Skip the signature because it must not be sent to the bootloader!
        start_addr = self._app_start_addr + len(self._signature)
        if self._bl_start_addr > self._app_start_addr:
            end_addr = self._bl_start_addr - 1  # Don't include bootloader
        else:
            end_addr = self._data.maxaddr()
        return bytearray(self._data.tobinarray(start=start_addr, end=end_addr))

    def _read_uint32(self, address):
        """
        Read an uint32 at a specific image address.

        :param int address: The address to read from.
        :return: The integer at the specified address.
        :rtype: int
        """
        return unpack("<I", self._data.tobinarray(start=address, size=4))[0]

    def _read_bytes(self, address, number_of_bytes):
        """
        Read at a specific image address.

        :param int address: The address to read from.
        :param int number_of_bytes: Number of bytes to read
        :return: The bytes from the specified address.
        :rtype: bytes
        """
        return self._data.tobinstr(start=address, size=number_of_bytes)

    def _calc_application_checksum(self):
        """
        Calculate the checksum over the application data, as needed for the
        firmware download command.

        :return: Checksum of application data
        :rtype: byte
        """
        return (sum(self._app_data) % 256) ^ 0xFF
Example #33
0
def cmd_update(args):
    if args.reset_tty:
        sys.stdout.write("resetting to bootloader via serial\n")
        serial = Tl866Driver(args.reset_tty)
        serial.cmd_reset_to_bootloader()

        # wait for the device to show up
        devs = None
        stop_time = time.time() + 5  # timeout 5s
        while not devs and time.time() < stop_time:
            time.sleep(0.100)
            devs = driver.list_devices()

    dev = find_dev()

    report = dev.report()
    if report.status != dev.STATUS_BOOTLOADER:
        sys.stdout.write("resetting to bootloader\n")
        dev.reset()

        report = dev.report()
        if report.status != dev.STATUS_BOOTLOADER:
            sys.stderr.write("device did not reset to booloader\n")
            sys.exit(2)

    model_a = (report.model == dev.MODEL_TL866A)

    # load the firmware image
    stock = None
    image = None
    if args.stock:
        with open(args.firmware, 'rb') as source:
            stock = firmware.UpdateFile(source.read())
            image = firmware.Firmware(
                stock.a_firmware if model_a else stock.cs_firmware,
                encrypted=True,
            )
    else:
        with open(args.firmware, 'r') as source:
            hexfile = IntelHex(source)
            image = firmware.Firmware(
                hexfile.tobinstr(start=0x1800, end=0x1FBFF),
                encrypted=False,
            )

    # load encryption and erase keys
    target_key = None
    target_erase = None
    if args.keys_from:
        with open(args.keys_from, 'rb') as source:
            keyfile = firmware.UpdateFile(source.read())
            keyfw = firmware.Firmware(
                keyfile.a_firmware if model_a else keyfile.cs_firmware,
                encrypted=True,
            )
            target_key = keyfw.key
            target_erase = keyfile.a_erase if model_a else keyfile.cs_erase
    elif stock:
        target_key = image.key
        target_erase = stock.a_erase if model_a else stock.cs_erase
    else:
        target_key = firmware.KEY_A if model_a else firmware.KEY_CS
        target_erase = firmware.ERASE_A if model_a else firmware.ERASE_CS

    if not image.valid:
        raise RuntimeError("firmware image invalid")

    sys.stdout.write("erasing\n")
    dev.erase(target_erase)

    sys.stdout.write("programming\n")
    addr = 0x1800
    cryptbuf = image.encrypt(target_key)
    for off in range(0, len(cryptbuf), 80):
        dev.write(addr, 80, cryptbuf[off:off + 80])
        addr += 64

    sys.stdout.write("success!\n")

    report = dev.report()
    if report.status != dev.STATUS_NORMAL:
        sys.stdout.write("resetting to firmware\n")
        dev.reset()
Example #34
0

def parse_args():
    parser = argparse.ArgumentParser(
        description='Hash data from file.',
        formatter_class=argparse.RawDescriptionHelpFormatter)

    parser.add_argument(
        '--infile',
        '-i',
        '--in',
        '-in',
        required=True,
        help=
        'Hash the contents of the specified file. If a *.hex file is given, the contents will '
        'first be converted to binary, with all non-specified area being set to 0xff. '
        'For all other file types, no conversion is done.')
    return parser.parse_args()


if __name__ == '__main__':
    args = parse_args()

    if args.infile.endswith('.hex'):
        ih = IntelHex(args.infile)
        ih.padding = 0xff  # Allows hashing with empty regions
        to_hash = ih.tobinstr()
    else:
        to_hash = open(args.infile, 'rb').read()
    sys.stdout.buffer.write(hashlib.sha256(to_hash).digest())
Example #35
0
    mergedHex.merge(fillHex, 'ignore')
    mergedHex = mergedHex[
        startAddr:endAddr]  # +1 since the last address is not inclusive
    mergedHex.padding = vargs.fill

    #if we are calculating metadata
    #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these
    #All onchip OAD images need metdata placement
    if not (vargs.oadtype == 'offchip' and
            (vargs.imgtype == 'production' or vargs.imgtype == 'np')):
        # Place metadata, onchip production image expects header at 0x600
        if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
            residentHdr = OadHdr._make(
                struct.unpack(
                    OAD_HDR_FMT,
                    mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN,
                                       INT_FL_OAD_IMG_A_META_BEGIN + 15)))
        else:
            residentHdr = OadHdr._make(
                struct.unpack(OAD_HDR_FMT,
                              mergedHex.tobinstr(startAddr, startAddr + 15)))
        metaAddr = vargs.meta
        if metaAddr is None:
            # Try first address, ideally there should be free space at the beginning of the image
            #in the reserved image metadata sector
            #if onchip production image, we must start at imgA start with is 0x600
            if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
                attemptedMetaStart = INT_FL_OAD_IMG_A_META_BEGIN
            else:
                attemptedMetaStart = mergedHex.minaddr()

            beginning = mergedHex.gets(attemptedMetaStart, OAD_METADATA_SIZE)
Example #36
0
        checkbin(binfile)
        target.append({ 'address': address, 'data': open(binfile,'rb').read() })

    if options.hexfiles:
      if not IntelHex:
        print("Error: IntelHex python module could not be found")
        sys.exit(1)
      for hex in options.hexfiles:
        ih = IntelHex(hex)
        for (address,end) in ih.segments():
          try:
            address = address & 0xFFFFFFFF
          except ValueError:
            print "Address %s invalid." % address
            sys.exit(1)
          target.append({ 'address': address, 'data': ih.tobinstr(start=address, end=end-1)})

    outfile = args[0]
    device = DEFAULT_DEVICE
    if options.device:
      device=options.device
    try:
      v,d=[int(x,0) & 0xFFFF for x in device.split(':',1)]
    except:
      print("Invalid device '%s'." % device)
      sys.exit(1)
    build(outfile,[target],DEFAULT_NAME,device)
  elif options.s19files and len(args)==1:
    address = 0
    data = ""
    target = []
Example #37
0
    raise ApplicationError, 'No any DKSF*.hex files found!'
hexfn = sorted(hexfnlist, key=os.path.getmtime)[-1]
print
print os.path.abspath(hexfn)

bootfn = glob.glob('..\\..\\Bootloader_Debug\\Exe\\*.hex')
if len(bootfn) != 1:
    raise ApplicationError, 'More than one bootloader .hex file found!'
bootfn = os.path.abspath(bootfn[0])
print bootfn

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!'
Example #38
0
%prog {-i|--ihex} file.hex [-i file.hex ...] [{-D|--device}=vendor:device] outfile.dfu"""

  parser = OptionParser(usage=usage)
  parser.add_option("-i", "--ihex", action="append", dest="hexfiles",
    help="build a DFU file from given HEXFILES", metavar="HEXFILES")
  parser.add_option("-D", "--device", action="store", dest="device",
    help="build for DEVICE, defaults to %s" % DEFAULT_DEVICE, metavar="DEVICE")
  (options, args) = parser.parse_args()

  if options.hexfiles and len(args)==1:
    target = []
    
    for h in options.hexfiles:
      ih = IntelHex(h)
      for (s,e) in ih.segments():
        target.append({ 'address': s, 'data': ih.tobinstr(s,e-1) })
    
    outfile = args[0]
    device = DEFAULT_DEVICE
    if options.device:
      device=options.device
    try:
      v,d=map(lambda x: int(x,0) & 0xFFFF, device.split(':',1))
    except:
      print "Invalid device '%s'." % device
      sys.exit(1)
    build(outfile,[target],device)
  else:
    parser.print_help()
    sys.exit(1)
Example #39
0
          sys.exit(1)
        try:
          address = int(address,0) & 0xFFFFFFFF
        except ValueError:
          print("Address %s invalid." % address)
          sys.exit(1)
        if not os.path.isfile(binfile):
          print("Unreadable file '%s'." % binfile)
          sys.exit(1)
        target.append({ 'address': address, 'data': open(binfile,'rb').read() })
    
    if options.hexfiles:
      for hex in options.hexfiles:
        ih = IntelHex(hex)
        address = ih.minaddr()
        data = ih.tobinstr()
        try:
          address = address & 0xFFFFFFFF
        except ValueError:
          print("Address %s invalid." % address)
          sys.exit(1)
        target.append({ 'address': address, 'data': data })

    revision = DEFAULT_REVISION
    if options.revision:
        try:
            rev2byte(options.revision)
            revision  = options.revision
        except ValueError:
            print("Invalid revision value.")
            sys.exit(1)
Example #40
0
    #if specified, the script will pad the image with the pad value
    fillHex = IntelHex()
    fillHex.puts(startAddr, struct.pack('B', vargs.fill) * (endAddr))
    mergedHex.merge(fillHex, 'ignore')
    mergedHex = mergedHex[startAddr:endAddr] # +1 since the last address is not inclusive
    mergedHex.padding = vargs.fill


    #if we are calculating metadata
    #Offchip OAD production images and NP images don't have embedded metadata headers, skip meta data calc for these
    #All onchip OAD images need metdata placement
    if not(vargs.oadtype == 'offchip' and (vargs.imgtype == 'production' or vargs.imgtype == 'np')):
        # Place metadata, onchip production image expects header at 0x600
        if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
            residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN, INT_FL_OAD_IMG_A_META_BEGIN+15)))
        else:
            residentHdr = OadHdr._make(struct.unpack(OAD_HDR_FMT, mergedHex.tobinstr(startAddr, startAddr+15)))
        metaAddr = vargs.meta
        if metaAddr is None:
            # Try first address, ideally there should be free space at the beginning of the image
            #in the reserved image metadata sector
            #if onchip production image, we must start at imgA start with is 0x600
            if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
                attemptedMetaStart = INT_FL_OAD_IMG_A_META_BEGIN
            else:
                attemptedMetaStart = mergedHex.minaddr()

            beginning = mergedHex.gets(attemptedMetaStart, OAD_METADATA_SIZE)

Example #41
0
out = open(sys.argv[2], 'wb')

# 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])
Example #42
0
    else:
        imgLen = int(math.ceil(
            (endAddr - startAddr) / 4.0))  # Image length in words
        imgVer = vargs.imgVer  # Offchip OAD has no requirements for LSB

    usrId = vargs.usrId
    imgAddr = startAddr / 4  # In words
    imgType = imgTypes[vargs.imgtype]
    crcShdw = 0xffff

    meta = struct.pack('HHHH4sHBB', crcShdw, crcShdw, imgVer, imgLen, usrId,
                       imgAddr, imgType, META_STATUS_SUCCESS)
    mergedHex.puts(metaAddr, meta)
    #production image only calculates over imgA region
    if vargs.oadtype == 'onchip' and vargs.imgtype == 'production':
        asBin = mergedHex.tobinstr(INT_FL_OAD_IMG_A_META_BEGIN,
                                   INT_FL_OAD_IMG_A_END)
    else:
        asBin = mergedHex.tobinstr(startAddr, endAddr - 1)
    crc = crc16(asBin[4:])
    mergedHex.puts(metaAddr, struct.pack('H', crc))

    metaVector = OadHdr._make([
        crc, crcShdw, imgVer, imgLen, usrId, imgAddr, imgType,
        META_STATUS_SUCCESS
    ])

    print_metadata(metaVector)

    if vargs.out and not (vargs.out is sys.stdout
                          and vargs.outbin is sys.stdout):
        print("Writing to:\n", vargs.out.name)
Example #43
0
		print "%s: CRC mismatch" % name
	else:
		(band, deemph, spacing, chan, vol) = unpack('<BBBHB8x', info)
		try:
			freq = calc_freq(band, spacing, chan)
			print "%s: Freq %.2f MHz" % (name, freq)
		except:
			print "%s: Cannot decode frequency" % name

		print "    Band: %02x" % band
		print "    Deemphasis: %02x" % deemph
		print "    Spacing: %02x" % spacing
		print "    Channel: %d" % chan
		print "    Volume: %02x" % vol

dump=IntelHex(source)

payload = list(unpack_from('<14sH14sH17sBB2s13s17s', dump.tobinstr()))

if eyecatcher in payload[9]:
	dump_freq(payload[0], payload[1], "Working")
	dump_freq(payload[2], payload[3], "Factory")

	print "SN: %s" % payload[4].strip('\000')
	print "WW: %d" % payload[5]
	print "YY: %d" % payload[6]
	print "Station: %s" % payload[7]
	print "Campaign: %s" % payload[8].strip('\000')
else:
	sys.exit(1)
Example #44
0
def get_bootloader_hex_image(bootoaderFile):
    hex = IntelHex(bootoaderFile)
    hex.padding = 0x00

    hexImage = hex.tobinstr(BOOTLOADER_START_ADDRESS, BOOTLOADER_END_ADDRESS)
    return hexImage