调试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去执行了。
?
??? 今天到此为止,明天继续……
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |