如何在 Linux 中测试 SD 卡的全部容量?

Ear*_*ine 18 sd-card bad-blocks

我从 eBay 购买了 64 GB SD 卡。当我将 Arch Linux ARM 映像刻录到它并使用它来启动我的 Raspberry Pi 时,它工作正常。

但是,当我尝试在其上创建单个 ext4 分区以使用卡的所有容量时,会发生错误。mkfs.ext4总是幸福地结束;但是,分区不能被mount编辑,总是抛出错误并dmesg显示内核消息包括Cannot find journal. 事实证明,至少在两个平台上都是这种情况:Arch Linux ARM 和 Ubuntu 13.04。

另一方面,我可以无误地创建和挂载 FAT32 分区(尚未完成全容量检查)。

我听说有些坏人可以更改 SD 卡接口以向操作系统报告错误的容量(即该卡实际上只有 2 GB,但它报告自己为 64 GB),以便以更好的价格出售该卡。

我知道有类似的工具badblocks可供我检查 SD 卡是否存在坏块。能badblocks检测出这样的问题吗?如果没有,还有什么其他解决方案可供我测试卡?

理想情况下,我想知道我是否被骗了;如果结果显示我刚收到一件坏物品,我只能退回给卖家,而不是向 eBay 报告有人试图欺骗我。

更新

操作和消息:

~$ sudo mkfs.ext4 /dev/sde1
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
4096000 inodes, 16383996 blocks
819199 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
500 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
    32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
4096000, 7962624, 11239424

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done   

~$ dmesg | tail
...
[4199.749118]...
~$ sudo mount /dev/sde1 /mnt
mount: wrong fs type, bad option, bad superblock on /dev/sde1,
   missing codepage or helper program, or other error
   In some cases useful info is found in syslog - try
   dmesg | tail  or so

~$ dmesg | tail
...
[ 4199.749118]...
[ 4460.857603] JBD2: no valid journal superblock found
[ 4460.857618] EXT4-fs (sde1): error loading journal
Run Code Online (Sandbox Code Playgroud)

更新

我已经运行badblocks /dev/sde但它没有报告错误。这意味着剩下的原因是:

  • SD 车很好,但由于某种原因mke2fsmount内核存在导致问题的错误。

  • 我以一种badblocks无法察觉失败的方式被欺骗了。这是合理的,因为我认为badblocks只是在进行一些就地读写测试。但是,作弊者可以使对出站区域的访问链接回某些入站块。在这种情况下,就地读写检查无法检测到问题。

如果没有应用程序可以做适当的测试,我想我可以尝试编写一个简单的C程序来测试它。

小智 27

如果稍后有人看到:有人编写了一个名为“F3”的开源工具来测试 SD 卡和其他此类媒体的容量。它可以在项目主页Github 中找到


Ear*_*ine 6

现在已经通过以下步骤确认作弊:

  • 生成随机数据文件。(4194304 = 4 × 1024 × 1024 = 4?MiB,总大小 = 40 × 4?MiB = 160?MiB)

    命令:

    dd if=/dev/urandom of=test.orig bs=4194304 count=40
    40+0 records in
    40+0 records out
    167772160 bytes (168 MB) copied, 11.0518 s, 15.2 MB/s
    
    Run Code Online (Sandbox Code Playgroud)
  • 将数据复制到 SD 卡。(2038340 × 4096 = 8153600?KiB = 7962.5?MiB)

    命令:

    sudo dd if=test.orig of=/dev/sde seek=2038399 bs=4096
    40960+0 records in
    40960+0 records out
    167772160 bytes (168 MB) copied, 41.6087 s, 4.0 MB/s
    
    Run Code Online (Sandbox Code Playgroud)
  • 从 SD 卡读回数据。

    命令:

    sudo dd if=/dev/sde of=test.result skip=2038399 bs=4096 count=40960
    40960+0 records in
    40960+0 records out
    167772160 bytes (168 MB) copied, 14.5498 s, 11.5 MB/s
    
    Run Code Online (Sandbox Code Playgroud)
  • 显示结果

    命令:

    hexdump test.result | less
    ...
    0000ff0 b006 fe69 0823 a635 084a f30a c2db 3f19
    0001000 0000 0000 0000 0000 0000 0000 0000 0000
    *
    1a81000 a8a5 9f9d 6722 7f45 fbde 514c fecd 5145
    
    ...
    
    Run Code Online (Sandbox Code Playgroud)

发生了什么?我们观察到零的差距。这是随机数据尚未真正写入卡的指示符。但是为什么数据会在之后回来1a81000呢?显然该卡有一个内部缓存。

我们还可以尝试调查缓存的行为。

hexdump test.orig | grep ' 0000 0000 '
Run Code Online (Sandbox Code Playgroud)

没有提供任何结果,这意味着生成的垃圾没有这样的模式。?但是,

hexdump test.result | grep ' 0000 0000 '
0001000 0000 0000 0000 0000 0000 0000 0000 0000
213b000 0000 0000 0000 0000 0000 0000 0000 0000
407b000 0000 0000 0000 0000 0000 0000 0000 0000
601b000 0000 0000 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)

有 4 场比赛。

所以这就是它通过badblocks检查的原因。进一步测试可以看出,实际容量为7962.5?MB,略小于8?GB。

我的结论是这不太可能只是随机的硬件故障,而更有可能是一种作弊(即欺诈)。我想知道我可以采取什么行动来帮助其他受害者。

更新 11/05/2019

  • 人们问我如何找出正确的seek参数是2038399. 我做了比我在上面展示的更多的经验。基本上你必须首先猜测。您必须猜测适当的数据大小,并且必须猜测数据损坏的位置。但是你总是可以使用二分法来帮助。

  • 在下面的评论中,我认为我假设上面的第二步(将数据复制到 SD 卡)仅复制 1 个扇区。但我在实验中并没有犯这个错误。相反,它seek是为了表明在“显示结果”步骤中,偏移量1000只是发生在数据的第二个扇区中。如果seek是 2038399 个扇区,则腐败在第 2038400 个扇区。