我正在努力在Linux中闪存嵌入式设备的先前ROM转储。我以前的转储包含oob数据。我用nandwrite -n -N -o /dev/mtd0 backup.bin
编写了它,然后再次进行ROM转储。
通过比较旧的和新的ROM转储,我看到一些不可解释的情况:任何空块(填充0xFF)的oob(ecc字节)的最后24个字节也应该是0xFF,但是那些在新的ROM转储填充0x00,导致以后写入失败。
oob应该是:
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
但nandwrite
:
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
FFFFFFFF FFFFFFFF 00000000 00000000
00000000 00000000 00000000 00000000
任何人都知道为什么?
我在nandwrite
代码中添加了一个hack,如果要写入的内容是0xFF
,则跳过写入NAND,并且它有效。那么在尝试将空白页写入NAND时存在问题吗?
增加:
现在,在编写引导加载程序映像时,我也遇到了这个问题。该图片不是页面对齐的,因此nandwrite
用0xFF
填充它。但对于只有0xFF
的页面,ecc字节仍然被0x00
污染,就像上面一样。似乎我的黑客并没有完全解决我的问题。有人可以帮忙吗?也许它可能是内核2.6.35中的错误?
这是我的黑客:
int i;
int needwrite=0;
for (i = 0 ; i < len ; ++i){
if(((uint8_t*)data)[i]!=0xff){
needwrite=1;
break;
}
}
if(!needwrite)
return 0;
答案 0 :(得分:2)
抱歉,Alvin,但备份真的不会“只对那个特定的闪存工作”,因为你不知道何时某个位将从好到边缘或边缘坏到坏。您可以在一个状态下读取它,尝试以完全相同的状态写入它,并在任何给定的日期,使用任何给定的备份失败。
安全备份NAND设备中的数据的 ONLY 方式是WITH ECC TURNED ON。您从具有ECC更正的设备读取以获得良好数据。然后,在已打开ECC的情况下将已知良好数据写回NAND,以便在使用新ECC值时可以使用以前读取它时现在边缘或坏的任何位。
答案 1 :(得分:1)
这是因为它是警告。 它不会可靠地工作。
考虑一种情况,你有一个块(1),位置0有错误。 Nand-flash设备的“控制器”会使用纠错码来纠正此错误。
使用 ECC复制第1块中的数据 但是,当您将数据写入新 Nand-flash设备时,您正在克隆数据。 如果新的nand-flash设备在位置1有错误。 然后,在下面的读取中,您写回的数据将是错误的,因为位置1是错误的。 但是系统会认为它是正确的,因为ECC在位置1中没有显示错误
您无法直接将1 nand-flash直接克隆到另一个,因为硬/软错误位置不相同。
唯一可靠地执行此操作的方法是读取数据,使用系统ECC算法来纠正任何错误。 将数据写入新设备,使用系统算法纠正任何误码。
您可能认为设备是相同的,但结果是由于位错误映射不匹配导致数据/程序损坏。
回应Alvin的评论:
我非常有信心克隆完全相同的NAND,即我对该特定芯片进行了备份,然后将其写回特定芯片。不是我认为它是一样的,但从开始到结束只有一个芯片。这很奇怪,但是其他一些人声称它在自己的设备上工作,而我的设备没有,驱动程序中是否有错误? - Alvin Wong 8月5日5:16
抱歉不可能(除非你真的......真的很幸运,得到的芯片有0个缺陷)
每个Nand-Flash芯片都有自己的一组缺陷位,它们是唯一的。 用户绕过它的方式是生成一个文件系统,一旦坏位超出CRC的能力,就会屏蔽坏块。 将nand-chip复制到另一个设备时,CRC映射与主芯片匹配。当您对设备进行1:1克隆时,一些数据位将在写入后翻转(坏单元格),并且由于您正在进行克隆,因此您不会在CRC中考虑这些位已翻转(因为你正在逐字复制)。
它对某些人“有效”这一事实并不意味着它是正确的,不仅仅是我可以驾驶汽车,但我发现制动器在我需要它时不起作用。更糟糕的是,网络中许多所谓的“专家”实际上擦除了制造商提供的“克隆”设备时所提供的缺陷图,或者在节省之前执行“芯片擦除”缺陷图。
这就是ebay出现的许多'狡猾的'nand-flash usb棒子所发生的事情,它们实际上是删除了“缺陷图”的芯片,因此它们看起来像是好的设备,直到你试图保存给他们内容。
答案 2 :(得分:0)
在我的嵌入式世界中,您首先使用flash_erase
对所有内容进行处理,然后nandwrite -p
以0xFF填充页面的其余部分。
Usage: nandwrite [OPTION] MTD_DEVICE [INPUTFILE|-]
Writes to the specified MTD device.
-m, --markbad Mark blocks bad if write fails
-N, --noskipbad Write without bad block skipping
-o, --oob Image contains oob data
-O, --onlyoob Image contains oob data and only write the oob part
-r, --raw Image contains the raw oob data dumped by nanddump
-s addr, --start=addr Set start address (default is 0)
-p, --pad Pad to page size
-b, --blockalign=1|2|4 Set multiple of eraseblocks to align to
-q, --quiet Don't display progress messages
--help Display this help and exit
--version Output version information and exit
答案 3 :(得分:-1)
我的黑客正在nandwrite
添加一个检查,如果要写入的整个页面完全为空(即已满0xFF
),程序将< em>跳过写它(因为flash_erase
已经完成)。
额外的好处是因为跳过空白页面nandwrite
的整个过程变得更快。 Horray!
<强>增加:强>
事实证明,我的黑客实际上没有解决问题......
再次添加:(真实解决方案)
问题实际上是PXA310用空白页填充0x00
的硬件ECC位,因此如果软件写入空白页,则位为0x00
。这很奇怪,因为我应该已经在nandwrite
的参数中禁用了ECC。幸运的是,跳过编写空白页可以防止重写ROM转储的问题。
更多信息可在my blog post中找到。
A patch sent to the linux-mtd list actually mentioned about the fact。