Ok335xS U-Boot 进度条原理跟踪

/******************************************************************************
 *                   Ok335xS U-Boot 进度条原理跟踪
 * 说明:
 *     如果系统通过U-Boot进行烧写的话,同时显示屏上又没有显示,只能通过debug port
 * 进行察看进度,这对于生产来说是不可行,有一个烧写进度条,是有必要的,于是跟踪
 * 一下手里的U-Boot有有进度条的原理,看看是如何做到的。
 *
 *                                         2017-7-4 深圳 龙华樟坑村 曾剑锋
 *****************************************************************************/

void board_init_r(gd_t *id, ulong dest_addr)
{
    char *s;
    bd_t *bd;
    ulong malloc_start;
#if !defined(CONFIG_SYS_NO_FLASH)
    ulong flash_size;
#endif


    gd = id;
    bd = gd->bd;

    gd->flags |= GD_FLG_RELOC;    /* tell others: relocation done */

    monitor_flash_len = _end_ofs;

    /* Enable caches */
    enable_caches();

    debug("monitor flash len: %08lX\n", monitor_flash_len);
    board_init();    /* Setup chipselects */

#ifdef CONFIG_SERIAL_MULTI
    serial_initialize();
#endif

    debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr);

#ifdef CONFIG_LOGBUFFER
    logbuff_init_ptrs();
#endif
#ifdef CONFIG_POST
    post_output_backlog();
#endif

    /* The Malloc area is immediately below the monitor copy in DRAM */
    malloc_start = dest_addr - TOTAL_MALLOC_LEN;
    mem_malloc_init (malloc_start, TOTAL_MALLOC_LEN);

    stdio_init();    /* get the devices list going. */

    /**
      * zengjf 2015-9-26 open pwm out pin
      */
    //draw_rect(2,2,2+401,2+31,RGB(255,0,0));//draw rectangle
    //__raw_writel((1<<12) | (1<<22), 0x44E07194);

#if !defined(CONFIG_SYS_NO_FLASH)
    puts("Flash: ");

    flash_size = flash_init();
    if (flash_size > 0) {
# ifdef CONFIG_SYS_FLASH_CHECKSUM
        print_size(flash_size, "");
        /*
         * Compute and print flash CRC if flashchecksum is set to 'y'
         *
         * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
         */
        s = getenv("flashchecksum");
        if (s && (*s == 'y')) {
            printf("  CRC: %08X", crc32(0,
                (const unsigned char *) CONFIG_SYS_FLASH_BASE,
                flash_size));
        }
        putc('\n');
# else    /* !CONFIG_SYS_FLASH_CHECKSUM */
        print_size(flash_size, "\n");
# endif /* CONFIG_SYS_FLASH_CHECKSUM */
    } else {
        puts(failed);
        hang();
    }
#endif

    puts("zengjf :\n");
#if defined(CONFIG_CMD_NAND)
    puts("NAND :  ");
    nand_init();        /* go init the NAND */         ---------------------+
#endif                                                                      |
                                                                            |
#if defined(CONFIG_CMD_ONENAND)                                             |
    onenand_init();                                                         |
#endif                                                                      |
                                                                            |
#ifdef CONFIG_GENERIC_MMC                                                   |
       puts("MMC:   ");                                                     |
       mmc_initialize(bd);                                                  |
#endif                                                                      |
                                                                            |
#ifdef CONFIG_HAS_DATAFLASH                                                 |
    AT91F_DataflashInit();                                                  |
    dataflash_print_info();                                                 |
#endif                                                                      |
                                                                            |
    /* initialize environment */                                            |
    env_relocate();                                                         |
                                                                            |
#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI)                          |
    arm_pci_init();                                                         |
#endif                                                                      |
                                                                            |
    /* IP Address */                                                        |
    gd->bd->bi_ip_addr = getenv_IPaddr("ipaddr");                           |
                                                                            |
                                                                            |
    jumptable_init();                                                       |
                                                                            |
#if defined(CONFIG_API)                                                     |
    /* Initialize API */                                                    |
    api_init();                                                             |
#endif                                                                      |
                                                                            |
    console_init_r();    /* fully init console as a device */               |
                                                                            |
#if defined(CONFIG_ARCH_MISC_INIT)                                          |
    /* miscellaneous arch dependent initialisations */                      |
    arch_misc_init();                                                       |
#endif                                                                      |
#if defined(CONFIG_MISC_INIT_R)                                             |
    /* miscellaneous platform dependent initialisations */                  |
    misc_init_r();                        ----------------------------------*--------+
#endif                                                                      |        |
                                                                            |        |
     /* set up exceptions */                                                |        |
    interrupt_init();                                                       |        |
    /* enable exceptions */                                                 |        |
    enable_interrupts();                                                    |        |
                                                                            |        |
    /* Perform network card initialisation if necessary */                  |        |
#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)     |        |
    /* XXX: this needs to be moved to board init */                         |        |
    if (getenv("ethaddr")) {                                                |        |
        uchar enetaddr[6];                                                  |        |
        eth_getenv_enetaddr("ethaddr", enetaddr);                           |        |
        smc_set_mac_addr(enetaddr);                                         |        |
    }                                                                       |        |
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */               |        |
                                                                            |        |
    /* Initialize from environment */                                       |        |
    s = getenv("loadaddr");                                                 |        |
    if (s != NULL)                                                          |        |
        load_addr = simple_strtoul(s, NULL, 16);                            |        |
#if defined(CONFIG_CMD_NET)                                                 |        |
    s = getenv("bootfile");                                                 |        |
    if (s != NULL)                                                          |        |
        copy_filename(BootFile, s, sizeof(BootFile));                       |        |
#endif                                                                      |        |
                                                                            |        |
#ifdef BOARD_LATE_INIT                                                      |        |
    board_late_init();                                                      |        |
#endif                                                                      |        |
                                                                            |        |
#ifdef CONFIG_BITBANGMII                                                    |        |
    bb_miiphy_init();                                                       |        |
#endif                                                                      |        |
#if defined(CONFIG_CMD_NET)                                                 |        |
#if defined(CONFIG_NET_MULTI)                                               |        |
    puts("Net:   ");                                                        |        |
