2

我需要创建一个实用程序来检查闪存中的坏扇区。

我从我拥有的旧闪存驱动器开始,将它卡在我的 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 字节
磁盘标识符:0x6b3ee723

Device 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's 写入驱动器(512x2498561位),然后将其读回以确保将其设置为 1 是否可行?然后写相同数量的0s,确保可以清零?

这会验证一切正常吗?有没有机会我可以覆盖 FTL(Flash 翻译层)代码,或者即使我像这样弄乱驱动器也能保护它?

<background for interested parties>
这是一个项目,我们有一个具有奇怪行为的 uCLinux 2.4 内核。我们怀疑硬件不好(特别是闪存),但我找不到在 2.4 上工作的好工具来测试闪存 fs,所以我想我会尝试写我自己的。
</background>

4

2 回答 2

2

我猜,由于您的设备已安装,/dev/sdb1我们正在处理某种可移动的闪存媒体设备,例如 USB 棒或媒体卡。如果您正在处理连接 SATA 的 SSD,则需要考虑类似的注意事项。

在这些设备中,块接口是对位于闪存顶部的复杂设备控制器的抽象。

闪存设备通常具有非常大的块(称为擦除单元,128kB 的大小并不少见),可以在更慢的擦除发生之前写入一次。设备的控制器在块接口(如主机所见)和物理设备上的擦除单元之间实现逻辑<->物理映射。作为管理过程的一部分,控制器将实施错误检测和纠正,并管理有缺陷的擦除单元。这整个过程在块界面是不可见的。

因此,由于逻辑块永远不会永久映射到物理擦除单元,因此不可能从块接口执行有意义的坏块扫描。

如果您碰巧有一个由该mtd层管理的直接连接的闪存阵列,mtd-tools那么这就是您想要的,以及相应的内核模块。文档可以在这里找到

于 2013-01-10T01:24:44.147 回答
0

现代硬件通常可以识别数据损坏,即您更有可能遇到 I/O 错误,而不是实际从设备读取错误数据。此外,设备通常包含一些冗余,因此会检测到坏块并用好块替换。对于现代硬盘,SMART将提供有关坏块计数的信息。不确定这是否也适用于常见的闪存设备,但我猜是这样。

于 2013-01-10T10:39:04.397 回答