调试U-Boot笔记(七)

简介:
   对不起,这几天工作很忘没有抽得出空学习,上次我们找通过U-boot命令将U-Boot.bin烧到NorFlash失败的原因
    总体来讲,问题是出在 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去执行了。
 
    今天到此为止,明天继续…… 
目录
相关文章
|
存储 C# 图形学
【Unity 3D】C#数据类型和变量、命名规范的讲解(附源码)
【Unity 3D】C#数据类型和变量、命名规范的讲解(附源码)
424 1
|
人工智能 自然语言处理 搜索推荐
全面升级!揭秘阿里云智能Logo设计的AI黑科技
免费体验!阿里云智能logo设计一直致力于用AI技术,帮助更多有设计需求的朋友能“多快好省”地做logo,让“设计logo”这件有门槛的事情,通过智能工具能轻松打造。满意再付款,首单仅需9.9元。
3679 0
全面升级!揭秘阿里云智能Logo设计的AI黑科技
|
9月前
|
数据采集 数据挖掘 物联网
Pandas高级数据处理:实时数据处理
本文介绍了如何使用Pandas进行实时数据处理,涵盖从基础到高级的技巧。Pandas作为Python中流行的数据处理库,提供了高效的DataFrame和Series结构,适用于金融、社交媒体和物联网等领域的数据分析。文章详细讲解了数据读取、清洗、转换及常见问题的解决方案,如内存不足、数据不一致和性能瓶颈,并提供了避免常见报错的方法,帮助读者更高效地处理实时数据。
282 15
|
XML 数据格式 Python
【Python】已解决:xml.parsers.expat.ExpatError: no element found: Line 1, column 0
【Python】已解决:xml.parsers.expat.ExpatError: no element found: Line 1, column 0
577 0
|
存储 弹性计算 人工智能
阿里云99计划2核2G服务器99元/年,新购续费均可用
阿里云服务器99元一年配置为云服务器ECS经济型e实例,2核2G配置、3M固定带宽和40G ESSD Entry系统盘,新用户和老用户均可买
|
运维 网络安全 Docker
docker报错ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule
docker报错ERROR: Failed to Setup IP tables: Unable to enable SKIP DNAT rule
1173 0
|
Android开发 Kotlin
判断App是否处于后台/前台,使用ActivityLifecycleCallbacks稳得很!
RunningAppProcessInfo.IMPORTANCE_FOREGROUND,或者RunningTask来判断过, 但是遇到过偶然失灵或者无法适配现在的android版本。毕竟太老了,现在用点进去经常会有@Deprecated注解,表示废弃了。
|
机器学习/深度学习 数据采集 监控
解决办法:undefined reference to symbol 'dlclose@@GLIBC_2.2.5'
解决办法:undefined reference to symbol 'dlclose@@GLIBC_2.2.5'
973 0