#endif                                                                      |        |
    eth_initialize(gd->bd);                                                 |        |
#if defined(CONFIG_RESET_PHY_R)                                             |        |
    debug("Reset Ethernet PHY\n");                                          |        |
    reset_phy();                                                            |        |
#endif                                                                      |        |
#endif                                                                      |        |
                                                                            |        |
#ifdef CONFIG_POST                                                          |        |
    post_run(NULL, POST_RAM | post_bootmode_get(0));                        |        |
#endif                                                                      |        |
                                                                            |        |
#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)                       |        |
    /*                                                                      |        |
     * Export available size of memory for Linux,                           |        |
     * taking into account the protected RAM at top of memory               |        |
     */                                                                     |        |
    {                                                                       |        |
        ulong pram;                                                         |        |
        uchar memsz[32];                                                    |        |
#ifdef CONFIG_PRAM                                                          |        |
        char *s;                                                            |        |
                                                                            |        |
        s = getenv("pram");                                                 |        |
        if (s != NULL)                                                      |        |
            pram = simple_strtoul(s, NULL, 10);                             |        |
        else                                                                |        |
            pram = CONFIG_PRAM;                                             |        |
#else                                                                       |        |
        pram = 0;                                                           |        |
#endif                                                                      |        |
#ifdef CONFIG_LOGBUFFER                                                     |        |
#ifndef CONFIG_ALT_LB_ADDR                                                  |        |
        /* Also take the logbuffer into account (pram is in kB) */          |        |
        pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;                    |        |
#endif                                                                      |        |
#endif                                                                      |        |
        sprintf((char *)memsz, "%ldk", (gd->ram_size / 1024) - pram);       |        |
        setenv("mem", (char *)memsz);                                       |        |
    }                                                                       |        |
#endif                                                                      |        |
                                                                            |        |
    /* main_loop() can return to retry autoboot, if so just run it again. */|        |
    for (;;) {                                                              |        |
        main_loop();                                                        |        |
    }                                                                       |        |
                                                                            |        |
    /* NOTREACHED - no way out of command loop except booting */            |        |
}                                                                           |        |
                                                                            |        |
void nand_init(void)                       <--------------------------------+        |
{                                                                                    |
    int i;                                                                           |
    unsigned int size = 0;                                                           |
    for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) {                               |
        nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]);   --------+   |
        size += nand_info[i].size / 1024;                                        |   |
        if (nand_curr_device == -1)                                              |   |
            nand_curr_device = i;                                                |   |
    }                                                                            |   |
    printf("%u MiB\n", size / 1024);                                             |   |
                                                                                 |   |
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE                                             |   |
    /*                                                                           |   |
     * Select the chip in the board/cpu specific driver                          |   |
     */                                                                          |   |
    board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);|   |
#endif                                                                           |   |
}                                                                                |   |
                                                                                 |   |
static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand,  <------+   |
               ulong base_addr)                                                      |
{                                                                                    |
    int maxchips = CONFIG_SYS_NAND_MAX_CHIPS;                                        |
    static int __attribute__((unused)) i = 0;                                        |
                                                                                     |
    if (maxchips < 1)                                                                |
        maxchips = 1;                                                                |
    mtd->priv = nand;                                                                |
                                                                                     |
    nand->IO_ADDR_R = nand->IO_ADDR_W = (void  __iomem *)base_addr;                  |
    if (board_nand_init(nand) == 0) {               ----------------+                |
        if (nand_scan(mtd, maxchips) == 0) {        ----------------*-+              |
            if (!mtd->name)                                         | |              |
                mtd->name = (char *)default_nand_name;              | |              |
#ifdef CONFIG_NEEDS_MANUAL_RELOC                                    | |              |
            else                                                    | |              |
                mtd->name += gd->reloc_off;                         | |              |
#endif                                                              | |              |
                                                                    | |              |
#ifdef CONFIG_MTD_DEVICE                                            | |              |
            /*                                                      | |              |
             * Add MTD device so that we can reference it later     | |              |
             * via the mtdcore infrastructure (e.g. ubi).           | |              |
             */                                                     | |              |
            sprintf(dev_name[i], "nand%d", i);                      | |              |
            mtd->name = dev_name[i++];                              | |              |
            add_mtd_device(mtd);                                    | |              |
#endif                                                              | |              |
        } else                                                      | |              |
            mtd->name = NULL;                                       | |              |
    } else {                                                        | |              |
        mtd->name = NULL;                                           | |              |
        mtd->size = 0;                                              | |              |
    }                                                               | |              |
                                                                    | |              |
}                                                                   | |              |
                                                                    | |              |
#ifdef CONFIG_NAND_DAVINCI                                          | |              |
int board_nand_init(struct nand_chip *nand)          <--------------+ |              |
{                                                                     |              |
    davinci_nand_init(nand);                         ---------------+ |              |
                                                                    | |              |
    return 0;                                                       | |              |
}                                                                   | |              |
#endif                                                              | |              |
                                                                    | |              |
void davinci_nand_init(struct nand_chip *nand)       <--------------+ |              |
{                                                                     |              |
    nand->chip_delay  = 0;                                            |              |
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT                                  |              |
    nand->options      |= NAND_USE_FLASH_BBT;                         |              |
#endif                                                                |              |
#ifdef CONFIG_SYS_NAND_HW_ECC                                         |              |
    nand->ecc.mode = NAND_ECC_HW;                                     |              |
    nand->ecc.size = 512;                                             |              |
    nand->ecc.bytes = 3;                                              |              |
    nand->ecc.calculate = nand_davinci_calculate_ecc;                 |              |
    nand->ecc.correct  = nand_davinci_correct_data;                   |              |
    nand->ecc.hwctl  = nand_davinci_enable_hwecc;                     |              |
#else                                                                 |              |
    nand->ecc.mode = NAND_ECC_SOFT;                                   |              |
#endif /* CONFIG_SYS_NAND_HW_ECC */                                   |              |
#ifdef CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST                           |              |
    nand->ecc.mode = NAND_ECC_HW_OOB_FIRST;                           |              |
    nand->ecc.size = 512;                                             |              |
    nand->ecc.bytes = 10;                                             |              |
    nand->ecc.calculate = nand_davinci_4bit_calculate_ecc;            |              |
    nand->ecc.correct = nand_davinci_4bit_correct_data;               |              |
    nand->ecc.hwctl = nand_davinci_4bit_enable_hwecc;                 |              |
    nand->ecc.layout = &nand_davinci_4bit_layout_oobfirst;            |              |
#endif                                                                |              |
    /* Set address of hardware control function */                    |              |
    nand->cmd_ctrl = nand_davinci_hwcontrol;                          |              |
                                                                      |              |
    nand->read_buf = nand_davinci_read_buf;                           |              |
    nand->write_buf = nand_davinci_write_buf;                         |              |
                                                                      |              |
    nand->dev_ready = nand_davinci_dev_ready;                         |              |
                                                                      |              |
    nand_flash_init();                                                |              |
}                                                                     |              |
                                                                      |              |
