Exemplo n.º 1
0
/**
 * Block until the sequence of bytes
 *
 *    "[^$]*\$[^#]*#.*"
 *
 * has been read from the client fd.  This is one (or more) gdb
 * packet(s).
 */
static void read_packet(struct dbg_context* dbg)
{
    byte* p;
    size_t checkedlen;

    /* Read and discard bytes until we see the start of a
     * packet.
     *
     * NB: we're ignoring "+/-" responses from gdb.  There doesn't
     * seem to be any sane reason why we would send a damaged
     * packet to gdb over TCP, then see a "-" reply from gdb and
     * somehow magically fix our bug that led to the malformed
     * packet in the first place.
     */
    while (skip_to_packet_start(dbg)) {
        read_data_once(dbg);
    }

    if (dbg->inbuf[0] == INTERRUPT_CHAR) {
        /* Interrupts are kind of an ugly duckling in the gdb
         * protocol ... */
        dbg->packetend = 1;
        return;
    }

    /* Read until we see end-of-packet. */
    for (checkedlen = 0;
            !(p = memchr(dbg->inbuf + checkedlen, '#', dbg->inlen));
            checkedlen = dbg->inlen) {
        read_data_once(dbg);
    }
    dbg->packetend = (p - dbg->inbuf);
    /* NB: we're ignoring the gdb packet checksums here too.  If
     * gdb is corrupted enough to garble a checksum over TCP, it's
     * not really clear why asking for the packet again might make
     * the bug go away. */
    assert('$' == dbg->inbuf[0] && dbg->packetend < dbg->inlen);

    /* Acknowledge receipt of the packet. */
    if (!dbg->no_ack) {
        write_data_raw(dbg, (byte*)"+", 1);
        write_flush(dbg);
    }
}
Exemplo n.º 2
0
static void cmd_flash(struct protocol_handle *phandle, const char *arg)
{
    int partition;
    uint64_t sz;
    char data[BOOT_MAGIC_SIZE];
    char path[PATH_MAX];
    ssize_t header_sz = 0;
    int data_fd = 0;

    D(DEBUG, "cmd_flash %s\n", arg);

    if (try_handle_virtual_partition(phandle, arg)) {
        return;
    }

    if (phandle->download_fd < 0) {
        fastboot_fail(phandle, "no kernel file");
        return;
    }

    if (flash_find_entry(arg, path, PATH_MAX)) {
        fastboot_fail(phandle, "partition table doesn't exist");
        return;
    }

    if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) {
        fastboot_fail(phandle, "Access forbiden you need certificate");
        return;
    }

    // TODO: Maybe its goot idea to check whether the partition is bootable
    if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) {
        if (read_data_once(data_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) {
            fastboot_fail(phandle, "incoming data read error, cannot read boot header");
            return;
        }
        if (memcmp((void *)data, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
            fastboot_fail(phandle, "image is not a boot image");
            return;
        }
    }

    partition = flash_get_partiton(path);

    sz = get_file_size64(data_fd);

    sz -= header_sz;

    if (sz > get_file_size64(partition)) {
        flash_close(partition);
        D(WARN, "size of file too large");
        fastboot_fail(phandle, "size of file too large");
        return;
    }

    D(INFO, "writing %"PRId64" bytes to '%s'\n", sz, arg);

    if (flash_write(partition, phandle->download_fd, sz, header_sz)) {
        fastboot_fail(phandle, "flash write failure");
        return;
    }
    D(INFO, "partition '%s' updated\n", arg);

    flash_close(partition);
    close(data_fd);

    fastboot_okay(phandle, "");
}