def cli(): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-daemon {} - Collaborative board access daemon\n".format(rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_terminal_opts(parser) helper.add_file_handling_opts(parser) helper.add_resetseq_options(parser, resets) parser.add_argument("-L", "--listen", help="Specify address:port to listen (default 0.0.0.0:10000)", nargs=1, metavar=('listen'), default=["0.0.0.0:10000"], required=False) opts = parser.parse_args() chip, term, reset = helper.create_core_stuff_from_options(opts) c = helper.detect_chip_type(opts, chips, formats) if opts.log: term.logstream = opts.log srv = server(term, opts.listen[0]) srv.set_reset_seq(reset) if "file" in opts: srv.preload_binaries(opts.file) return srv.loop()
def cli(): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-daemon {} - Collaborative board access daemon\n". format(rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_terminal_opts(parser) helper.add_file_handling_opts(parser) helper.add_resetseq_options(parser, resets) parser.add_argument( "-L", "--listen", help="Specify address:port to listen (default 0.0.0.0:10000)", nargs=1, metavar=('listen'), default=["0.0.0.0:10000"], required=False) parser.add_argument( "-m", "--max-usage-time", help= "Specify maximum time a client can use the board before being kicked (seconds)", default=360, type=int, required=False) parser.add_argument( "--execute-binaries-from-temp-dir", help= "Super-special debug mode. Mock a bootrom, receive upload binaries and exec them", action="store_true", required=False) opts = parser.parse_args() if opts.execute_binaries_from_temp_dir: opts.port = "loop://" chip, term, reset = helper.create_core_stuff_from_options(opts) c = helper.detect_chip_type(opts, chips, formats) if opts.log: term.logstream = opts.log srv = server(term, opts.listen[0], opts.max_usage_time, opts.execute_binaries_from_temp_dir) srv.set_reset_seq(reset) if "file" in opts: srv.preload_binaries(opts.file) return srv.loop()
def cli(): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-daemon {} - Collaborative board access daemon\n". format(rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_terminal_opts(parser) helper.add_file_handling_opts(parser) helper.add_resetseq_options(parser, resets) parser.add_argument( "-L", "--listen", help="Specify address:port to listen (default 0.0.0.0:10000)", nargs=1, metavar=('listen'), default=["0.0.0.0:10000"], required=False) opts = parser.parse_args() c = helper.detect_chip_type(opts, chips, formats) if c == None: c = chips["basis"] return 1 print("Detected chip: %s (%s)" % (c.name, c.part)) if c == None: print("ERROR: Failed to auto-detect chip type") return 1 if opts.baud == None: opts.baud = [c.baudrate] reset = resets[opts.reset[0]](opts) if opts.log: term.logstream = opts.log print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud[0])) print("Serial Port: %s" % opts.port[0]) print("Listen address: %s" % opts.listen) term = terminal(opts.port[0], opts.baud[0]) srv = server(term, opts.listen[0]) srv.set_reset_seq(reset) if "file" in opts: srv.preload_binaries(opts.file) return srv.loop()
def __init__(self, target_chip=None, transport="xmodem", args=None): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") c = chips[target_chip] parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description= "Rumboot Scripting Engine script, using rumboot-tools {}\n".format( rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_terminal_opts(parser) helper.add_resetseq_options(parser, resets) opts = parser.parse_args() dump_path = os.path.dirname(__file__) + "/romdumps/" helper.detect_terminal_options(opts, c) print("Target Chip: %s (%s)" % (c.name, c.part)) if c == None: raise Exception("ERROR: Failed to auto-detect chip type") if opts.baud == None: opts.baud = [c.baudrate] reset = resets[opts.reset[0]](opts) term = terminal(opts.port[0], opts.baud[0]) term.set_chip(c) try: romdump = open(dump_path + c.romdump, "r") term.add_dumps({'rom': romdump}) except: pass if opts.log: term.logstream = opts.log print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud[0])) print("Port: %s" % opts.port[0]) if opts.edcl and c.edcl != None: term.xfer.selectTransport("edcl") print("Preferred data transport: %s" % term.xfer.how) print("--- --- --- --- --- --- --- --- --- ") self.terminal = term self.xfer = term.xfer
def intialize_testing(target_chip=None): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") c = chips[target_chip] parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-factorytest {} - RumBoot Board Testing Framework\n" .format(rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_terminal_opts(parser) helper.add_resetseq_options(parser, resets) opts = parser.parse_args() dump_path = os.path.dirname(__file__) + "/romdumps/" helper.detect_terminal_options(opts, c) print("Detected chip: %s (%s)" % (c.name, c.part)) if c == None: print("ERROR: Failed to auto-detect chip type") return 1 if opts.baud == None: opts.baud = [c.baudrate] reset = resets[opts.reset[0]](opts) term = terminal(opts.port[0], opts.baud[0]) term.set_chip(c) try: romdump = open(dump_path + c.romdump, "r") term.add_dumps({'rom': romdump}) except: pass if opts.log: term.logstream = opts.log print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud[0])) print("Port: %s" % opts.port[0]) if opts.edcl and c.edcl != None: term.xfer.selectTransport("edcl") print("Preferred data transport: %s" % term.xfer.how) print("--- --- --- --- --- --- ") return term, reset
def create_core_stuff_from_options(self, opts): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") c = self.detect_chip_type(opts, chips, formats) if not c: return None, None, None print("Detected chip: %s (%s)" % (c.name, c.part)) if c == None: raise Exception("ERROR: Failed to auto-detect chip type") if opts.baud == None: opts.baud = c.baudrate params_for_xfers = { "force_static_arp": opts.force_static_arp, "default": "xmodem" } if opts.edcl: params_for_xfers["default"] = "edcl" if opts.edcl_ip: params_for_xfers["edcl_ip"] = opts.edcl_ip if opts.edcl_mac: params_for_xfers["edcl_mac"] = opts.edcl_mac if opts.edcl_timeout: params_for_xfers["edcl_timeout"] = opts.edcl_timeout term = terminal(opts.port, opts.baud, xferparams=params_for_xfers) reset = resets[opts.reset[0]](term, vars(opts)) term.set_chip(c) reset.set_chip(c) print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud)) print("Port: %s" % opts.port) print("Preferred data transport: %s" % params_for_xfers["default"]) return c, term, reset
def cli(): parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description= "rumboot-packimage {} - Universal RumBoot Image Manipulation Tool\n". format(rumboot.__version__) + rumboot.__copyright__) parser.add_argument("-f", "--file", help="image file", type=argparse.FileType("r+b"), required=True) parser.add_argument("-i", "--info", help="Show information about the image", action="store_true") parser.add_argument( "-c", "--checksum", help= '''This option will modify the file! Calculates valid checksums to the header. The length is set to cover the full length of file ONLY if it's zero. ''', action="store_true") parser.add_argument( "-C", "--checksum_fix_length", help= "This option will modify the file! The same as --checksum/-c, but always overrides length to covert the full length of file", action="store_true") parser.add_argument("-r", "--raw", help="Display raw header field names", action="store_true") parser.add_argument( '-R', '--relocate', nargs=1, metavar=('relocation'), help= '''Tell bootrom to relocate the image at the specified address before executing it. Only RumBootV3 and above ''') parser.add_argument( '-Z', '--compress', action="store_true", help='''Compress image data with heatshrink algorithm (V3 or above only) ''') parser.add_argument( '-U', '--decompress', action="store_true", help= '''Decompress image data with heatshrink algorithm (V3 or above only) ''') parser.add_argument( '-z', '--add_zeroes', nargs=1, metavar=('value'), help= '''This option will add N bytes of zeroes to the end of the file (after checksummed area). This is required to avoid propagating 'X' during the next image check during simulation. Normally, you do not need this option ''') parser.add_argument( '-a', '--align', nargs=1, metavar=('value'), help= '''Pad resulting image size to specified alignment. Remember to add -C to have correct checksums! ''') parser.add_argument( '-F', '--flag', action="append", nargs=2, metavar=('value'), help='''Set image flag to a desired value. Only RumBootV3 or above ''') parser.add_argument('--set-data', action="append", nargs=2, metavar=('offset', 'value'), help='''Sets data at byte 'offset' to value 'offset' ''') parser.add_argument( '-g', '--get', nargs=1, metavar=('key'), help='''Get a single field from header. Nothing else will be printed. NOTE: The value will be formatted as hex ''') parser.add_argument( '-s', '--set', nargs=2, metavar=('key', 'value'), help= '''This option will modify the file! Set a header key to specified value. Use -r flag on an existing image to find out what keys exist. Use -c to update the checksums ''') parser.add_argument( '-e', '--reverse-endianness', action="store_true", help= '''Use this option to reverse endianness of all headers. This will not touch data. For testing only ''') parser.add_argument( '-w', '--wrap', nargs=1, help='''Use this option to wrap arbitrary data to V1/V2/V3 images. ''') opts = parser.parse_args() formats = ImageFormatDb("rumboot.images") t = formats.guess(opts.file) if opts.wrap: if t != False: print( f"File {opts.file.name} already wrapped into rumboot format ({t})" ) return 1 t = formats.wrap(opts.file, opts.wrap[0]) print(f"Wrapped file {opts.file.name} with {t.name} header") calc_data = True if (t == False): if not opts.wrap: print("ERROR: Not a valid image, see README.md") else: print("ERROR: Failed to wrap data into image for some reason") return 1 if opts.set != None: t.set(opts.set[0], opts.set[1]) #FixMe: Hack if (opts.set[0] == "data_crc32"): calc_data = False opts.info = True print("Setting " + opts.set[0] + " to " + opts.set[1]) if not opts.checksum: print("WARNING: Add -c option to update checksums!") if opts.compress: if not hasattr(t, "compress"): print( "ERROR: Image (de)compression is not supported by this image format" ) return 1 t.compress() opts.checksum_fix_length = True opts.checksum = True opts.info = True if opts.decompress: if not hasattr(t, "decompress"): print( "ERROR: Image (de)compression is not supported by this image format" ) return 1 t.decompress() opts.checksum_fix_length = True opts.checksum = True opts.info = True if opts.relocate: if not hasattr(t, "relocate"): print("ERROR: Relocation is not supported by this image format") return 1 t.relocate(opts.relocate[0]) opts.info = True if not opts.checksum: print("WARNING: Add -c option to update checksums!") if opts.get: print("0x%x" % t.get(opts.get[0])) return 0 if opts.reverse_endianness: t.swap_endian() if opts.set_data: for f in opts.set_data: t.write8(t.get_header_length() + int(f[0]), int(f[1])) if opts.flag: for f in opts.flag: if not hasattr(t, "flag"): print( "ERROR: Image flags are not supported by this image format" ) return 1 t.flag(f[0], bool(strtobool(f[1]))) if opts.align: t.align(opts.align[0]) opts.checksum_fix_length = True if (opts.checksum_fix_length): t.fix_length() opts.info = True if opts.checksum or opts.checksum_fix_length: t.fix_checksums(calc_data) print("Wrote valid checksums to image header") opts.info = True if opts.add_zeroes: t.add_zeroes(opts.add_zeroes[0]) if opts.info: t.read_header() #Return non-zero on invalid data/header crc, except for error-injection cases if not t.dump_header(opts.raw) and not opts.set: return 1 return 0
class terminal: verbose=True logstream=None plusargs={} initial_loop_done = False runlist = [] formats = ImageFormatDb("rumboot.images") chip = chipBase() dumps = {} curbin = "bootrom" progress = tqdm(disable=True) replay = False replay_till_the_end = False ser = None cmdline = None xfer = None desc_widget = None prog_widget = None shell_prompt = None def __init__(self, port, speed): self.port = port self.speed = speed self.xfer = xferManager(self) self.reopen() def serial(self): return self.ser def reopen(self): if self.ser != None: self.ser.close() self.ser = None if self.port.find("file://") == 0: self.ser = open(self.port.replace("file://",""), "rb+") self.replay = True elif self.port.find("://") < 0: self.ser = serial.Serial(self.port, self.speed, timeout=5) else: self.ser = serial.serial_for_url(self.port, timeout=5) self.opf = OpFactory("rumboot.ops", self) def set_chip(self, chip): self.chip = chip self.xfer.setChip(chip) def tqdm(self, *args, **kwargs): self.progress.close() self.progress = tqdm(*args, **kwargs) def add_binaries(self, path): if type(path) is list: for p in path: self.runlist.append(p[0]) else: self.runlist.append(path) def add_dumps(self, dumps): self.dumps.update(dumps) def next_binary(self, peek=False): if len(self.runlist) > 0: ret = self.runlist[0] if not peek: self.runlist.pop(0) self.curbin = ret return ret return None def current_binary(self): return self.curbin def current_dump(self): if self.curbin == "bootrom": return self.dumps["rom"] if self.curbin.name in self.dumps: return self.dumps[self.curbin.name] def log(self, skipecho, *args, **kwargs): # Sometimes we get a weird exception on certain windows systems/setups # Try to catch any exceptions and dispose of them here try: if not skipecho and self.verbose: self.progress.write(*args, **kwargs) sys.stdout.flush() if not self.logstream == None: self.logstream.write(*args) self.logstream.write("\n") except: pass def sync(self): if not self.replay: self.ser.reset_input_buffer() c1 = b'a' c2 = b'd' while True: c2 = self.ser.read(1) if c1 == b'U' and c2 == b'\r': break if c1 == b'U' and c2 == b'\n': break c1 = c2 def hack(self, name): if name in self.chip.hacks and self.chip.hacks[name]: return True return False def set_progress_widgets(self, desc_widget = None, prog_widget = None): self.desc_widget = desc_widget self.prog_widget = prog_widget def progress_start(self, description, total): if self.prog_widget == None: self.tqdm(desc=description, total=total, unit_scale=True, unit_divisor=1024, unit='B', disable=False) else: pass def progress_update(self, total, position, increment): self.progress.update(increment) def progress_end(self): self.tqdm(disable=True) def wait(self, format, timeout=1000): while True: line = self.ser.read_until() line = line.decode(errors="replace").rstrip() self.log(False, line, end='\n') ret = parse(format, line) if ret != None: return ret def shell_mode(self, prompt): self.shell_prompt = prompt def wait_prompt(self, initial=False): if initial: self.ser.write(b"\r\n") found = False data = b"" while True: ret = self.ser.read_until(self.shell_prompt.encode()) data = data + ret ret = ret.decode(errors="replace") self.log(False, ret, end='\n') if ret.find(self.shell_prompt) > -1: found = True if not initial: break if found and len(ret) == 0: break return data def shell_cmd(self, cmd, timeout=10, initial=False): if initial: self.wait_prompt(initial) cmd = cmd.encode() + b"\r" self.ser.write(cmd) ret = self.wait_prompt(False).decode(errors="replace") ret = ret[len(cmd):] ret = ret[:-len(self.shell_prompt)-2] return ret def loop(self, use_stdin=False, break_after_uploads=False, timeout=-1): if not self.initial_loop_done: self.initial_loop_done = True self.opf.on_start() return_code = 0 time_start = time.time() if use_stdin: old_settings = termios.tcgetattr(sys.stdin) try: if use_stdin: tty.setcbreak(sys.stdin.fileno()) if not self.hack("skipsync"): self.sync() while True: ret = None if use_stdin : line = b'' sym = b'' while sym != b'\n': if select.select([self.ser], [], [], 0) == ([self.ser], [], []): sym = self.ser.read(1) line = line + sym sys.stdout.write(str(sym, 'utf-8', errors='replace')) sys.stdout.flush() if select.select([sys.stdin], [], [], 0) == ([sys.stdin], [], []): insym = sys.stdin.read(1) self.ser.write(insym.encode()) else: line = self.ser.readline() if timeout >= 0 and time.time() - time_start > timeout: return_code = 5 break if line == b'': continue try: line = line.decode().rstrip() except: continue ret = self.opf.handle_line(line, use_stdin) if type(ret) is int: if not self.replay_till_the_end: return ret else: return_code = ret if break_after_uploads and len(self.runlist) == 0: break if self.replay: if (self.ser.tell() == os.fstat(self.ser.fileno()).st_size): print("== END OF LOG REACHED ==") break finally: if use_stdin: termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings) return return_code
def cli(): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-gdb {} - Debugger launcher tool\n".format( rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_terminal_opts(parser) parser.add_argument( "-v", "--verbose", action='store_true', default=False, help="Print serial debug messages during preload phase"), parser.add_argument("-z", "--spl-path", help="Path for SPL writers (Debug only)", type=str, required=False) parser.add_argument("-L", "--load", help="Load binary on start", action='store_true', default=False, required=False) parser.add_argument("-f", "--file", help="Application ELF file to debug", type=str, required=False) parser.add_argument( "-x", "--exec", help="Execute supplied binary on start (Implies --load)", action='store_true', default=False, required=False) parser.add_argument("-R", "--rebuild", help="Attempt to rebuild binary", action='store_true', default=False, required=False) parser.add_argument("--debug-remote", help="Send 'set debug remote 1' to gdb for debugging", action='store_true', default=False, required=False) parser.add_argument("--debug-serial", help="Send 'set debug serial 1' to gdb for debugging", action='store_true', default=False, required=False) parser.add_argument("-g", "--gdb-path", help="Path to flashrom binary", type=str, required=False) parser.add_argument("-G", "--gdb-gui", help="Start GDB gui", action='store_true', default=False, required=False) parser.add_argument("-c", "--chip_id", help="Chip Id (numeric or name)", required=True) parser.add_argument('remaining', nargs=argparse.REMAINDER, default=[], help="Extra gdb arguments (e.g. filename)") helper.add_resetseq_options(parser, resets) opts = parser.parse_args() if opts.remaining and opts.remaining[0] == "--": opts.remaining = opts.remaining[1:] gdb_args = " ".join(opts.remaining) c = chips[opts.chip_id] if (c == None): return 1 helper.detect_terminal_options(opts, c) print("Detected chip: %s (%s)" % (c.name, c.part)) if c.warning != None: print(" --- WARNING ---") print(c.warning) print(" --- WARNING ---") print("") spl_path = os.path.dirname(__file__) + "/tools/" if opts.baud == None: opts.baud = [c.baudrate] reset = resets[opts.reset[0]](opts) term = terminal(opts.port[0], opts.baud[0]) term.verbose = opts.verbose term.set_chip(c) if opts.log: term.logstream = opts.log try: spl = c.stub except: print("ERROR: Target chip (%s) doesn't have a gdb stub" % (c.name)) return 1 if opts.spl_path != None: spl_path = opts.spl_path print("SPL %s" % (spl_path + c.stub)) spl = spl_path + c.stub if opts.gdb_path: gdb = opts.gdb_path else: gdb = c.gdb print(opts.rebuild, opts.file) if opts.rebuild and opts.file != None: if 0 != os.system("cmake --build . --target " + opts.file): os.exit(1) print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud[0])) print("Port: %s" % opts.port[0]) print("GDB: %s" % gdb) if opts.edcl and c.edcl != None: term.xfer.selectTransport("edcl") reset.resetToHost() term.add_binaries(spl) term.loop(break_after_uploads=True) while True: s = term.ser.readline() if opts.verbose: print(s) if s.decode("utf-8", errors="replace").find("STUB READY!") != -1: break print("gdb-stub is ready for operations, starting gdb..") # If we're here, we'll need to setup socket redirector port = 20000 while True: try: print("Trying port %d" % port) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(("127.0.0.1", port)) server.listen() break except: port = port + 1 if port > 30000: print("Weird shit going on, breaking") break #Fire up flashrom in background if opts.gdb_gui: flr = ipgdbgui() else: flr = ipgdb() if opts.debug_remote: flr.add_command("set debug remote 1") if opts.debug_serial: flr.add_command("set debug serial 1") if opts.file != None: gdb_args = gdb_args + opts.file flr.configure(gdb, port, gdb_args) if opts.load or opts.exec: flr.add_command("load") if opts.exec: flr.add_command("continue") flr.start() #Accept connection connection, client_address = server.accept() connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) rd = redirector() rd.configure(term.ser, connection) rd.start() return flr.join()
def cli(): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-xrun {} - RumBoot X-Modem execution tool\n".format(rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_file_handling_opts(parser, True) helper.add_terminal_opts(parser) helper.add_resetseq_options(parser, resets) plus = parser.add_argument_group("Plusargs parser options", """ rumboot-xrun can parse plusargs (similar to verilog simulator) and use them for runtime file uploads. This option is intended to be used for """) plus.add_argument('-A', '--plusargs', nargs='*') parser.add_argument("-R", "--rebuild", help="Attempt to rebuild/update target before uploading", action="store_true", default=False, required=False) parser.add_argument("-I", '--stdin', help="Use stdin redirection to tty", action="store_true", default=False, required=False) parser.add_argument('--replay-no-exit', help="Do not exit on panics/rom returns when replaying logs (for batch analysis)", action="store_true", default=False, required=False) if len(sys.argv) == 1: sys.argv = sys.argv + ["--help"] opts = parser.parse_args() #Open files, rebuild if needed opts.file[0], dumps = helper.process_files(opts.file[0], opts.rebuild) dump_path = os.path.dirname(__file__) + "/romdumps/" plusargs = {} if opts.plusargs: for a in opts.plusargs: ret = parse("+{}={}", a) if ret: plusargs[ret[0]] = ret[1] continue ret = parse("+{}", a) if ret: plusargs[ret[0]] = True c = helper.detect_chip_type(opts, chips, formats) if c == None: return 1 print("Detected chip: %s (%s)" % (c.name, c.part)) if c == None: print("ERROR: Failed to auto-detect chip type") return 1 if opts.baud == None: opts.baud = [ c.baudrate ] reset = resets[opts.reset[0]](opts) term = terminal(opts.port[0], opts.baud[0]) term.set_chip(c) term.plusargs = plusargs term.xfer.xfers["edcl"].force_static_arp = opts.force_static_arp try: romdump = open(dump_path + c.romdump, "r") term.add_dumps({'rom' : romdump}) except: pass if opts.log: term.logstream = opts.log print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud[0])) print("Port: %s" % opts.port[0]) reset.resetToHost() term.add_binaries(opts.file) term.add_dumps(dumps) term.replay_till_the_end = opts.replay_no_exit if opts.edcl and c.edcl != None: term.xfer.selectTransport("edcl") print("Preferred data transport: %s" % term.xfer.how) return term.loop(opts.stdin)
def rumboot_start_flashing(partmap=None): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-xflash {} - RumBoot firmware updater tool\n". format(rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_file_handling_opts(parser, True) helper.add_terminal_opts(parser) parser.add_argument("-v", "--verbose", default=False, action='store_true', help="Print serial debug messages during update"), parser.add_argument("-m", "--memory", help="Memory program. Help for a list of memories", metavar=('memory'), default="help") parser.add_argument("-z", "--spl-path", help="Path for SPL writers (Debug only)", type=str, required=False) parser.add_argument( "--no-spl", help="Do not upload spl, assume it boots on it's own (Debug only)", action="store_true", default=False, required=False) parser.add_argument("-o", "--offset", help="Memory offset for read/write operations", type=int, default=0, required=False) parser.add_argument( "-L", "--length", help="How many bytes to read/write (defaults to whole file/flash)", type=int, default=-1, required=False) parser.add_argument("-R", "--read", help="Read flash to file", action='store_true', required=False) parser.add_argument("-W", "--write", help="Write flash from file", default=False, action='store_true', required=False) parser.add_argument("-E", "--erase", help="Erase flash", default=False, action='store_true', required=False) parser.add_argument("-F", "--firmware-file", help="Write firmware from configuration file", type=argparse.FileType("r"), default=None, required=False) parser.add_argument("-U", "--upload-baudrate", help="Change baudrate for uploads", default=0, type=int, required=False) helper.add_resetseq_options(parser, resets) opts = parser.parse_args() chip = helper.detect_chip_type(opts, chips, formats) if not chip: return 1 mem = opts.memory if mem == "help": print(f"Available memories for chip '{chip.name}'") for mem, cfg in chip.memories.items(): print("%16s: %s" % (mem, cfg["comment"])) return 1 chip, term, reset = helper.create_core_stuff_from_options(opts) if opts.read and opts.write: print("Please select either --read or --write, not both") return 1 #Open files, rebuild if needed #opts.file[0], dumps = helper.process_files(opts.file[0], False) spl_path = os.path.dirname(__file__) + "/spl-tools/" try: config = chip.memories[mem] mem = config["device"] except: print( "ERROR: Target chip (%s) doesn't have memory '%s'. Run with -m help for a list" % (chip.name, mem)) return 1 if opts.spl_path != None: spl_path = opts.spl_path print("SPL %s" % (spl_path + chip.memories[mem])) spl = spl_path + config["spl"] term.verbose = opts.verbose if not opts.no_spl: term.add_binaries(spl) if opts.edcl and chip.edcl != None: term.xfer.selectTransport("edcl") try: reset.resetToHost() except: print("WARN: Reset method doesn't support HOST mode switching") print("WARN: If things don't work - check jumpers!") reset.reset() term.loop(break_after_uploads=True) flashers = FlashAlgoFactory("rumboot.flashing", config["protocol"]) flasher = flashers[mem](term, config) # ------------------------ offset = opts.offset length = -1 if "offset" in config: offset += config["offset"] if "size" in config: flasher.size = config["size"] flasher.dump() if opts.file and len(opts.file) > 1: print("ERROR: Only one file may be specified") return 1 if opts.file and len(opts.file) == 0: return 1 if opts.upload_baudrate == 0 and hasattr(chip, "flashbaudrate"): opts.upload_baudrate = chip.flashbaudrate if opts.upload_baudrate > 0: print(f"WARN: Changing baudrate to {opts.upload_baudrate} bps") print( "WARN: If everything freezes - try a different setting via -U / --upload-baudrate" ) flasher.switchbaud(opts.upload_baudrate) term.xfer.connect(chip) runlist = [] if opts.firmware_file is None: part = flasher.add_partition(mem, opts.offset, opts.length) if opts.write: action = { "partition": part, "action": "write", "file": opts.file[0][0] } runlist.append(action) if opts.read: action = { "partition": part, "action": "read", "file": opts.file[0][0] } runlist.append(action) if opts.erase: action = {"partition": part, "action": "erase", "file": None} runlist.append(action) else: runlist = parse_firmware_file(opts.firmware_file, flasher) execute_runlist(term, spl, runlist) if opts.firmware_file or opts.write: print("Saving environment and partition information") flasher.save_partitions() flasher.saveenv() return 1
def cli(): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-flashrom {} - flashrom wrapper tool\n".format( rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_terminal_opts(parser) parser.add_argument( "-v", "--verbose", action='store_true', default=False, help="Print serial debug messages during preload phase"), parser.add_argument( "-m", "--memory", help="SPI bus to use. Names match '-m help' of rumboot-xflash", nargs=1, metavar=('memory'), default="help", required=True) parser.add_argument("-z", "--spl-path", help="Path for SPL writers (Debug only)", type=str, required=False) parser.add_argument("-f", "--flashrom-path", help="Path to flashrom binary", type=str, required=False) parser.add_argument("-c", "--chip_id", help="Chip Id (numeric or name)", required=True) parser.add_argument('remaining', nargs=argparse.REMAINDER, default=[], help="Flashrom arguments") # parser.add_argument('-F', '--flashrom-args', nargs='*', default=[], ) helper.add_resetseq_options(parser, resets) opts = parser.parse_args() if opts.remaining and opts.remaining[0] == "--": opts.remaining = opts.remaining[1:] flashrom_args = " ".join(opts.remaining) c = chips[opts.chip_id] if (c == None): return 1 helper.detect_terminal_options(opts, c) print("Detected chip: %s (%s)" % (c.name, c.part)) if c.warning != None: print(" --- WARNING ---") print(c.warning) print(" --- WARNING ---") print("") spl_path = os.path.dirname(__file__) + "/tools/" if opts.baud == None: opts.baud = [c.baudrate] reset = resets[opts.reset[0]](opts) term = terminal(opts.port[0], opts.baud[0]) term.verbose = opts.verbose term.set_chip(c) if opts.log: term.logstream = opts.log mem = opts.memory[0] if not mem: return 1 if mem == "help": for mem, spl in c.flashrom.items(): print("Memory %16s: %s" % (mem, spl)) return 1 try: spl = c.flashrom[mem] except: print( "ERROR: Target chip (%s) doesn't have bus '%s'. Run with -m help for a list" % (c.name, mem)) return 1 if opts.spl_path != None: spl_path = opts.spl_path print("SPL %s" % (spl_path + c.flashrom[mem])) spl = spl_path + c.flashrom[mem] print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud[0])) print("Port: %s" % opts.port[0]) flashrom = None flashrom_paths = [ "/usr/local/sbin/flashrom", "/sbin/flashrom", "/usr/sbin/flashrom", "C:\\flashrom\\flashrom.exe" ] if opts.flashrom_path and os.path.exists(opts.flashrom_path): flashrom = opts.flashrom_path elif opts.flashrom_path: print("[W] Specified flashrom path (%s) is invalid, trying to guess" % opts.flashrom_path) for f in flashrom_paths: if os.path.exists(f): flashrom = f if flashrom == None: print( "FATAL: Failed to find working flashrom. Please download and install from https://flashrom.org/" ) return 1 print("FlashRom: %s" % flashrom) print("FlashRom args: %s" % flashrom_args) reset.resetToHost() term.add_binaries(spl) term.loop(break_after_uploads=True) while True: s = term.ser.readline() if s.decode("utf-8", errors="replace").find("SERPROG READY!") != -1: break print("Serprog stub ready!") if opts.port[0].find("socket://") == -1: #Use flashrom directly ret = os.system(flashrom + " -p serprog:dev=" + opts.port[0] + ":" + opts.baud[0]) reset.resetToNormal return ret # If we're here, we'll need to setup socket redirector port = 20000 while True: try: print("Trying port %d" % port) server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.bind(("127.0.0.1", port)) server.listen() break except: port = port + 1 if port > 30000: print("Weird shit going on, breaking") break #Fire up flashrom in background flr = ipflashrom() flr.configure(flashrom, port, flashrom_args) flr.start() #Accept connection connection, client_address = server.accept() connection.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) rd = redirector() rd.configure(term.ser, connection) rd.start() return flr.join()
def cli(): resets = ResetSeqFactory("rumboot.resetseq") formats = ImageFormatDb("rumboot.images") chips = ChipDb("rumboot.chips") parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="rumboot-xflash {} - RumBoot X-Modem firmware update tool\n" .format(rumboot.__version__) + rumboot.__copyright__) helper = arghelper() helper.add_file_handling_opts(parser, True) helper.add_terminal_opts(parser) parser.add_argument("-v", "--verbose", action='store_true', help="Print serial debug messages during update"), parser.add_argument("-m", "--memory", help="Memory program. Help for a list of memories", nargs=1, metavar=('memory'), default="help", required=True) parser.add_argument("-z", "--spl-path", help="Path for SPL writers (Debug only)", type=str, required=False) helper.add_resetseq_options(parser, resets) opts = parser.parse_args() c = helper.detect_chip_type(opts, chips, formats) if (c == None): return 1 mem = opts.memory[0] if not mem: return 1 if mem == "help": for mem, spl in c.memories.items(): print("Memory %16s: %s" % (mem, spl)) return 1 #Open files, rebuild if needed opts.file[0], dumps = helper.process_files(opts.file[0], False) print("Detected chip: %s (%s)" % (c.name, c.part)) if c.warning != None: print(" --- WARNING ---") print(c.warning) print(" --- WARNING ---") print("") spl_path = os.path.dirname(__file__) + "/spl-tools/" if opts.baud == None: opts.baud = [c.baudrate] reset = resets[opts.reset[0]](opts) term = terminal(opts.port[0], opts.baud[0]) term.set_chip(c) if opts.log: term.logstream = opts.log term.verbose = opts.verbose term.xfer.xfers["edcl"].force_static_arp = opts.force_static_arp try: spl = c.memories[mem] except: print( "ERROR: Target chip (%s) doesn't have memory '%s'. Run with -m help for a list" % (c.name, mem)) return 1 if opts.spl_path != None: spl_path = opts.spl_path print("SPL %s" % (spl_path + c.memories[mem])) spl = spl_path + c.memories[mem] print("Reset method: %s" % (reset.name)) print("Baudrate: %d bps" % int(opts.baud[0])) print("Port: %s" % opts.port[0]) reset.resetToHost() term.add_binaries(spl) term.add_binaries(opts.file[0][0]) if opts.edcl and c.edcl != None: term.xfer.selectTransport("edcl") print("Preferred data transport: %s" % term.xfer.how) reset.resetToHost() term.loop()