加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

调试U-Boot笔记(七)

发布时间:2020-12-15 18:18:10 所属栏目:百科 来源:网络整理
导读:??? 对不起,这几天工作很忘没有抽得出空学习,上次我们找通过U-boot命令将U-Boot.bin烧到NorFlash失败的原因,详情请回顾 《调试U-Boot笔记(六)》 ??? 总体来讲,问题是出在 write_hword() 函数中的最后 验证写入的数据是否与实现一致 时出的错。 *addr =
??? 对不起,这几天工作很忘没有抽得出空学习,上次我们找通过U-boot命令将U-Boot.bin烧到NorFlash失败的原因,详情请回顾 《调试U-Boot笔记(六)》
??? 总体来讲,问题是出在 write_hword() 函数中的最后 验证写入的数据是否与实现一致时出的错。
*addr = CMD_READ_ARRAY;
if (chip == ERR || *addr != data)    // *addr != data
    rc = ERR_PROG_ERROR;
if (iflag)
??? 为什么写入的东西结果读出来不一致呢?想一下,在上一次实验中,写入的数据是18(10010B),结果读出来的是1107(10001010011B)。比较一下二进制:
??? 18??? 000000 10010
??? 1107? 100010 10011
??? 我们发觉它们的1~4位都是1001,这个是不是给我们一点提示?
??? NorFlash在擦除时是将所有的位都清成0,当写入数据时将对应的位置1,进行OR运行,所以叫NorFlash。与此相反的NandFlash则是在擦除时将所有位置1,写入时与写入的数据进行AND运算。
??? 我们可以进行一个大胆的猜测,NorFlash原来这个地址上的数据并没有被擦除,原来的值为100010 000011,当我们写入18(10010)时,与100010000011进行OR运行,最终得到 100010 10011。
?
??? 为了证实我的这一个推论,只要将写入前addr地址上的值打印出来就知道了。
???

??? 在写数据之前,先打印一下result的值。OK,Let me have a try.
???

??? 在写入数据之前,我们从地址上读出的数据是1107,这确实说明NorFlash没有被擦除,不然这个值要么是0xFFFFFFFF要么是0x00000000,怎么会是一个1107呢?
?
????既然是没有擦除引起的,那么我就来查找一下到底是为什么没有擦除。
??? 我们要关注:u-boot/board/my2440/flash.c 文件中的 flash_erase() 函数:
???

int flash_erase (flash_info_t * info,int s_first,int s_last)
    {
        ushort result;
        int iflag,cflag,prot,sect;
        int rc = ERR_OK;
        int chip;
        /* first look for protection bits */
        if (info->flash_id == FLASH_UNKNOWN)
            return ERR_UNKNOWN_FLASH_TYPE;
        if ((s_first < 0) || (s_first > s_last)) {
            return ERR_INVAL;
        }
        if ((info->flash_id & FLASH_VENDMASK) !=
         (AMD_MANUFACT & FLASH_VENDMASK)) {
            return ERR_UNKNOWN_FLASH_VENDOR;
        }
        prot = 0;
        for (sect = s_first; sect <= s_last; ++sect) {
            if (info->protect[sect]) {
                prot++;
            }
        }
        if (prot)
            return ERR_PROTECTED;
        /*
         * Disable interrupts which might cause a timeout
         * here. Remember that our exception vectors are
         * at address 0 in the flash,and we don't want a
         * (ticker) exception to happen while the flash
         * chip is in programming mode.
         */
        cflag = icache_status ();
        icache_disable ();
        iflag = disable_interrupts ();
        /* Start erase on unprotected sectors */
        for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
            printf ("Erasing sector %2d ... ",sect);
            /* arm simple,non interrupt dependent timer */
            reset_timer_masked ();
            if (info->protect[sect] == 0) {    /* not protected */
                vu_short *addr = (vu_short *) (info->start[sect]);
                MEM_FLASH_ADDR1 = CMD_UNLOCK1;
                MEM_FLASH_ADDR2 = CMD_UNLOCK2;
                MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
                MEM_FLASH_ADDR1 = CMD_UNLOCK1;
                MEM_FLASH_ADDR2 = CMD_UNLOCK2;
                *addr = CMD_ERASE_CONFIRM;
                /* wait until flash is ready */
                chip = 0;
                do {
                    result = *addr;
                    /* check timeout */
                    if (get_timer_masked () >
                     CFG_FLASH_ERASE_TOUT) {
                        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
                        chip = TMO;
                        break;
                    }
                    if (!chip
                     && (result & 0xFFFF) & BIT_ERASE_DONE)
                        chip = READY;
                    if (!chip
                     && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
                        chip = ERR;
                } while (!chip);
                MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
                if (chip == ERR) {
                    rc = ERR_PROG_ERROR;
                    goto outahere;
                }
                if (chip == TMO) {
                    rc = ERR_TIMOUT;
                    goto outahere;
                }
                printf ("ok.n");
            } else {    /* it was protected */
                printf ("protected!n");
            }
        }
        if (ctrlc ())
            printf ("User Interrupt!n");
    outahere:
        /* allow flash to settle - wait 10 ms */
        udelay_masked (10000);
        if (iflag)
            enable_interrupts ();
        if (cflag)
            icache_enable ();
        return rc;
    }

??? 第一步:8~20,是在对一些基本信息进行校验。
??? 第二步:20~29,检查Flash芯片的保护标志,如果还有扇区还处于保存状态则返回 ERR_PROTECTED 。
??? 第三步:38~40,关中断与cache。
??? 第四步: 42~100,正式执行擦除操作。
??? 第五步:102~116,现场恢复
??? 结合U-Boot命令执行结果输出:
???

?
????可以分析出:
??? (1)程序输出了“Erasing sector 0...”说明函数执行到了第四步。
??? (2)程序没有输出:“Ok.”,“protected!”,也没有输出“User Interrupt!”信息,说明程序地执行擦除操作时执行了 L88 或 L92 处的 goto outahere; 直接跳到 L105去执行了。
?
??? 今天到此为止,明天继续……

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读