我需要创建一个实用程序来检查闪存中的坏扇区。
我开始使用旧的闪存驱动器,我将其粘贴在我的Ubuntu笔记本电脑中并检查dmesg
以查看它已挂载为/dev/sdb
,然后我运行fdisk
查看部门的数量/规模:
mike @ mike-Qosmio-X770:迈克的〜$ sudo fdisk -l [sudo]密码:磁盘/ dev / sdb:127 MB,127926272字节16个磁头,32个扇区/磁道,488 气缸,总计249856个扇区
单位=扇区1 * 512 = 512 字节
扇区大小(逻辑/物理):512字节/ 512字节
I / O大小 (最小/最佳):512字节/ 512字节
磁盘标识符:0x6b3ee723Device Boot Start End Blocks Id System /dev/sdb1 * 32 249854 124911+ b W95 FAT32
太棒了,我知道一个扇区是512字节,总共应该有249,856个扇区。基于此,我写了这个小测试程序来仔细检查:
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
FILE * fp = NULL;
char buffer[512] = {0}; // size of a sector, 512 bytes
long sector_count = 0;
fp = fopen("/dev/sdb", "rb"); // open the flash device as binary
if(fp == NULL) {
printf("Can't open the flash drive!\n");
return -1;
}
while(!feof(fp) && (fread(buffer, sizeof(buffer), 1, fp) > 0)){
sector_count++;
}
fclose(fp);
printf("Sectors: %ld\n", sector_count);
return 0;
}
工作得非常好,报告249856.现在我一直在想如何继续。是否可以将一系列0xFF
写入驱动器(512x249856 1
位),然后将其读回以确保设置为1?然后写相同数量的0
以确保它可以被清除?
那会验证一切正常吗?有没有机会我可以覆盖FTL(Flash转换层)代码,或者是否受到保护,即使我不喜欢这样的驱动器?
<background for interested parties>
这是一个项目,我们有一个uCLinux 2.4内核有奇怪的行为..我们怀疑坏硬件(特别是闪存)但我找不到工作2.4的好工具来测试闪存fs所以我想我会尝试写我自己的。
</background>
答案 0 :(得分:1)
我猜测,因为您的设备已安装在/dev/sdb1
上,我们正在处理某种可移动的闪存介质设备,例如USB记忆棒或媒体卡。如果您正在处理SATA连接的SSD,则类似的考虑因素也适用。
在这些设备中,块接口是位于闪存顶部的复杂设备控制器的抽象。
闪存设备通常具有非常大的块(称为擦除单元,128kB作为大小并不罕见),可以在发生更慢的擦除之前写入一次。设备的控制器在块接口(如主机所见)和物理设备上的擦除单元之间实现逻辑 - 物理映射。作为管理过程的一部分,控制器将实施错误检测和纠正并管理有缺陷的擦除单元。整个过程在块接口处是不可见的。
因此,由于逻辑块永远不会永久映射到物理擦除单元,因此无法从块接口执行有意义的坏块扫描。
如果碰巧有一个由mtd
层管理的直接连接的闪存阵列,mtd-tools
就是您想要的,以及相应的内核模块。可以找到文档here
答案 1 :(得分:0)
现代硬件通常可以识别数据损坏,即您实际上比从设备读取错误数据更容易遇到I / O错误。此外,设备通常包含一定量的冗余,因此将检测到坏块并用好的块替换。对于现代硬盘,S.M.A.R.T.将提供有关坏块数的信息。不确定这是否适用于普通的闪存设备,但我猜是这样。