def act_pack(args): args = loadconfigs(args, "pack") params = {} def cnn(v): if args[v] is None: print "Expected '%s' argument for sdb packing" % v sys.exit(1) return args[v] params["maintainer_name"] = cnn("maintainer") params["repository_url"] = args.get("repository","UNKNOWN") params["version"] = cnn("version") params["build_date"] = str(datetime.datetime.now()) params["changeset_id"] = args.get("changeset","UNKNOWN") params["description"] = cnn("description") params["short_name"] = cnn("name") params["tool_versions"] = [] if args["tool"] is None: args["tool"] = [] for tl in args["tool"]: try: tool, version = tl.split("=") params["tool_versions"].append((tool, version)) except ValueError: print "Invalid tool version specification '%s'. " % tl print "Expected 'toolname=version'" sys.exit(1) cell = SLCell.generate(params, args["elf"]) oname = args.get("outfile", params["short_name"]+".sdb") if args["assetlist"] is not None: f = open(args["assetlist"],"r") for l in f.readlines(): l = l.strip() if len(l) == 0 or l.startswith("#"): continue la = l.split() if len(la) != 4: print "Asset manifest syntax is <i/x> <addr/*> <name> <filename>" print "got: ", repr(la) sys.exit(1) intex, addr, name, filename = la if intex not in ["i","x"]: print "Incorrect location specifier for flash asset: allowed 'i' or 'x'" sys.exit(1) _add_asset(cell, {"internal": intex == "i", "name": name, "asset": filename, "addr": None if addr == "*" else addr}) cell.save(oname)
def act_cloudflash(args): args = loadconfigs(args, "cloudflash") imgl = args["image"].split(":", 1) if len(imgl) != 2: print "bad image descriptor, expected ns:name" ithen = time.time() if args["verbose"]: print "Downloading image ", sys.stdout.flush() r = requests.get("http://cloud.storm.rocks/r/"+imgl[0]+"/"+imgl[1]) if args["verbose"]: print "done (%.3f seconds)" %(time.time() - ithen) if len(r.content) == 0: print "Could not download image" sys.exit(1) with tempfile.NamedTemporaryFile() as ntf: try: ntf.write(r.content) ntf.flush() sl = sl_api.StormLoader(args.get("tty", None)) sl.enter_bootload_mode() then = time.time() try: cell = SLCell.load(ntf.name) except: print "SDB image is corrupt" sys.exit(1) img = cell.get_raw_image() sl.write_extended_irange(cell.FLASH_BASE, img) now = time.time() if args["verbose"]: print "Wrote %d bytes in %.3f seconds" %(len(img), now-then) expected_crc = sl.crc32(img) written_crc = sl.c_crcif(cell.FLASH_BASE, len(img)) if expected_crc != written_crc: print "CRC failure: expected 0x%04x, got 0x%04x" % (expected_crc, written_crc) sys.exit(1) elif args["verbose"]: print "CRC pass" sl.enter_payload_mode() except sl_api.StormloaderException as e: print "Fatal error:", e sys.exit(1)
def act_list_assets(args): args = loadconfigs(args, "assetlist") cell = SLCell.load(args["sdb"]) iassets = cell.list_iassets() eassets = cell.list_eassets() def pr_assets_human(assets): print " # Address Length Name" for (i, a) in assets: print "{:>2d} 0x{:07x} 0x{:05x} {}".format(i, a["address"], a["length"], a["name"]) def pr_assets_header(assets): s1s = [] s2s = [] s3s = [] for (i, a) in assets: s1s.append(("#define ASSET_{}_NAME".format(a["name"].upper()), "\"{}\"".format(a["name"]))) s2s.append(("#define ASSET_{}_ADDR".format(a["name"].upper()), "0x{:07x}".format(a["address"]))) s3s.append(("#define ASSET_{}_LEN".format(a["name"].upper()), "0x{:05x}".format(a["length"]))) longest = max(len(i[0]) for i in (s1s+s2s+s3s)) for i in s1s+s2s+s3s: print ("{:<%ds} {}" % longest).format(*i) if len(iassets) > 0: print "Internal flash assets" if not args["header"]: pr_assets_human(iassets) else: pr_assets_header(iassets) else: print "No internal flash assets" print "" if len(eassets) > 0: print "External flash assets" if not args["header"]: pr_assets_human(eassets) else: pr_assets_header(eassets) else: print "No external flash assets"
def act_flash_assets(args): try: args = loadconfigs(args, "assetflash") sl = sl_api.StormLoader(args.get("tty", None)) sl.enter_bootload_mode() then = time.time() cell = SLCell.load(args["sdb"]) for i, a in cell.list_iassets(): body = a["contents"] if args["verbose"]: print "writing %s to iflash @ 0x%x (%d : 0x%x bytes)... " %\ (a["name"],a["address"],a["length"],a["length"]), sys.stdout.flush() sl.write_extended_irange(a["address"], body) if args["verbose"]: print "ok" for i, a in cell.list_eassets(): body = a["contents"] if args["verbose"]: print "writing %s to xflash @ 0x%x (%d : 0x%x bytes)... " %\ (a["name"],a["address"],a["length"],a["length"]), sys.stdout.flush() sl.write_extended_xrange(a["address"], body) ecrc = sl.crc32(body) rcrc = sl.c_crcef(a["address"], a["length"]) if ecrc != rcrc: print "CRC FAIL! (expected 0x%08x, got 0x%08x" % (ecrc, rcrc) sys.exit(1) if args["verbose"]: print "ok" now = time.time() if args["verbose"]: print "%.2f seconds" % (now-then) sl.enter_payload_mode() except sl_api.StormloaderException as e: print "Fatal error:", e sys.exit(1)
def act_flash(args, ftdi_device_id=None): try: args = loadconfigs(args, "flash") sl = sl_api.StormLoader(args.get("tty", None), device_id=ftdi_device_id) sl.enter_bootload_mode() then = time.time() cell = SLCell.load(args["sdb"]) img = cell.get_raw_image() sl.write_extended_irange(cell.FLASH_BASE, img) now = time.time() if args["verbose"]: print "Wrote %d bytes in %.3f seconds" %(len(img), now-then) expected_crc = sl.crc32(img) written_crc = sl.c_crcif(cell.FLASH_BASE, len(img)) if expected_crc != written_crc: print "CRC failure: expected 0x%04x, got 0x%04x" % (expected_crc, written_crc) sys.exit(1) elif args["verbose"]: print "CRC pass" sl.enter_payload_mode() except sl_api.StormloaderException as e: print "Fatal error:", e sys.exit(1)
def act_hexdump(args): args = loadconfigs(args, "hexdump") cell = SLCell.load(args["sdb"]) print cell.get_hex_image()
def act_add_asset(args): args = loadconfigs(args, "assetadd") cell = SLCell.load(args["sdb"]) _add_asset(cell, args) cell.save(args["sdb"])
def act_program_kernel_payload(args, ftdi_device_id=None): cache_file = '.cached_payload' if ftdi_device_id is None else '.cached_payload_{0}'.format(ftdi_device_id) try: eximage = open(cache_file,"r").read() except: eximage = None try: args = loadconfigs(args, "program") params = {} params["maintainer_name"] = "UNKNOWN" params["repository_url"] ="UNKNOWN" params["version"] = "UNKNOWN" params["build_date"] = str(datetime.datetime.now()) params["changeset_id"] = "UNKNOWN" params["description"] = "UNKNOWN" params["short_name"] = "UNKNOWN" params["tool_versions"] = [] cell = SLCell.generate(params, args["elf"]) img = cell.get_raw_image()[0x40000:] #was 0x4... sl = sl_api.StormLoader(args.get("tty", None), device_id=ftdi_device_id) sl.enter_bootload_mode() print "Probing payload ELF for entry point..." _start = cell.locate_symbol("_start") if _start != None: print "Located _start at 0x%06x" % _start print "Setting entrypoint attribute" sl.c_sattr(1,"_start", [_start & 0xFF, (_start >> 8) & 0xFF, (_start >> 16) & 0xFF, (_start >> 24) & 0xFF ]) else: print "Could not locate _start! This payload will not boot!" def wfull(): print "Writing full payload..." idx = 0 retries = 0 then = time.time() while idx < len(img): endslice = idx + 0x200 if endslice > len(img): endslice = len(img) sl.write_extended_irange(0x50000 + idx, img[idx:endslice]) expected_crc = sl.crc32(img[idx:endslice]) written_crc = sl.c_crcif(0x50000 + idx, endslice-idx) if (expected_crc != written_crc): #print ("expected page: ") a = (" ".join("%02x" % ord(c) for c in img[idx:endslice])) #print a rpage = sl.read_extended_irange(0x50000 + idx, 0x200) #print ("got page: ") b = (" ".join("%02x" % ord(c) for c in rpage)) #print b print ("slice crc mismatch at 0x%x"%(0x50000 + idx)) print "mismatches in bytes: ", [i/3 for i in xrange(len(b)) if a[i] != b[i]] #sl.c_epage(0x50000+idx) retries += 1 if (retries == 5): print("hit max retries") print("aborting. please report") sys.exit(1) else: retries = 0 idx += 0x200 now = time.time() expected_crc = sl.crc32(img) written_crc = sl.c_crcif(0x50000, len(img)) print "Image is 0x%x bytes long" % (len(img)) if expected_crc != written_crc: print "CRC failure: expected 0x%04x, got 0x%04x" % (expected_crc, written_crc) sys.exit(1) print "Wrote and verified %d bytes in %.3f seconds" %(len(img), now-then) if eximage != None: excrc = sl.crc32(eximage) realcrc = sl.c_crcif(0x50000, len(eximage)) if excrc != realcrc: print "Payload cached contents do not match (this will take longer)" wfull() else: newimg = img oldimg = eximage if len(newimg) % 512 != 0: newimg += "\xFF"*(512 - (len(newimg)%512)) if len(oldimg) < len(newimg): old_end = len(oldimg) &~ 511 start_address = (0x50000 + old_end) sl.write_extended_irange(start_address, newimg[old_end:]) oldimg = oldimg[:old_end] oldimg += newimg[old_end:] assert len(oldimg) >= len(newimg) def fix_difference(): for idx in xrange(len(newimg)): if oldimg[idx] != newimg[idx]: page_address = idx &~511 real_address = page_address + 0x50000 if args["verbose"]: print "Changed page at 0x%08x" % real_address sl.c_wpage(real_address, newimg[page_address:page_address+512]) # oldimg[page_address:page_address+512] = newimg[page_address:page_address+512] newoldimg = oldimg[:page_address] + newimg[page_address:page_address+512] + \ oldimg[page_address + 512:] return (True, newoldimg) return (False, oldimg) then = time.time() for i in xrange(len(oldimg)+1): changes, oldimg = fix_difference() if not changes: expected_crc = sl.crc32(newimg) written_crc = sl.c_crcif(0x50000, len(newimg)) if expected_crc != written_crc: print "CRC failure: expected 0x%04x, got 0x%04x" % (expected_crc, written_crc) sys.exit(1) elif args["verbose"]: print "CRC pass" print "Written and verified in %.2f seconds" % (time.time() - then) break else: raise sl.StormloaderException("Delta algorithm bug detected") else: print "No cached contents (this will take longer)" wfull() with open(cache_file,"w") as f: f.write(img) sl.enter_payload_mode() except sl_api.StormloaderException as e: print "Fatal error:", e sys.exit(1)
def act_delta(args, ftdi_device_id=None): args = loadconfigs(args, "flashdelta") sl = sl_api.StormLoader(args.get("tty", None), device_id=ftdi_device_id) sl.enter_bootload_mode() newcell = SLCell.load(args["newimg"]) newimg = newcell.get_raw_image() def full_flash(): then = time.time() #write the whole img sl.write_extended_irange(SLCell.FLASH_BASE, newimg) expected_crc = sl.crc32(newimg) written_crc = sl.c_crcif(SLCell.FLASH_BASE, len(newimg)) if expected_crc != written_crc: print "CRC failure: expected 0x%04x, got 0x%04x" % (expected_crc, written_crc) sys.exit(1) elif args["verbose"]: print "CRC pass" sl.enter_payload_mode() if args["verbose"]: print "Written and verified in %.2f seconds" % (time.time() - then) return #We also permit an empty file to be specified as the old image #this represents null if not (os.path.exists(args["oldimg"]) and os.path.isfile(args["oldimg"])) or os.stat(args["oldimg"]).st_size == 0: if args["verbose"]: print "Old image is empty, doing full flash" full_flash() return oldcell = SLCell.load(args["oldimg"]) oldimg = oldcell.get_raw_image() oldimgcrc = sl.crc32(oldimg) actualcrc = sl.c_crcif(sl.FLASH_FLOOR, len(oldimg)) if oldimgcrc != actualcrc: print "Actual contents do not match expected image, this will take longer" full_flash() return if len(newimg) % 512 != 0: newimg += "\xFF"*(512 - (len(newimg)%512)) if len(oldimg) < len(newimg): old_end = len(oldimg) &~ 511 start_address = (sl.FLASH_FLOOR + old_end) sl.write_extended_irange(start_address, newimg[old_end:]) oldimg = oldimg[:old_end] oldimg += newimg[old_end:] assert len(oldimg) >= len(newimg) def fix_difference(): for idx in xrange(len(newimg)): if oldimg[idx] != newimg[idx]: page_address = idx &~511 real_address = page_address + oldcell.FLASH_BASE if args["verbose"]: print "Changed page at 0x%08x" % real_address sl.c_wpage(real_address, newimg[page_address:page_address+512]) # oldimg[page_address:page_address+512] = newimg[page_address:page_address+512] newoldimg = oldimg[:page_address] + newimg[page_address:page_address+512] + \ oldimg[page_address + 512:] return (True, newoldimg) return (False, oldimg) then = time.time() for i in xrange(len(oldimg)+1): changes, oldimg = fix_difference() if not changes: expected_crc = sl.crc32(newimg) written_crc = sl.c_crcif(oldcell.FLASH_BASE, len(newimg)) if expected_crc != written_crc: print "CRC failure: expected 0x%04x, got 0x%04x" % (expected_crc, written_crc) sys.exit(1) elif args["verbose"]: print "CRC pass" print "Written and verified in %.2f seconds" % (time.time() - then) break else: raise sl.StormloaderException("Delta algorithm bug detected") sl.enter_payload_mode()