Exemplo n.º 1
0
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()
Exemplo n.º 2
0
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()
Exemplo n.º 3
0
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()
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
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
Exemplo n.º 8
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
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
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)
Exemplo n.º 11
0
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
Exemplo n.º 12
0
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()
Exemplo n.º 13
0
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()