如何检查 SD 卡的健康状况?
当我想检查硬盘时,我可以使用SMART,我应该如何检查SD卡?有通用的方法吗?
我刚刚格式化了microSD卡,想运行一个dd
命令。不幸的是dd
命令失败:
$ sudo dd bs=1m if=2016-02-26-raspbian-jessie-lite.img of=/dev/rdisk2
dd: /dev/rdisk2: Resource busy
$
Run Code Online (Sandbox Code Playgroud)
互联网上的每个人都说我需要先卸载磁盘。当然,可以做到这一点并继续前进。但我想了解为什么/在 OS X 中究竟是什么让设备忙碌?我该如何诊断?
到目前为止,我尝试过:
列出打开的文件:
$ lsof /dev/disk2
$ lsof /dev/disk2s1
$
Run Code Online (Sandbox Code Playgroud)
还:
$ lsof /Volumes/UNTITLED
$
Run Code Online (Sandbox Code Playgroud)列出处理文件的用户:
$ fuser -u /dev/disk2
/dev/disk2:
$ fuser -u /dev/disk2s1
/dev/disk2s1:
$
Run Code Online (Sandbox Code Playgroud)
还:
$ fuser -u /Volumes/UNTITLED
$
Run Code Online (Sandbox Code Playgroud)检查系统消息:
$ sudo dmesg | grep disk
$
Run Code Online (Sandbox Code Playgroud)
还:
$ sudo dmesg | grep /Volumes/UNTITLED
$
Run Code Online (Sandbox Code Playgroud)我的环境
操作系统:
Darwin Eugenes-MacBook-Pro-2.local 15.3.0 Darwin Kernel Version 15.3.0: Thu …
Run Code Online (Sandbox Code Playgroud)昨天我与某人就我在这里回答的逻辑和/或真实性进行了一场小辩论,vis.,在一个像样的 (GB+) 大小的 SD 卡上记录和维护 fs 元数据永远不会足够重要到佩戴该卡在合理的时间内(年和年)。反驳的要点似乎是我一定是错的,因为网上有很多关于人们磨损 SD 卡的故事。
由于我确实有带有 SD 卡的设备,其中包含 24/7 保留的 rw 根文件系统,因此我之前已经测试过这个前提,令我自己满意。我稍微调整了这个测试,重复了它(实际上是使用同一张卡)并在这里展示它。我的两个核心问题是:
我把问题放在这里而不是 SO 或 SuperUser 因为对第一部分的反对可能不得不断言我的测试并没有像我确定的那样真正写入卡,并且断言这需要一些linux 的特殊知识。
[也可能是 SD 卡使用某种智能缓冲或缓存,这样对同一位置的重复写入将被缓冲/缓存在不易磨损的地方。我在任何地方都没有发现任何迹象,但我在 SU 上询问了这一点]
测试背后的想法是向卡上的同一个小块写入数百万次。这远远超出了此类设备可以承受多少写入周期的任何说法,但假设磨损均衡是有效的,如果卡的大小合适,那么数百万次此类写入仍然无关紧要,因为“同一个块”会不是字面上的相同物理块。为此,我需要确保每次写入都真正刷新到硬件,并刷新到相同的明显位置。
为了刷新到硬件,我依赖于 POSIX 库调用fdatasync()
:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
// Compile std=gnu99
#define BLOCK 1 << 16
int main (void) {
int in = open ("/dev/urandom", O_RDONLY);
if (in < 0) { …
Run Code Online (Sandbox Code Playgroud) 在基于 SD 卡的设备不正常关机后,我将 SD 卡取出到fsck
根文件系统。这导致了以下变化:
e2fsck 1.43.1 (08-Jun-2016)
/dev/sdc2: recovering journal
Superblock needs_recovery flag is clear, but journal has data.
Run journal anyway<y>? no
Clear journal<y>? no
e2fsck: unable to set superblock flags on /dev/sdc2
Run Code Online (Sandbox Code Playgroud)
在这里,我两次都回答“否”,但没有一系列是/否不会立即导致相同的结果。
文件系统可以挂载,随便检查一下就可以了;它在设备中也能正常工作,这就是根文件系统(实际上结果不太好,请参阅评论;tldr 一些无法挽回的损坏目录)。
我dd
将分区(8 GB)分配给一个文件,并在其上尝试了 fsck。有趣的是:
e2fsck 1.43.1 (08-Jun-2016)
plush.rootfs: recovering journal
Clearing orphaned inode 18290 (uid=0, gid=0, mode=0100644, size=34096)
Clearing orphaned inode 18270 (uid=0, gid=0, mode=0100644, size=38916)
Clearing orphaned inode 18250 (uid=0, gid=0, mode=0100644, size=1128076)
Clearing orphaned inode 11411 (uid=0, …
Run Code Online (Sandbox Code Playgroud) 我用 gparted 试过,没用。我找到了一个SDFormatter,一个完全擦除的 Windows 工具。
我有一张 SD 卡,想在上面安装 Debian。dd 过程大约需要 45 分钟,之后我退出了。在我的 Windows 机器上,它显示在驱动器列表中,但在尝试格式化甚至打开时也出现未定义的错误。gparted 只是告诉我
/dev/mmcblk0: unrecognised disk label
Run Code Online (Sandbox Code Playgroud)
我发出
dd if='deb.iso' of=/dev/mmcblk0 bs=512k
dd: error writing „/dev/mmcblk0“: I/O error
0+1 data in
0+0 data out
copied 0 Bytes (0 B), 10,098 s, 0,0 kB/s
Run Code Online (Sandbox Code Playgroud)
之后我试过了
root@kali:~# lsblk -o NAME,FSTYPE,MOUNTPOINT,SIZE,RO
NAME FSTYPE MOUNTPOINT SIZE RO
sda 465,8G 0
??sda1 ext4 / 450,1G 0
??sda2 1K 0
??sda5 swap [SWAP] 15,7G 0
sr0 1024M 0
mmcblk0 29,5G 0
Run Code Online (Sandbox Code Playgroud)
mmcblk0 …
我打算将 SD 卡(或闪存驱动器)作为我的主目录,以便能够在不同的 PC 上轻松工作。
出于某种原因,这是一个坏主意吗?
我有一个带有几个 ext4 分区的驱动器(SD 卡),但还有一些未分配的空间。该fstrim
实用程序只能在文件系统中工作。在我重新发明轮子并编写一个之前,是否有另一种实用程序可以修剪未分配的空间(或者可以修剪明确指定的范围)?
我可以验证控制器当前不知道设备上的大部分未分配空间是否可用,正如我观察到的那样,在这张特定的卡上,读取到修剪过的空间返回 0,但设备的扫描显示留下了大量的垃圾数据。
编辑:我在使用hdparm
. 下面的示例丢弃了第一个扇区,但无论我指定的范围如何,我都会看到相同的结果。fstrim
设备上没有问题:
root@ubuntu:~# hdparm --please-destroy-my-drive --trim-sector-ranges 0:1 --verbose /dev/mmcblk0
/dev/mmcblk0:
trimming 1 sectors from 1 ranges
outgoing cdb: 85 0d 06 00 01 00 01 00 00 00 00 00 00 40 06 00
outgoing_data:
00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 …
Run Code Online (Sandbox Code Playgroud) 我们正在开发一个小型嵌入式 Linux 系统(2.6.35-ish),带有一个用于操作系统和应用程序的小型内部 NAND 设备(250-500Meg)和一个带有 8Gb SDHC SD 卡的 SD 卡用于数据。
可以随时切断设备的电源。
系统必须将数据存储到 SD 卡。这些数据非常重要……这是系统的全部目的。这些系统通常与远程位置的任何网络完全断开,每 4-8 周通过运动鞋网检索数据。
目前,我们只是在 SD 卡上安装了 VFAT。这主要是为了让第一批测试客户可以轻松地将数据手动复制到他们的 Win7 笔记本电脑上。
但是,我现在担心在错误的时间断电导致数据丢失只是时间问题。
配置此类系统以防止数据丢失的最佳方法是什么?JFFS2 在写入数据的方式方面听起来像是我想要的(并且性能需求根本不高),但是使用 block2mtd 等听起来相当笨拙。我也不确定卡的磨损均衡将如何交互用它。
做到这一点的最佳方法是什么?
编辑
我现在正在考虑离开文件系统 VFAT 并一次分配一天大小的文件,填充 0xFF,这应该会极大地限制电源循环故障的风险。然后我只能在这些预先创建的块中附加记录,希望 SD 卡不会太愚蠢以至于它们会擦除/磨损级别写入 0xFF 区域。
我可以使用 noatime,但是是否有等效的 VFAT nomtime 来防止写入修改后的时间字段?在创建新的一天的文件之前,我需要某种方法来阻止任何元数据更新。
编辑 2
电子堆栈交换中的某个人提醒我,NAND 上也有 ECC 数据,因此无法防止需要擦除。
那么,在这种情况下,通过 block2mtd 的 JFFS2 是否合适?
编辑 3
这比我想象的还要糟糕。即使您将完全相同的内容写入磁盘,我拥有的 SD 卡也会擦除数据块。擦除块是 64KB,这太大了,无法完全延迟写入。我将在 NAND 闪存中存储多达 128KB 的数据(我可以控制其写入行为),在一种日志中,然后将 128KB 块写入 SD 卡上 VFAT 分区中的 128KB 对齐文件(在如果其他 SD 卡有 128KB 擦除块)。
我有几十张 SD 卡需要跟踪一个项目。现在,他们每个人都有一个用永久性记号笔写在外面的数字。这没问题,但我想看看我可以记录的每张 SD 卡中是否内置了一些独特的东西。到目前为止,我知道:
所以,我想我的问题是:
我尝试从 SD 卡运行 Android。这张卡准备好了。有隔板:boot(FAT32)
,rootfs(ext4)
,system(ext4)
,cache(ext4)
和usedata(ext4)
。引导分区有文件来运行的u-boot: MLO
,u-boot.bin
和uImage
。要运行它,我使用命令
mmcinit 0
fatload mmc 0 0x80000000 uImage
setenv bootargs 'console=ttyO2,115200n8 mem=456M@0x80000000 mem=512M@0xA0000000 init=/init vram=10M omapfb.vram=0:4M androidboot.console=ttyO2 root=/dev/mmcblk1p2 rw rootwait rootfstype=ext4'
bootm 0x80000000
Run Code Online (Sandbox Code Playgroud)
比我看到 Linux 是如何启动的。但是在加载步骤几秒钟后,rootfs
我看到一条错误消息
[ 4.015655] EXT4-fs (mmcblk1p2): couldn't mount RDWR because of unsupported optional features (400)
[ 4.036499] sd 0:0:0:0: [sda] Attached SCSI removable disk
[ 4.079986] List of all partitions:
[ 4.083801] b300 31162368 mmcblk0 …
Run Code Online (Sandbox Code Playgroud)