Ejemplo n.º 1
0
int main(int argc, char **argv) {
    libusb_context *c;
    libusb_device_handle *h;
    int offset = 0, size = 0;
    char action;

    NEXT; if (!argc) usage();

    action = **argv; NEXT;

    switch(action) {
    case 'b':
        if (argc) usage();
        break;
    case 'e': case 'r': case 'w':
        if (argc!=2) usage();
        offset = strtoul(argv[0], NULL, 0);
        size   = strtoul(argv[1], NULL, 0);
        break;
    case 'v': case 'V':
        printf("rkflashtool version %d.%d\n",
               RKFLASHTOOL_VER_MAJOR, RKFLASHTOOL_VER_MINOR);
        exit(0);
        break;
    default:
        usage();
    }

    if (libusb_init(&c)) fatal("cannot init libusb\n");

    libusb_set_debug(c, 3);

    if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x290a)))
        if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x281a)))
        if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x300a)))
        if (!(h = libusb_open_device_with_vid_pid(c, 0x2207, 0x310b)))
            fatal("cannot open device\n");

    if (libusb_kernel_driver_active(h, 0) == 1) {
        info("kernel driver active\n");
        if (!libusb_detach_kernel_driver(h, 0))
            info("driver detached\n");
    }

    if (libusb_claim_interface(h, 0)<0) fatal("cannot claim interface\n");
    info("interface claimed\n");

    send_cmd(h, 2, 0x80, 0x00060000, 0x00000000, 0x00);        /* INIT */
    recv_res(h, 1);
    usleep(20*1000);

    switch(action) {
    case 'b':
        info("rebooting device...\n");
        send_cmd(h, 2, 0x00, 0x0006ff00, 0x00000000, 0x00);
        recv_res(h, 1);
        break;
    case 'r':
        while (size>0) {
            if (offset % RKFT_DISPLAY == 0)
                info("reading flash memory at offset 0x%08x\r", offset);

            send_cmd(h, 2, 0x80, 0x000a1400, offset, RKFT_OFF_INCR);
            recv_buf(h, 1, RKFT_BLOCKSIZE);
            recv_res(h, 1);

            /* check for write() errors to catch disk-full, no-perms, etc. */
            if (write(1, buf, RKFT_BLOCKSIZE) < 0)
                fatal("error writing buffer to stdout: %s\n", strerror(errno));
            offset += RKFT_OFF_INCR;
            size   -= RKFT_OFF_INCR;
        }
        fprintf(stderr, "\n");
        break;
    case 'w':
        while (size>0) {
            if (offset % RKFT_DISPLAY == 0)
                info("writing flash memory at offset 0x%08x\r", offset);

            memset(buf, 0, RKFT_BLOCKSIZE);
            /* we ignore here read() errors and pad up to given size */
            if (read(0, buf, RKFT_BLOCKSIZE) < 0) {};

            send_cmd(h, 2, 0x80, 0x000a1500, offset, RKFT_OFF_INCR);
            send_buf(h, 2, RKFT_BLOCKSIZE);
            recv_res(h, 1);

            offset += RKFT_OFF_INCR;
            size   -= RKFT_OFF_INCR;
        }
        fprintf(stderr, "\n");
        break;
    case 'e':
        memset(buf, RKFT_FILLBYTE, RKFT_BLOCKSIZE);
        while (size>0) {
            if (offset % RKFT_DISPLAY == 0)
                info("erasing flash memory at offset 0x%08x\r", offset);

            send_cmd(h, 2, 0x80, 0x000a1500, offset, RKFT_OFF_INCR);
            send_buf(h, 2, RKFT_BLOCKSIZE);
            recv_res(h, 1);

            offset += RKFT_OFF_INCR;
            size   -= RKFT_OFF_INCR;
        }
        fprintf(stderr, "\n");
        break;
    default:
        break;
    }

    libusb_release_interface(h, 0);
    libusb_close(h);
    libusb_exit(c);
    return 0;
}
Ejemplo n.º 2
0
int main(int argc, char **argv) {
    const struct t_pid *ppid = pidtab;
    int offset = 0, size = 0;
    char action;

    info("rkflashtool v%d.%d\n", RKFLASHTOOL_VERSION_MAJOR,
                                 RKFLASHTOOL_VERSION_MINOR);
    
    NEXT; if (!argc) usage();

    action = **argv; NEXT;

    switch(action) {
    case 'b':
    case 'l':
        if (argc) usage(); 
        break;
    case 'e':
    case 'r': 
    case 'w': 
    case 'm':
    case 'i':
        if (argc != 2) usage();
        offset = strtoul(argv[0], NULL, 0);
        size   = strtoul(argv[1], NULL, 0);
        break;
    case 'p':
        if (argc) usage();
        offset = 0;
        size   = 1024;
        break;
    default:
        usage();
    }

    /* Initialize libusb */
    
    if (libusb_init(&c)) fatal("cannot init libusb\n");

    libusb_set_debug(c, 3);
    
    /* Detect connected RockChip device */
    
    while ( !h && ppid->pid) {
        h = libusb_open_device_with_vid_pid(c, 0x2207, ppid->pid);
        if (h) {
            info("Detected %s...\n", ppid->name);
            break;
        }
        ppid++;
    } 
    if (!h) fatal("cannot open device\n");

    /* Connect to device */
    
    if (libusb_kernel_driver_active(h, 0) == 1) {
        info("kernel driver active\n");
        if (!libusb_detach_kernel_driver(h, 0))
            info("driver detached\n");
    }

    if (libusb_claim_interface(h, 0) < 0)  
        fatal("cannot claim interface\n");
    info("interface claimed\n");

    /* Initialize bootloader interface */

    send_cmd(RKFT_CMD_TESTUNITREADY, 0, 0);
    recv_res();
    usleep(20*1000);

    /* Check and execute command */

    switch(action) {
    case 'b':   /* Reboot device */
        info("rebooting device...\n");
        send_cmd(RKFT_CMD_RESETDEVICE, 0, 0);
        recv_res();
        break;
    case 'r':   /* Read FLASH */
        while (size > 0) {
            info("reading flash memory at offset 0x%08x\n", offset);

            send_cmd(RKFT_CMD_READLBA, offset, RKFT_OFF_INCR);
            recv_buf(RKFT_BLOCKSIZE);
            recv_res();

            if (write(1, buf, RKFT_BLOCKSIZE) <= 0)
                fatal("Write error! Disk full?\n");
            
            offset += RKFT_OFF_INCR;
            size   -= RKFT_OFF_INCR;
        }
        break;
    case 'w':   /* Write FLASH */
        while (size > 0) {
            info("writing flash memory at offset 0x%08x\n", offset);

            if (read(0, buf, RKFT_BLOCKSIZE) <= 0)
                fatal("premature end-of-file reached.\n");

            send_cmd(RKFT_CMD_WRITELBA, offset, RKFT_OFF_INCR);
            send_buf(RKFT_BLOCKSIZE);
            recv_res();

            offset += RKFT_OFF_INCR;
            size   -= RKFT_OFF_INCR;
        }
        break;
    case 'p':   /* Retreive parameters */
        {
            uint32_t *p = (uint32_t*)buf+1;

            info("reading parameters at offset 0x%08x\n", offset);

            send_cmd(RKFT_CMD_READLBA, offset, RKFT_OFF_INCR);
            recv_buf(RKFT_BLOCKSIZE);
            recv_res();
            size = *p;
            info("size:  0x%08x\n", size);

            if (write(1, &buf[8], size) <= 0)
                fatal("Write error! Disk full?\n");
        }
        break;
    case 'l':   /* Retreive flashinfo */
        {
            info("reading parameters at offset 0x%08x\n", offset);

            send_cmd(RKFT_CMD_READFLASHINFO, offset, RKFT_OFF_INCR);
            recv_buf(RKFT_FLASHINFO_SIZE);
            recv_res();

            if (write(1, buf, RKFT_FLASHINFO_SIZE) <= 0)
                fatal("Write error! Disk full?\n");
        }
        break;
    case 'm':   /* Read RAM */
        while (size > 0) {
            int sizeRead = size > RKFT_MEM_INCR ? RKFT_MEM_INCR : size;
            info("reading memory at offset 0x%08x size %x\n", offset, sizeRead);

            send_cmd(RKFT_CMD_READSDRAM, offset-0x60000000, sizeRead);
            recv_buf(sizeRead);
            recv_res();

            if (write(1, buf, sizeRead) <= 0)
                fatal("Write error! Disk full?\n");

            offset += sizeRead;
            size -= sizeRead;
        }
        break;
    case 'i':   /* Read IDB */
        while (size > 0) {
            int sizeRead = size > RKFT_IDB_INCR ? RKFT_IDB_INCR : size;
            info("reading IDB flash memory at offset 0x%08x\n", offset);
             
            send_cmd(RKFT_CMD_READSECTOR, offset, sizeRead);
            recv_buf(RKFT_IDB_BLOCKSIZE * sizeRead);
            recv_res();
             
            if (write(1, buf, RKFT_IDB_BLOCKSIZE * sizeRead) <= 0)
                fatal("Write error! Disk full?\n");

            offset += sizeRead;
            size -= sizeRead;
        }
        break;
    case 'e':   /* Erase flash */
        memset(buf, 0xff, RKFT_BLOCKSIZE);
        while (size > 0) {
                info("erasing flash memory at offset 0x%08x\n", offset);

                send_cmd(RKFT_CMD_WRITELBA, offset, RKFT_OFF_INCR);
                send_buf(RKFT_BLOCKSIZE);
                recv_res();

                offset += RKFT_OFF_INCR;
                size   -= RKFT_OFF_INCR;
        }
        break;
    default:
        break;
    }

    /* Disconnect and close all interfaces */

    libusb_release_interface(h, 0);
    libusb_close(h);
    libusb_exit(c);
    return 0;
}