int nand_scan(struct mtd_info *mtd, int maxchips)       <-------------+              |
{                                                                                    |
    int ret;                                                                         |
                                                                                     |
    ret = nand_scan_ident(mtd, maxchips, NULL);         --------------+              |
    if (!ret)                                           --------------*------------+ |
        ret = nand_scan_tail(mtd);                                    |            | |
    return ret;                                                       |            | |
}                                                                     |            | |
                                                                      |            | |
int nand_scan_ident(struct mtd_info *mtd, int maxchips, <-------------+            | |
            const struct nand_flash_dev *table)                                    | |
{                                                                                  | |
    int i, busw, nand_maf_id, nand_dev_id;                                         | |
    struct nand_chip *chip = mtd->priv;                                            | |
    const struct nand_flash_dev *type;                                             | |
                                                                                   | |
    /* Get buswidth to select the correct functions */                             | |
    busw = chip->options & NAND_BUSWIDTH_16;                                       | |
    /* Set the default functions */                                                | |
    nand_set_defaults(chip, busw);                                                 | |
                                                                                   | |
    /* Read the flash type */                                                      | |
    type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id, &nand_dev_id, table);| |
                                                                                   | |
    if (IS_ERR(type)) {                                                            | |
#ifndef CONFIG_SYS_NAND_QUIET_TEST                                                 | |
        printk(KERN_WARNING "No NAND device found!!!\n");                          | |
#endif                                                                             | |
        chip->select_chip(mtd, -1);                                                | |
        return PTR_ERR(type);                                                      | |
    }                                                                              | |
                                                                                   | |
    /* Check for a chip array */                                                   | |
    for (i = 1; i < maxchips; i++) {                                               | |
        chip->select_chip(mtd, i);                                                 | |
        /* See comment in nand_get_flash_type for reset */                         | |
        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);                                | |
        /* Send the command for reading device ID */                               | |
        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);                             | |
        /* Read manufacturer and device IDs */                                     | |
        if (nand_maf_id != chip->read_byte(mtd) ||                                 | |
            nand_dev_id != chip->read_byte(mtd))                                   | |
            break;                                                                 | |
    }                                                                              | |
#ifdef DEBUG                                                                       | |
    if (i > 1)                                                                     | |
        printk(KERN_INFO "%d NAND chips detected\n", i);                           | |
#endif                                                                             | |
                                                                                   | |
    /* Store the number of chips and calc total size for mtd */                    | |
    chip->numchips = i;                                                            | |
    mtd->size = i * chip->chipsize;                                                | |
                                                                                   | |
    return 0;                                                                      | |
}                                                                                  | |
                                                                                   | |
