예제 #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()
예제 #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()
예제 #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()
예제 #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
예제 #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
예제 #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
예제 #7
0
 def __init__(self):
     self.opts = None
     self.env = {}
     self.resets = ResetSeqFactory("rumboot.resetseq")
     self.chips = ChipDb("rumboot.chips")
     self.chip = None
예제 #8
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()
예제 #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-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)
예제 #10
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
예제 #11
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()
예제 #12
0
class edclmanager(object):
    edcl = None
    verbose = False
    chips = ChipDb("rumboot.chips")
    warned = []
    force_static_arp = False

    def __init__(self):
        self.edcl = edcl()

    def check_reachability(self, ip):
        for i in ni.interfaces():
            if not ni.AF_INET in ni.ifaddresses(i):
                continue
            for addr in ni.ifaddresses(i)[ni.AF_INET]:
                if IPAddress(ip) in IPNetwork(addr['addr'] + "/" +addr["netmask"]):
                    return True
        return False

    def buggy_ip(self, params):
        arr = params["ip"].split(".")
        return int(arr[3]) == 0
            
    def __getattribute__(self, key):
        try:
            return object.__getattribute__(self, key)
        except:
            return object.__getattribute__(self.edcl, key)

    def try_connect(self, chip, params):
        if self.buggy_ip(params) or self.force_static_arp:
            #FIXME: This logic sucks. 
            #TODO: Implement a better solution to find non-used IP on the subnet
            params["ip"] = params["ip"].replace(".0", ".76")
            self.prepareStaticARP(chip, params)
        if not self.check_reachability(params["ip"]) and not params["ip"] in self.warned:
            print("WARNING: IP address %s is not in your subnet." % params["ip"])
            print("WARNING: Please check network interface settings.")
            self.warned.append(params["ip"])
            return None

        if self.verbose:
            print("Testing: %s (%s) IP %s" % (chip.__name__, params["name"], params["ip"]))
        try: 
            ret = self.edcl.connect(params["ip"])
        except:
            return None
        if ret:
            print("Connected: %s (%s)" % (chip.__name__, params["name"]))
            return chip

    def probe(self, chip):
        for params in chip.edcl:
            if None != self.try_connect(chip, params):
                return params
        return None

    def scan(self, match=None):
        ret = []
        if type(match) == int or type(match) == str:
            match = self.chips[match]

        if match == None:
            chips = self.chips
        else:
            chips = { match }
        for c in chips:
            tmp = self.probe(c)
            if tmp != None:
                db = {
                    "chip" : c,
                    "params": tmp
                }
                ret.append(db)
        return ret

    def test_chip(self, chip):
        pass

    def showArpWarning(self, cmd):
        print("WARNING: Trying to add ARP record via 'sudo'/'runas'.")
        print("WARNING: If that doesn't work please run manually: %s" % cmd)

    def dropARP(self, chip, params):
        if platform.system() == 'Linux':
            cmd = "sudo arp -d %s" % params["ip"]
        elif platform.system() == 'Windows': 
            cmd = "runas /user:Administrator arp /d %s" % params["ip"]
        else:
            raise("FATAL: Don't know how to add static ARP on %s", platform.system())
        os.system(cmd)
        self.showArpWarning(cmd)

    def addARP(self, chip, params):
        if platform.system() == 'Linux':
            cmd = "sudo arp -s %s %s" % (params["ip"], params["mac"])
        elif platform.system() == 'Windows': 
            cmd = "runas /user:Administrator arp /s %s %s" % (params["ip"], params["mac"].upper().replace(":","-"))
        else:
            raise("FATAL: Don't know how to add static ARP on %s", platform.system())
        os.system(cmd)
        self.showArpWarning(cmd)
        
    def listARP(self):
        ret = {}
        if platform.system() == 'Linux':
            cmd = "/usr/sbin/arp -n"
        elif platform.system() == 'Windows': 
            cmd = "arp -a"
        else:
            raise("FATAL: I don't know how to query ARP on %s", platform.system())
        out = subprocess.Popen(cmd.split(" "), 
                stdout=subprocess.PIPE, 
                stderr=subprocess.PIPE)
        stdout,stderr = out.communicate()
        if platform.system() == 'Linux':
            for l in stdout.decode().split("\n"):
                result = parse("{:<} ether {:>} {:>} {:>}", l)
                if result == None:
                    continue
                ret[result[0]]=result[1]
        elif  platform.system() == 'Windows': 
            for l in stdout.decode().split("\n"):
                result = parse("{:<} {:>} {:>}", l)
                if result == None:
                    continue
                ret[result[0]]=result[1].replace("-",":")
        return ret

    def getARP(self, ip):
        tbl = self.listARP()
        if ip in tbl:
            return tbl[ip]

    def prepareStaticARP(self, chip, params):
        if self.getARP(params["ip"]) and not self.force_static_arp:
            print("Static ARP record already exists, good")
            return
            
        if self.force_static_arp:
            self.dropARP(chip, params)
        self.addARP(chip, params)

    def smartupload(self, address, image, callback = None):
        self.edcl.send_from_file(address + 4, image, callback, 4)
        self.edcl.send_from_file(address    , image, None, 0, 4)

    def connect(self, chip):
        for i in range(3):
            ret = self.scan(chip)
            if ret != []:
                return ret
예제 #13
0
def smoke_test():
    db = ChipDb("rumboot.chips")
    c = db["basis"]
    assert c.chip_id == 3
    assert c.chip_rev == 1
예제 #14
0
def test_chipdb():
    db = ChipDb("rumboot.chips")
    c = db["basis"]
    assert c.chip_id == 3
    assert c.chip_rev == 1
예제 #15
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()