void handle_dump(const char *name, unsigned offset)
{
    ptentry *p;

    if(tmpbuf == 0) {
        tmpbuf = alloc(4096);
    }

    dprintf("dump '%s' partition\n", name);
    p = flash_find_ptn(name);

    if(p == 0) {
        jtag_fail("partition not found");
        return;
    }

    if(flash_init()) {
        jtag_fail("flash_init() failed");
        return;
    }

#if 0
    /* XXX reimpl */
    if(flash_read_page(p->start * 64, tmpbuf, tmpbuf + 2048)) {
        jtag_fail("flash_read() failed");
        return;
    }
#endif

    dprintf("page %d data:\n", p->start * 64);
    hexdump(tmpbuf, 256);
    dprintf("page %d extra:\n", p->start * 64);
    hexdump(tmpbuf, 16);
    jtag_okay("done");
}
예제 #2
0
int boot_linux_from_flash(void)
{
    boot_img_hdr *hdr = (void*) raw_header;
    unsigned n;
    ptentry *p;
    unsigned offset = 0;
    const char *cmdline;

    if((p = flash_find_ptn("boot")) == 0) {
        cprintf("NO BOOT PARTITION\n");
        return -1;
    }

    if(flash_read(p, offset, raw_header, 2048)) {
        cprintf("CANNOT READ BOOT IMAGE HEADER\n");
        return -1;
    }
    offset += 2048;
    
    if(memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
        cprintf("INVALID BOOT IMAGE HEADER\n");
        return -1;
    }

    n = (hdr->kernel_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1));
    if(flash_read(p, offset, (void*) hdr->kernel_addr, n)) {
        cprintf("CANNOT READ KERNEL IMAGE\n");
        return -1;
    }
    offset += n;

    n = (hdr->ramdisk_size + (FLASH_PAGE_SIZE - 1)) & (~(FLASH_PAGE_SIZE - 1));
    if(flash_read(p, offset, (void*) hdr->ramdisk_addr, n)) {
        cprintf("CANNOT READ RAMDISK IMAGE\n");
        return -1;
    }
    offset += n;
    
    dprintf("\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr, hdr->kernel_size);
    dprintf("ramdisk @ %x (%d bytes)\n\n\n", hdr->ramdisk_addr, hdr->ramdisk_size);

    if(hdr->cmdline[0]) {
        cmdline = (char*) hdr->cmdline;
    } else {
        cmdline = board_cmdline();
        if(cmdline == 0) {
            cmdline = "mem=50M console=null";
        }
    }
    cprintf("cmdline = '%s'\n", cmdline);
    
    cprintf("\nBooting Linux\n");

    create_atags(ADDR_TAGS, cmdline,
                 hdr->ramdisk_addr, hdr->ramdisk_size);
    
    boot_linux(hdr->kernel_addr);
    return 0;
}
예제 #3
0
/*****************************************************************************
* name		: flash_erase_force
*
* description	: Erase nand block force, even if it's bad.
*
* input		: char *partition_name: partition to be erase
*
* other		: No
*****************************************************************************/
void flash_erase_force(char *partition_name)
{
	unsigned i = 0;
    unsigned ret = ERROR;
	unsigned block_start = 0;
	unsigned block_end= 0;

    struct nand_spec spec;
    struct ptentry *ptn = NULL;

    ret = nand_get_spec(&spec);
    if(ret)
    {
        cprintf("ERROR: nand get spec failed!\n");
        goto EXIT;
    }

    partition_name = bsp_nand_argument_check(partition_name);
    if(NULL == partition_name)
    {
        cprintf("ERROR: no partition name!\n");
        goto EXIT;
    }

    ptn = flash_find_ptn(partition_name);
    if(!ptn)
    {
        cprintf("ERROR: wrong partition name: %s\n", partition_name);
        goto EXIT;
    }

    /* coverity[uninit_use] */
	block_start = (ptn->start + spec.blocksize- 1) / spec.blocksize;
	block_end = (ptn->start + ptn->length + spec.blocksize - 1) / spec.blocksize;

	for (i = block_start; i < block_end; i++)
	{
	    ret = nand_erase(i);
        if(ret)
        {
            cprintf("ERROR: nand erase error, block id = %d, ret = %d.\n", i, ret);
        }
	}
    cprintf("Erase %s force finished!\n", partition_name);

    return;
EXIT:
    cprintf("ret = 0x%x!\n", ret);
    return;
}
예제 #4
0
/*****************************************************************************
* name		: flash_scan_bad
*
* description	: scan bad block, if partition_name is NULL, scan all partitions
*
* input		: char *partition_name: partition to scan
*
* other		: No
*****************************************************************************/
void flash_scan_bad(char *partition_name)
{
    struct ptentry *ptn = NULL;
    struct ST_PART_TBL *part = (struct ST_PART_TBL *)SHM_MEM_PTABLE_ADDR;
    struct nand_spec spec;
    struct ptentry tn;

    if(nand_get_spec(&spec))
    {
        cprintf("ERROR: nand get spec failed!\n");
        return;
    }

    partition_name = bsp_nand_argument_check(partition_name);

    /* scan all partitions */
    if(!partition_name)
    {
        part++;
        while(0 != strcmp(PTABLE_END_STR, part->name))
        {
            if(DATA_VALID == ptable_get_validity(part))
            {
                /* coverity[buffer_size_warning] */
                strncpy(tn.name, part->name, 16);
                tn.start = part->offset;
                tn.length = part->capacity;
                /* coverity[uninit_use_in_call] */
                get_partition_badblock(&tn, &spec);
            }


            part++;
        }
    }
    else /* scan one partition */
    {
        ptn = flash_find_ptn(partition_name);
        if(!ptn)
        {
            cprintf("ERROR: wrong partition name: %s\n", partition_name);
            return;
        }
        /* coverity[uninit_use_in_call] */
        get_partition_badblock(ptn, &spec);
    }

    cprintf("\n\n");
    return;
}
void handle_flash(const char *name, unsigned addr, unsigned len)
{
    int r;
    ptentry *p;

    dprintf("image @ 0x%x (0x%x bytes)\n", addr, len);
    dprintf("write to '%s' partition\n", name);

    p = flash_find_ptn(name);

    if(p == 0) {
        dprintf("ERROR: partition not found\n");
        return;
    } else {
        if(flash_init()) {
            dprintf("ERROR: flash_init() failed\n");
            return;
        }

        dprintf("erasing flash @ 0x%x (len=0x%x)\n", p->start, p->length);

        /* coverity[unchecked_value] */
        flash_erase(p);

        if(len) {
            dprintf("writing flash at @ 0x%x\n", p->start);

            if(!strcmp(name, PTABLE_SYSTEM_NM) || !strcmp(name, PTABLE_USERDATA_NM)) {
                r = flash_write(p, 16, (void*) addr, len);
            } else {
                len = (len + FLASH_PAGE_SIZE - 1) & (~(FLASH_PAGE_SIZE-1));
                r = flash_write(p, 0, (void*) addr, len);
            }
            if(r) {
                dprintf("ERROR: partition write failed, ret = %d\n", r);
            } else {
                dprintf("SUCCESS: %s written successful\n", name);
            }
            return;
        } else {
            dprintf("ERROR: file length is 0x0\n");
            return;
        }
    }
}
예제 #6
0
static void usb_rx_cmd_complete(struct usb_request *req, unsigned actual, int status)
{
    if(status != 0) return;
    
    if(actual > 4095) actual = 4095;    
    cmdbuf[actual] = 0;

    dprintf("\n> %s\n",cmdbuf);
    
//    dprintf("usb_rx_cmd_complete() '%s'\n", cmdbuf);  
    
    if(memcmp(cmdbuf, "reboot", 6) == 0) {
        tx_status("OKAY");
        rx_cmd();
        mdelay(100);
        board_reboot();
    }
#if 0
    if(memcmp(cmdbuf, "debug:", 6) == 0) {
        void debug(char *cmd, char *resp);
        memcpy(cmdbuf, "OKAY", 5);
        tx_status(cmdbuf);
        rx_cmd();
        mdelay(5000);
        dprintf("NOW!\n");
        debug(cmdbuf + 6, cmdbuf + 4);
        return;
    }
#endif
    if(memcmp(cmdbuf, "getvar:", 7) == 0) {
        char response[64];
        strcpy(response,"OKAY");
        
        if(!strcmp(cmdbuf + 7, "version")) {
            strcpy(response + 4, VERSION);
        } else if(!strcmp(cmdbuf + 7, "product")) {
            strcpy(response + 4, PRODUCTNAME);
        } else if(!strcmp(cmdbuf + 7, "serialno")) {
            strcpy(response + 4, serialno);
        } else {
            board_getvar(cmdbuf + 7, response + 4);
        }
        tx_status(response);
        rx_cmd();
        return;
    }

    if(memcmp(cmdbuf, "download:", 9) == 0) {
        char status[16];
        rx_addr = kernel_addr;
        rx_length = hex2unsigned(cmdbuf + 9);
        if (rx_length > (64*1024*1024)) {
            tx_status("FAILdata too large");
            rx_cmd();
            return;
        }
        kernel_size = rx_length;
        dprintf("recv data addr=%x size=%x\n", rx_addr, rx_length); 
        strcpy(status,"DATA");
        num_to_hex8(rx_length, status + 4);
        tx_status(status);
        rx_data();
        return;
    }

    if(memcmp(cmdbuf, "erase:", 6) == 0){
        struct ptentry *ptn;
        ptn = flash_find_ptn(cmdbuf + 6);
        if(ptn == 0) {
            tx_status("FAILpartition does not exist");
            rx_cmd();
            return;
        }
        dprintf("erasing '%s'\n", ptn->name);
        cprintf("erasing '%s'", ptn->name);
        if(flash_erase(ptn)) {
            tx_status("FAILfailed to erase partition");
            rx_cmd();
            cprintf(" - FAIL\n");
            return;
        } else {
            dprintf("partition '%s' erased\n", ptn->name);
            cprintf(" - OKAY\n");
        }
        tx_status("OKAY");
        rx_cmd();
        return;
    }

    if(memcmp(cmdbuf, "flash:", 6) == 0){
        struct ptentry *ptn;
        int extra = 0;
        ptn = flash_find_ptn(cmdbuf + 6);
        if(kernel_size == 0) {
            tx_status("FAILno image downloaded");
            rx_cmd();
            return;
        }
        if(ptn == 0) {
            tx_status("FAILpartition does not exist");
            rx_cmd();
            return;
        }
        if(!strcmp(ptn->name,"boot") || !strcmp(ptn->name,"recovery")) {
            if(memcmp((void*) kernel_addr, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
                tx_status("FAILimage is not a boot image");
                rx_cmd();
                return;
            }
        }
#if REQUIRE_SIGNATURE
        {
            unsigned char digest[DIGEST_SIZE];
            compute_digest((void*) kernel_addr, kernel_size, digest);
            if (is_signature_okay(digest, signature, key_engineering)) {
                dprintf("verified by engineering key\n");
            } else {
                tx_status("FAILsignature did not verify");
                rx_cmd();
                return;
            }
        }
#endif
        if(!strcmp(ptn->name,"system") || !strcmp(ptn->name,"userdata")) {
            extra = 64;
        } else {
            kernel_size = (kernel_size + 2047) & (~2047);
        }
        dprintf("writing %d bytes to '%s'\n", 
                kernel_size, ptn->name);
        cprintf("writing '%s' (%d bytes)", ptn->name, kernel_size);
        if(flash_write(ptn, extra, (void*) kernel_addr, kernel_size)) {
            tx_status("FAILflash write failure");
            rx_cmd();
            cprintf(" - FAIL\n");
            return;
        } else {
            dprintf("partition '%s' updated\n", ptn->name);
            cprintf(" - OKAY\n");
        }
        tx_status("OKAY");
        rx_cmd();
        return;
    }
    if(memcmp(cmdbuf, "boot", 4) == 0) {
        if(init_boot_linux()) {
            tx_status("FAILinvalid boot image");
            rx_cmd();
            return;
        }
        dprintf("booting linux...\n");
        cprintf("\nbooting linux...\n");
        tx_status("OKAY");
        mdelay(10);
        usb_shutdown();
        boot_linux();
        return;
    }
    if(memcmp(cmdbuf, "signature", 9) == 0) {
        if (kernel_size != SIGNATURE_SIZE) {
            tx_status("FAILsignature not 256 bytes long");
            rx_cmd();
            return;
        }
        memcpy(signature, (void*)kernel_addr, SIGNATURE_SIZE);
        tx_status("OKAY");
        rx_cmd();
        return;
    }

    tx_status("FAILinvalid command");
    rx_cmd();
}