int nand_scan_tail(struct mtd_info *mtd)         <---------------------------------+ |
{                                                                                    |
    uint32_t dev_width;                                                              |
    int i;                                                                           |
    struct nand_chip *chip = mtd->priv;                                              |
                                                                                     |
    if (!(chip->options & NAND_OWN_BUFFERS))                                         |
        chip->buffers = kmalloc(sizeof(*chip->buffers), GFP_KERNEL);                 |
    if (!chip->buffers)                                                              |
        return -ENOMEM;                                                              |
                                                                                     |
    /* Set the internal oob buffer location, just after the page data */             |
    chip->oob_poi = chip->buffers->databuf + mtd->writesize;                         |
                                                                                     |
    dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;                             |
                                                                                     |
    /*                                                                               |
     * If no default placement scheme is given, select an appropriate one            |
     */                                                                              |
    if (!chip->ecc.layout) {                                                         |
        switch (mtd->oobsize) {                                                      |
        case 8:                                                                      |
            chip->ecc.layout = &nand_oob_8;                                          |
            break;                                                                   |
        case 16:                                                                     |
            chip->ecc.layout = &nand_oob_16;                                         |
            break;                                                                   |
        case 64:                                                                     |
            chip->ecc.layout = &nand_oob_64;                                         |
            break;                                                                   |
        case 128:                                                                    |
            chip->ecc.layout = &nand_oob_128;                                        |
            break;                                                                   |
        default:                                                                     |
            printk(KERN_WARNING "No oob scheme defined for "                         |
                   "oobsize %d\n", mtd->oobsize);                                    |
        }                                                                            |
    }                                                                                |
                                                                                     |
    if (!chip->write_page)                                                           |
        chip->write_page = nand_write_page;                                          |
                                                                                     |
    /*                                                                               |
     * check ECC mode, default to software if 3byte/512byte hardware ECC is          |
     * selected and we have 256 byte pagesize fallback to software ECC               |
     */                                                                              |
                                                                                     |
    switch (chip->ecc.mode) {                                                        |
    case NAND_ECC_HW_OOB_FIRST:                                                      |
        /* Similar to NAND_ECC_HW, but a separate read_page handle */                |
        if (!chip->ecc.calculate || !chip->ecc.correct ||                            |
             !chip->ecc.hwctl) {                                                     |
            printk(KERN_WARNING "No ECC functions supplied, "                        |
                   "Hardware ECC not possible\n");                                   |
            BUG();                                                                   |
        }                                                                            |
        if (!chip->ecc.read_page)                                                    |
            chip->ecc.read_page = nand_read_page_hwecc_oob_first;                    |
                                                                                     |
    case NAND_ECC_HW:                                                                |
        /* Use standard hwecc read page function ? */                                |
        if (!chip->ecc.read_page)                                                    |
            chip->ecc.read_page = nand_read_page_hwecc;                              |
        if (!chip->ecc.write_page)                                                   |
            chip->ecc.write_page = nand_write_page_hwecc;                            |
        if (!chip->ecc.read_page_raw)                                                |
            chip->ecc.read_page_raw = nand_read_page_raw;                            |
        if (!chip->ecc.write_page_raw)                                               |
            chip->ecc.write_page_raw = nand_write_page_raw;                          |
        if (!chip->ecc.read_oob)                                                     |
            chip->ecc.read_oob = nand_read_oob_std;                                  |
        if (!chip->ecc.write_oob)                                                    |
            chip->ecc.write_oob = nand_write_oob_std;                                |
                                                                                     |
    case NAND_ECC_HW_SYNDROME:                                                       |
        if ((!chip->ecc.calculate || !chip->ecc.correct ||                           |
             !chip->ecc.hwctl) &&                                                    |
            (!chip->ecc.read_page ||                                                 |
             chip->ecc.read_page == nand_read_page_hwecc ||                          |
             !chip->ecc.write_page ||                                                |
             chip->ecc.write_page == nand_write_page_hwecc)) {                       |
            printk(KERN_WARNING "No ECC functions supplied, "                        |
                   "Hardware ECC not possible\n");                                   |
            BUG();                                                                   |
        }                                                                            |
        /* Use standard syndrome read/write page function ? */                       |
        if (!chip->ecc.read_page)                                                    |
            chip->ecc.read_page = nand_read_page_syndrome;                           |
        if (!chip->ecc.write_page)                                                   |
            chip->ecc.write_page = nand_write_page_syndrome;                         |
        if (!chip->ecc.read_page_raw)                                                |
            chip->ecc.read_page_raw = nand_read_page_raw_syndrome;                   |
        if (!chip->ecc.write_page_raw)                                               |
            chip->ecc.write_page_raw = nand_write_page_raw_syndrome;                 |
        if (!chip->ecc.read_oob)                                                     |
            chip->ecc.read_oob = nand_read_oob_syndrome;                             |
        if (!chip->ecc.write_oob)                                                    |
            chip->ecc.write_oob = nand_write_oob_syndrome;                           |
                                                                                     |
        if (mtd->writesize >= chip->ecc.size)                                        |
            break;                                                                   |
        printk(KERN_WARNING "%d byte HW ECC not possible on "                        |
               "%d byte page size, fallback to SW ECC\n",                            |
               chip->ecc.size, mtd->writesize);                                      |
        chip->ecc.mode = NAND_ECC_SOFT;                                              |
                                                                                     |
    case NAND_ECC_SOFT:                                                              |
        chip->ecc.calculate = nand_calculate_ecc;                                    |
        chip->ecc.correct = nand_correct_data;                                       |
        chip->ecc.read_page = nand_read_page_swecc;                                  |
        chip->ecc.read_subpage = nand_read_subpage;                                  |
        chip->ecc.write_page = nand_write_page_swecc;                                |
        chip->ecc.read_page_raw = nand_read_page_raw;                                |
        chip->ecc.write_page_raw = nand_write_page_raw;                              |
        chip->ecc.read_oob = nand_read_oob_std;                                      |
        chip->ecc.write_oob = nand_write_oob_std;                                    |
        chip->ecc.size = 256;                                                        |
        chip->ecc.bytes = 3;                                                         |
        break;                                                                       |
                                                                                     |
#if !defined(CONFIG_TI81XX)                                                          |
    case NAND_ECC_4BIT_SOFT:                                                         |
        /* Use standard hwecc read page function */                                  |
        if (!chip->ecc.read_page)                                                    |
            chip->ecc.read_page = nand_read_page_hwecc;                              |
        if (!chip->ecc.write_page)                                                   |
            chip->ecc.write_page = nand_write_page_hwecc;                            |
        if (!chip->ecc.read_oob)                                                     |
            chip->ecc.read_oob = nand_read_oob_std;                                  |
        if (!chip->ecc.write_oob)                                                    |
            chip->ecc.write_oob = nand_write_oob_std;                                |
        chip->ecc.size = 2048;                                                       |
        chip->ecc.bytes = 28;                                                        |
        chip->ecc.hwctl = omap_enable_hwecc_bch4;                                    |
                chip->ecc.calculate = omap_calculate_ecc_bch4;                       |
                chip->ecc.correct = omap_correct_data_bch4;                          |
                chip->ecc.layout = omap_get_ecc_layout_bch(dev_width, 4);            |
        omap_hwecc_init_bch(chip);                                                   |
                break;                                                               |
                                                                                     |
    case NAND_ECC_8BIT_SOFT:                                                         |
        /* Use standard hwecc read page function */                                  |
        if (!chip->ecc.read_page)                                                    |
            chip->ecc.read_page = nand_read_page_hwecc;                              |
        if (!chip->ecc.write_page)                                                   |
            chip->ecc.write_page = nand_write_page_hwecc;                            |
        if (!chip->ecc.read_oob)                                                     |
            chip->ecc.read_oob = nand_read_oob_std;                                  |
        if (!chip->ecc.write_oob)                                                    |
            chip->ecc.write_oob = nand_write_oob_std;                                |
        chip->ecc.size = 2048;                                                       |
        chip->ecc.bytes = 52;                                                        |
        chip->ecc.hwctl = omap_enable_hwecc_bch8;                                    |
                chip->ecc.calculate = omap_calculate_ecc_bch8;                       |
                chip->ecc.correct = omap_correct_data_bch8;                          |
                chip->ecc.layout = omap_get_ecc_layout_bch(dev_width, 8);            |
        omap_hwecc_init_bch(chip);                                                   |
                                                                                     |
            break;                                                                   |
#endif                                                                               |
                                                                                     |
    case NAND_ECC_NONE:                                                              |
        printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "               |
               "This is not recommended !!\n");                                      |
        chip->ecc.read_page = nand_read_page_raw;                                    |
        chip->ecc.write_page = nand_write_page_raw;                                  |
        chip->ecc.read_oob = nand_read_oob_std;                                      |
        chip->ecc.read_page_raw = nand_read_page_raw;                                |
        chip->ecc.write_page_raw = nand_write_page_raw;                              |
        chip->ecc.write_oob = nand_write_oob_std;                                    |
        chip->ecc.size = mtd->writesize;                                             |
        chip->ecc.bytes = 0;                                                         |
        break;                                                                       |
                                                                                     |
    default:                                                                         |
        printk(KERN_WARNING "Invalid NAND_ECC_MODE %d\n",                            |
               chip->ecc.mode);                                                      |
        BUG();                                                                       |
    }                                                                                |
                                                                                     |
    /*                                                                               |
     * The number of bytes available for a client to place data into                 |
     * the out of band area                                                          |
     */                                                                              |
    chip->ecc.layout->oobavail = 0;                                                  |
    for (i = 0; chip->ecc.layout->oobfree[i].length                                  |
            && i < ARRAY_SIZE(chip->ecc.layout->oobfree); i++)                       |
        chip->ecc.layout->oobavail +=                                                |
            chip->ecc.layout->oobfree[i].length;                                     |
    mtd->oobavail = chip->ecc.layout->oobavail;                                      |
                                                                                     |
    /*                                                                               |
     * Set the number of read / write steps for one page depending on ECC            |
     * mode                                                                          |
     */                                                                              |
    chip->ecc.steps = mtd->writesize / chip->ecc.size;                               |
    if(chip->ecc.steps * chip->ecc.size != mtd->writesize) {                         |
        printk(KERN_WARNING "Invalid ecc parameters\n");                             |
        BUG();                                                                       |
    }                                                                                |
    chip->ecc.total = chip->ecc.steps * chip->ecc.bytes;                             |
                                                                                     |
    /*                                                                               |
     * Allow subpage writes up to ecc.steps. Not possible for MLC                    |
     * FLASH.                                                                        |
     */                                                                              |
    if (!(chip->options & NAND_NO_SUBPAGE_WRITE) &&                                  |
        !(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {                                  |
        switch(chip->ecc.steps) {                                                    |
        case 2:                                                                      |
            mtd->subpage_sft = 1;                                                    |
            break;                                                                   |
        case 4:                                                                      |
        case 8:                                                                      |
        case 16:                                                                     |
            mtd->subpage_sft = 2;                                                    |
            break;                                                                   |
        }                                                                            |
    }                                                                                |
    chip->subpagesize = mtd->writesize >> mtd->subpage_sft;                          |
                                                                                     |
    /* Initialize state */                                                           |
    chip->state = FL_READY;                                                          |
                                                                                     |
    /* De-select the device */                                                       |
    chip->select_chip(mtd, -1);                                                      |
                                                                                     |
    /* Invalidate the pagebuffer reference */                                        |
    chip->pagebuf = -1;                                                              |
                                                                                     |
    /* Fill in remaining MTD driver data */                                          |
    mtd->type = MTD_NANDFLASH;                                                       |
    mtd->flags = MTD_CAP_NANDFLASH;                                                  |
    mtd->erase = nand_erase;                                                         |
    mtd->point = NULL;                                                               |
    mtd->unpoint = NULL;                                                             |
    mtd->read = nand_read;                                                           |
    mtd->write = nand_write;          --------------------------------+              |
    mtd->read_oob = nand_read_oob;                                    |              |
    mtd->write_oob = nand_write_oob;                                  |              |
    mtd->sync = nand_sync;                                            |              |
    mtd->lock = NULL;                                                 |              |
    mtd->unlock = NULL;                                               |              |
    mtd->block_isbad = nand_block_isbad;                              |              |
    mtd->block_markbad = nand_block_markbad;                          |              |
                                                                      |              |
    /* propagate ecc.layout to mtd_info */                            |              |
    mtd->ecclayout = chip->ecc.layout;                                |              |
                                                                      |              |
    /* Check, if we should skip the bad block table scan */           |              |
    if (chip->options & NAND_SKIP_BBTSCAN)                            |              |
        chip->options |= NAND_BBT_SCANNED;                            |              |
                                                                      |              |
    return 0;                                                         |              |
}                                                                     |              |
                                                                      |              |
static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,<---+              |
              size_t *retlen, const uint8_t *buf)                                    |
{                                                                                    |
    struct nand_chip *chip = mtd->priv;                                              |
    int ret;                                                                         |
                                                                                     |
    /* Do not allow writes past end of device */                                     |
    if ((to + len) > mtd->size)                                                      |
        return -EINVAL;                                                              |
    if (!len)                                                                        |
        return 0;                                                                    |
                                                                                     |
    nand_get_device(chip, mtd, FL_WRITING);                                          |
                                                                                     |
    chip->ops.len = len;                                                             |
    chip->ops.datbuf = (uint8_t *)buf;                                               |
    chip->ops.oobbuf = NULL;                                                         |
                                                                                     |
    ret = nand_do_write_ops(mtd, to, &chip->ops);      --------------+               |
                                                                     |               |
    *retlen = chip->ops.retlen;                                      |               |
                                                                     |               |
    nand_release_device(mtd);                                        |               |
                                                                     |               |
    return ret;                                                      |               |
}                                                                    |               |
                                                                     |               |
