我需要创建一个实用程序来检查闪存中的坏扇区。
我从一个旧的闪存驱动器开始,我将它插入我的 Ubuntu 笔记本电脑并检查了 dmesg
看到它被安装为 /dev/sdb
,然后我跑了fdisk
查看扇区的数量/大小:
mike@mike-Qosmio-X770:~$ sudo fdisk -l [sudo] password for mike:
Disk /dev/sdb: 127 MB, 127926272 bytes 16 heads, 32 sectors/track, 488 cylinders, total 249856 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 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(闪存翻译层)代码,或者即使我像这样乱搞驱动器,它也能受到保护?
<background for interested parties>
这是一个项目,我们有一个行为奇怪的 uCLinux 2.4 内核。我们怀疑硬件不好(特别是闪存),但我找不到在 2.4 上工作的好工具来测试闪存文件系统,所以我想我会尝试一下自己写。
</background>
最佳答案
我猜测,由于您的设备安装在 /dev/sdb1
上,我们正在处理某种可移动闪存介质设备,例如 USB 内存棒或媒体卡。如果您使用的是 SATA 连接 SSD,则需要考虑类似的因素。
在这些设备中, block 接口(interface)是位于闪存之上的复杂设备 Controller 的抽象。
闪存设备通常具有非常大的 block (称为删除单元,128kB 的大小并不罕见),可以在发生慢得多的删除之前写入一次。设备的 Controller 在主机所见的 block 接口(interface)和物理设备上的删除单元之间实现逻辑<->物理映射。作为管理过程的一部分, Controller 将实现错误检测和纠正并管理有缺陷的删除单元。整个过程在 block 接口(interface)上是不可见的。
因此,由于逻辑 block 永远不会永久映射到物理删除单元,因此不可能从 block 接口(interface)执行有意义的坏 block 扫描。
如果您碰巧有一个由 mtd
层管理的直接连接的闪存阵列,则 mtd-tools
以及相应的内核模块就是您想要的。文档可以找到 here
关于c - 如何用C检查闪存设备的坏扇区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14245910/