背景
前段时间同事在烧录软件时,在uboot模式下将imgaddr变量的值写成了8010000(正确值应该0x84000000),断电之后,设备就变砖了,无法启动。
虽然知道他因为地址的原因,破坏了flash里面的数据,但是具体讨论起来,发现自己也不是很清楚,从讨论中,我也总结出了一些问题。该文章主要是解析这几个问题点。
问题一:flash,RAM,ROM的区别
在和王工分析的过程中,我指着开发板上的flash,如图:
说这个就是保存了我们的固件,里面包括bootload,firmwave,SQL等信息。之前的地址0x84000000应该是我们firmwave的起始地址,你现在改为了8010000,地址这么小,肯定把bootload给破坏了,导致设备起不来了。我对自己的分析感到很满意,说的头头是道。
但是后面有听到一个硬件专家说bootload应该不会存放在flash中的,一般会内嵌在CPU中,并且一般是无法访问的,更不可能修改。还有说板子还有另一个flash,如图:
听到他的这些话,我就产生了一系列问题,好奇害死猫。于是我就向他请教,加上自己在百度的查阅,不能说豁然开朗,但的确揭露了我的盲区,有种拨云见日的舒心。
首先他说的两个观点都是对的。图1表示的是NOR flash ,图2表示的是NAND flash。
NOR flash:支持片上运行,但是价格昂贵,并且因为工艺的原因,相同的容量,NOR flash的体积比NAND flash的要大很多,所以NOR flash在工艺上就注定无法大容量。
NAND flash:不支持片上运行,容量较大以及改写速度快等优点
通过上面的区分,我们知道uboot 一般是放在NOR flash中,我们的固件一般是放在NAND F lash中。
说到flash,我们就必须要提及一下内存,内存有两种,RAM,ROM。
ROM:是只读存储器,断电后数据还在。它不能修改和擦除,只能读取事先烧录好的程序,比如电脑的BIOS。用途不是很广。
RAM:就是我们平时提及的内存,断电后数据不能保存,读写速度很快。如图:
第二点:吴工说有些bootload 是内嵌到CPU的,这个应该是有些产品这样设计的,但是我目前还没有遇到过这样的设计。大部分都是uboot放在NOR flash中,Firmwave存放在NAND Flash中。
问题二:为什么王工的操作,导致设备变砖?
经过自己的推测和询问,了解到,王工主要是做了以下两步骤导致的出错。
tftpboot 0x84000000 xxxx-ipq40xx-single.img
imgaddr=0x8010000 && source $imgaddr:script
第一步:通过tftpboot 将固件下载到内存中的0x84000000这个地址中(虚拟地址)。
第二部:设置环境变量,imgaddr,执行source $imgaddr:script,擦写NOR flash和NAND Flash。
由于固件的地址在0x84000000,而烧录的时候,使用的是0x801000(这个地址后面应该都是乱码)。也就是说,NOR Flash 和NAND Flash此时里面都是乱码了。(可能NAND Flash还是正常的,不过NOR Flash肯定是错误的了)。之后断电重启,NOR Flash的bootload不存在,所以导致启动不了。
bootm从内存中启动firmwave
后面于工的一顿操作,惊艳到了我。那就是他直接在内存中,启动firmwave.不需要将firmwave烧录到Flash中。
其实,事后自己思考了一下,觉得这其实也没有什么特别之处的。为什么呢?
因为我们设备断电重启之后,都是将Flash中的firmwave拷贝到内存,再启动的。现在这个操作不在是通过Flash的拷贝,而是通过boottftp 下载到内存中。
若我的内容对您有所帮助,还请关注我的公众号。不定期分享干活,剖析案例,也可以一起讨论分享。
我的宗旨:
踩完您工作中的所有坑并分享给您,让你的工作无bug,人生尽是坦途