static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, <------+               |
                 struct mtd_oob_ops *ops)                                            |
{                                                                                    |
    int chipnr, realpage, page, blockmask, column;                                   |
    struct nand_chip *chip = mtd->priv;                                              |
    uint32_t writelen = ops->len;                                                    |
    uint8_t *oob = ops->oobbuf;                                                      |
    uint8_t *buf = ops->datbuf;                                                      |
    int ret, subpage;                                                                |
                                                                                     |
    ops->retlen = 0;                                                                 |
    if (!writelen)                                                                   |
        return 0;                                                                    |
                                                                                     |
    column = to & (mtd->writesize - 1);                                              |
    subpage = column || (writelen & (mtd->writesize - 1));                           |
                                                                                     |
    if (subpage && oob)                                                              |
        return -EINVAL;                                                              |
                                                                                     |
    chipnr = (int)(to >> chip->chip_shift);                                          |
    chip->select_chip(mtd, chipnr);                                                  |
                                                                                     |
    /* Check, if it is write protected */                                            |
    if (nand_check_wp(mtd)) {                                                        |
        printk (KERN_NOTICE "nand_do_write_ops: Device is write protected\n");       |
        return -EIO;                                                                 |
    }                                                                                |
                                                                                     |
    realpage = (int)(to >> chip->page_shift);                                        |
    page = realpage & chip->pagemask;                                                |
    blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;              |
                                                                                     |
    /* Invalidate the page cache, when we write to the cached page */                |
    if (to <= (chip->pagebuf << chip->page_shift) &&                                 |
        (chip->pagebuf << chip->page_shift) < (to + ops->len))                       |
        chip->pagebuf = -1;                                                          |
                                                                                     |
    /* If we're not given explicit OOB data, let it be 0xFF */                       |
    if (likely(!oob))                                                                |
        memset(chip->oob_poi, 0xff, mtd->oobsize);                                   |
                                                                                     |
    while(1) {                                                                       |
        WATCHDOG_RESET();                                                            |
                                                                                     |
        int bytes = mtd->writesize;                                                  |
        int cached = writelen > bytes && page != blockmask;                          |
        uint8_t *wbuf = buf;                                                         |
                                                                                     |
        /* Partial page write ? */                                                   |
        if (unlikely(column || writelen < (mtd->writesize - 1))) {                   |
            cached = 0;                                                              |
            bytes = min_t(int, bytes - column, (int) writelen);                      |
            chip->pagebuf = -1;                                                      |
            memset(chip->buffers->databuf, 0xff, mtd->writesize);                    |
            memcpy(&chip->buffers->databuf[column], buf, bytes);                     |
            wbuf = chip->buffers->databuf;                                           |
        }                                                                            |
                                                                                     |
        if (unlikely(oob))                                                           |
            oob = nand_fill_oob(chip, oob, ops);                                     |
                                                                                     |
        ret = chip->write_page(mtd, chip, wbuf, page, cached,                        |
                       (ops->mode == MTD_OOB_RAW));                                  |
        if (ret)                                                                     |
            break;                                                                   |
                                                                                     |
        writelen -= bytes;                                                           |
                                                                                     |
        if(!g_need_skip)                                                             |
        show_process(ops->len - writelen,ops->len);  --------+                       |
                                                             |                       |
        if (!writelen)                                       |                       |
            break;                                           |                       |
                                                             |                       |
        column = 0;                                          |                       |
        buf += bytes;                                        |                       |
        realpage++;                                          |                       |
                                                             |                       |
        page = realpage & chip->pagemask;                    |                       |
        /* Check, if we cross a chip boundary */             |                       |
        if (!page) {                                         |                       |
            chipnr++;                                        |                       |
            chip->select_chip(mtd, -1);                      |                       |
            chip->select_chip(mtd, chipnr);                  |                       |
        }                                                    |                       |
    }                                                        |                       |
                                                             |                       |
    ops->retlen = ops->len - writelen;                       |                       |
    if (unlikely(oob))                                       |                       |
        ops->oobretlen = ops->ooblen;                        |                       |
                                                             |                       |
    return ret;                                              |                       |
}                                                            |                       |
                                                             |                       |
int g_on = 0;                                                |                       |
void show_process(unsigned long a,unsigned long b)   <-------+                       |
{                                                                                    |
    static int last_percent = 100,type = 0;                                          |
    int percent = 0,i = 0;                                                           |
    char buf[512];                                                                   |
    char *title = "",*env;                                                           |
    if(!g_on)return;                                                                 |
    percent = a/(b/100);                                                             |
                                                                                     |
    if(percent != last_percent)                                                      |
    {                                                                                |
        update_led();                                                                |
                                                                                     |
        /*update uart console*/                                                      |
        printf("\r%02d%% complete",percent);                                         |
                                                                                     |
        /*update lcd process bar*/                                                   |
        if(last_percent == 100)                                                      |
        {                                                                            |
            env = getenv("TYPE");                                                    |
            if(env)                                                                  |
                type = (*env)-'0';                                                   |
            else                                                                     |
                type = 9;                                                            |
                                                                                     |
            switch(type)                                                             |
            {                                                                        |
            case 0:                                                                  |
                title = "Erasing nand chip............";                             |
                break;                                                               |
            case 1:                                                                  |
                title = "Reading MLO from MMC.........";                             |
                break;                                                               |
            case 2:                                                                  |
                title = "Burning MLO to nand..........";                             |
                break;                                                               |
            case 3:                                                                  |
                title = "Reading u-boot.img from MMC..";                             |
                break;                                                               |
            case 4:                                                                  |
                title = "Burning u-boot.img to nand...";                             |
                break;                                                               |
            case 5:                                                                  |
                title = "Reading uImage from MMC......";                             |
                break;                                                               |
            case 6:                                                                  |
                title = "Burning uImage to nand.......";                             |
                break;                                                               |
            case 7:                                                                  |
                title = "Reading ubi.img from MMC.....";                             |
                break;                                                               |
            case 8:                                                                  |
                title = "Burning ubi.img to nand......";                             |
                break;                                                               |
            default:                                                                 |
                title = "env is null..................";                             |
                break;                                                               |
            }                                                                        |
                                                                                     |
            video_drawchars(x1,y1, title, strlen(title));     --------------------+  |
            draw_rect(x2,y2,x2+401,y2+31,RGB(255,0,0));//draw rectangle           |  |
            draw_bar(x2+1,y2+1,x2+400,y2+30,RGB(0,0,0));//clear  old bar          |  |
            draw_bar(x2+1,y2+1,x2+1+percent*4,y2+30,RGB(0,0,255));//draw bar      |  |
        }                                                                         |  |
        else // just draw increased bar                                           |  |
        {                                                                         |  |
            draw_bar(x2+1+last_percent*4,y2+1,x2+percent*4,y2+30,RGB(0,0,255));   |  |
        }                                                                         |  |
                                                                                  |  |
        /*update lcd console*/                                                    |  |
        sprintf(buf,"       %02d%% complete        ",percent);                    |  |
        video_drawchars(x3,y3, buf, strlen(buf));                                 |  |
    }                                                                             |  |
                                                                                  |  |
    last_percent = percent;                                                       |  |
                                                                                  |  |
    if(percent == 100)                                                            |  |
    {                                                                             |  |
        if(type == 8)                                                             |  |
        {                                                                         |  |
            char *ok = "Update system to nand success,you can now boot from nand";|  |
            //draw_bar(0,0,VIDEO_VISIBLE_COLS,VIDEO_VISIBLE_ROWS,RGB(0,0,0));     |  |
            video_drawchars(x2-24,y3+32, ok, strlen(ok));                         |  |
        }                                                                         |  |
                                                                                  |  |
        printf("\n");                                                             |  |
    }                                                                             |  |
}                                                                                 |  |
                                                                                  |  |
void video_drawchars(int xx, int yy, unsigned char *s, int count)    <------------+  |
{                                                                                    |
    u8 *cdat, *dest, *dest0;                                                         |
    int rows, offset, c;                                                             |
                                                                                     |
    offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;                            |
    dest0 = video_fb_address + offset;                                               |
                                                                                     |
    switch (VIDEO_DATA_FORMAT) {                                                     |
    case GDF__8BIT_INDEX:                                                            |
    case GDF__8BIT_332RGB:                                                           |
        while (count--) {                                                            |
            c = *s;                                                                  |
            cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;                           |
            for (rows = VIDEO_FONT_HEIGHT, dest = dest0;                             |
                 rows--; dest += VIDEO_LINE_LEN) {                                   |
                u8 bits = *cdat++;                                                   |
                                                                                     |
                ((u32 *) dest)[0] =                                                  |
                    (video_font_draw_table8[bits >> 4] &                             |
                     eorx) ^ bgx;                                                    |
                ((u32 *) dest)[1] =                                                  |
                    (video_font_draw_table8[bits & 15] &                             |
                     eorx) ^ bgx;                                                    |
            }                                                                        |
            dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;                            |
            s++;                                                                     |
        }                                                                            |
        break;                                                                       |
                                                                                     |
    case GDF_15BIT_555RGB:                                                           |
        while (count--) {                                                            |
            c = *s;                                                                  |
            cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;                           |
            for (rows = VIDEO_FONT_HEIGHT, dest = dest0;                             |
                 rows--; dest += VIDEO_LINE_LEN) {                                   |
                u8 bits = *cdat++;                                                   |
                                                                                     |
                ((u32 *) dest)[0] =                                                  |
                    SHORTSWAP32((video_font_draw_table15                             |
                             [bits >> 6] & eorx) ^                                   |
                            bgx);                                                    |
                ((u32 *) dest)[1] =                                                  |
                    SHORTSWAP32((video_font_draw_table15                             |
                             [bits >> 4 & 3] & eorx) ^                               |
                            bgx);                                                    |
                ((u32 *) dest)[2] =                                                  |
                    SHORTSWAP32((video_font_draw_table15                             |
                             [bits >> 2 & 3] & eorx) ^                               |
                            bgx);                                                    |
                ((u32 *) dest)[3] =                                                  |
                    SHORTSWAP32((video_font_draw_table15                             |
                             [bits & 3] & eorx) ^                                    |
                            bgx);                                                    |
            }                                                                        |
            dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;                            |
            s++;                                                                     |
        }                                                                            |
        break;                                                                       |
                                                                                     |
    case GDF_16BIT_565RGB:                                                           |
        dest0 += 2;//align memory for 16bpp                                          |
        while (count--) {                                                            |
            c = *s;                                                                  |
            cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;                           |
            for (rows = VIDEO_FONT_HEIGHT, dest = dest0;                             |
                 rows--; dest += VIDEO_LINE_LEN) {                                   |
                u8 bits = *cdat++;                                                   |
                ((u32 *) dest)[0] =                                                  |
                    SHORTSWAP32((video_font_draw_table16                             |
                             [bits >> 6] & eorx) ^                                   |
                            bgx);                                                    |
                ((u32 *) dest)[1] =                                                  |
                    SHORTSWAP32((video_font_draw_table16                             |
                             [bits >> 4 & 3] & eorx) ^                               |
                            bgx);                                                    |
                ((u32 *) dest)[2] =                                                  |
                    SHORTSWAP32((video_font_draw_table16                             |
                             [bits >> 2 & 3] & eorx) ^                               |
                            bgx);                                                    |
                ((u32 *) dest)[3] =                                                  |
                    SHORTSWAP32((video_font_draw_table16                             |
                             [bits & 3] & eorx) ^                                    |
                            bgx);                                                    |
            }                                                                        |
            dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;                            |
            s++;                                                                     |
        }                                                                            |
        break;                                                                       |
                                                                                     |
    case GDF_32BIT_X888RGB:                                                          |
        while (count--) {                                                            |
            c = *s;                                                                  |
            cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;                           |
            for (rows = VIDEO_FONT_HEIGHT, dest = dest0;                             |
                 rows--; dest += VIDEO_LINE_LEN) {                                   |
                u8 bits = *cdat++;                                                   |
                                                                                     |
                ((u32 *) dest)[0] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits >> 4][0] & eorx) ^ bgx);                               |
                ((u32 *) dest)[1] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits >> 4][1] & eorx) ^ bgx);                               |
                ((u32 *) dest)[2] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits >> 4][2] & eorx) ^ bgx);                               |
                ((u32 *) dest)[3] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits >> 4][3] & eorx) ^ bgx);                               |
                ((u32 *) dest)[4] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits & 15][0] & eorx) ^ bgx);                               |
                ((u32 *) dest)[5] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits & 15][1] & eorx) ^ bgx);                               |
                ((u32 *) dest)[6] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits & 15][2] & eorx) ^ bgx);                               |
                ((u32 *) dest)[7] =                                                  |
                    SWAP32((video_font_draw_table32                                  |
                        [bits & 15][3] & eorx) ^ bgx);                               |
            }                                                                        |
            dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;                            |
            s++;                                                                     |
        }                                                                            |
        break;                                                                       |
                                                                                     |
    case GDF_24BIT_888RGB:                                                           |
        while (count--) {                                                            |
            c = *s;                                                                  |
            cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;                           |
            for (rows = VIDEO_FONT_HEIGHT, dest = dest0;                             |
                 rows--; dest += VIDEO_LINE_LEN) {                                   |
                u8 bits = *cdat++;                                                   |
                                                                                     |
                ((u32 *) dest)[0] =                                                  |
                    (video_font_draw_table24[bits >> 4][0]                           |
                     & eorx) ^ bgx;                                                  |
                ((u32 *) dest)[1] =                                                  |
                    (video_font_draw_table24[bits >> 4][1]                           |
                     & eorx) ^ bgx;                                                  |
                ((u32 *) dest)[2] =                                                  |
                    (video_font_draw_table24[bits >> 4][2]                           |
                     & eorx) ^ bgx;                                                  |
                ((u32 *) dest)[3] =                                                  |
                    (video_font_draw_table24[bits & 15][0]                           |
                     & eorx) ^ bgx;                                                  |
                ((u32 *) dest)[4] =                                                  |
                    (video_font_draw_table24[bits & 15][1]                           |
                     & eorx) ^ bgx;                                                  |
                ((u32 *) dest)[5] =                                                  |
                    (video_font_draw_table24[bits & 15][2]                           |
                     & eorx) ^ bgx;                                                  |
            }                                                                        |
            dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;                            |
            s++;                                                                     |
        }                                                                            |
        break;                                                                       |
    }                                                                                |
}                                                                                    |
                                                                                     |
int misc_init_r(void)                     <------------------------------------------+
{
#ifdef DEBUG
    unsigned int cntr;
    unsigned char *valPtr;

    debug("EVM Configuration - ");
    debug("\tBoard id %x, profile %x, db %d\n", board_id, profile,
                        daughter_board_connected);
    debug("Base Board EEPROM Data\n");
    valPtr = (unsigned char *)&header;
    for(cntr = 0; cntr < sizeof(header); cntr++) {
        if(cntr % 16 == 0)
            debug("\n0x%02x :", cntr);
        debug(" 0x%02x", (unsigned int)valPtr[cntr]);
    }
    debug("\n\n");

    debug("Board identification from EEPROM contents:\n");
    debug("\tBoard name   : %.8s\n", header.name);
    debug("\tBoard version: %.4s\n", header.version);
    debug("\tBoard serial : %.12s\n", header.serial);
    debug("\tBoard config : %.6s\n\n", header.config);
#endif

#ifdef AUTO_UPDATESYS
    /*sdÆô¶¯²Å×Ô¶¯¸üÐÂϵͳ*/
    if(*((int *)0x80000000) == 8)
        run_command("run auto_update_nand", 0);  ----------+
#endif                                                     |
                                                           |
    if(*((int *)0x80000000) == 8)                          |
        setenv("bootdev","MMC");                           |
    else                                                   |
        setenv("bootdev","NAND");                          |
                                                           |
    return 0;                                              |
}                                                          |
                                                           |
int run_command (const char *cmd, int flag)   <------------+
{
    cmd_tbl_t *cmdtp;
    char cmdbuf[CONFIG_SYS_CBSIZE];    /* working copy of cmd        */
    char *token;            /* start of token in cmdbuf    */
    char *sep;            /* end of token (separator) in cmdbuf */
    char finaltoken[CONFIG_SYS_CBSIZE];
    char *str = cmdbuf;
    char *argv[CONFIG_SYS_MAXARGS + 1];    /* NULL terminated    */
    int argc, inquotes;
    int repeatable = 1;
    int rc = 0;

#ifdef DEBUG_PARSER
    printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
    puts (cmd ? cmd : "NULL");    /* use puts - string may be loooong */
    puts ("\"\n");
#endif

    clear_ctrlc();        /* forget any previous Control C */

    if (!cmd || !*cmd) {
        return -1;    /* empty command */
    }

    if (strlen(cmd) >= CONFIG_SYS_CBSIZE) {
        puts ("## Command too long!\n");
        return -1;
    }

    strcpy (cmdbuf, cmd);

    /* Process separators and check for invalid
     * repeatable commands
     */

#ifdef DEBUG_PARSER
    printf ("[PROCESS_SEPARATORS] %s\n", cmd);
#endif
    while (*str) {

        /*
         * Find separator, or string end
         * Allow simple escape of ';' by writing "\;"
         */
        for (inquotes = 0, sep = str; *sep; sep++) {
            if ((*sep=='\'') &&
                (*(sep-1) != '\\'))
                inquotes=!inquotes;

            if (!inquotes &&
                (*sep == ';') &&    /* separator        */
                ( sep != str) &&    /* past string start    */
                (*(sep-1) != '\\'))    /* and NOT escaped    */
                break;
        }

        /*
         * Limit the token to data between separators
         */
        token = str;
        if (*sep) {
            str = sep + 1;    /* start of command for next pass */
            *sep = '\0';
        }
        else
            str = sep;    /* no more commands for next pass */
#ifdef DEBUG_PARSER
        printf ("token: \"%s\"\n", token);
#endif

        /* find macros in this token and replace them */
        process_macros (token, finaltoken);

        /* Extract arguments */
        if ((argc = parse_line (finaltoken, argv)) == 0) {
            rc = -1;    /* no command at all */
            continue;
        }

        /* Look up command in command table */
        if ((cmdtp = find_cmd(argv[0])) == NULL) {
            printf ("Unknown command '%s' - try 'help'\n", argv[0]);
            rc = -1;    /* give up after bad command */
            continue;
        }

        /* found - check max args */
        if (argc > cmdtp->maxargs) {
            cmd_usage(cmdtp);
            rc = -1;
            continue;
        }

#if defined(CONFIG_CMD_BOOTD)
        /* avoid "bootd" recursion */
        if (cmdtp->cmd == do_bootd) {
#ifdef DEBUG_PARSER
            printf ("[%s]\n", finaltoken);
#endif
            if (flag & CMD_FLAG_BOOTD) {
                puts ("'bootd' recursion detected\n");
                rc = -1;
                continue;
            } else {
                flag |= CMD_FLAG_BOOTD;
            }
        }
#endif

        /* OK - call function to do the command */
        if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) {
            rc = -1;
        }

        repeatable &= cmdtp->repeatable;

        /* Did the user stop this? */
        if (had_ctrlc ())
            return -1;    /* if stopped then not repeatable */
    }

    return rc ? rc : repeatable;
}

 

posted on 2017-07-04 11:08  zengjf  阅读(346)  评论(0编辑  收藏  举报

导航