e2fsprogs
是用于 ext2/3/4
文件系统的工具集,其中 badblocks
工具用于检测磁盘坏块。嵌入式系统使用的 eMMC
也可以用它来检测当前 Flash 的健康状况。我希望把它单独拿出来,做成一个测试工具
badblocks 说明
badblocks
用于搜索设备(通常是磁盘分区)上的坏块。 device
是设备对应的特殊文件(例如 /dev/hdc1
)。 last_block
是要检查的最后一个块,如果没有指定,则使用设备上的最后一个块作为默认值。 first_block
是一个可选参数,指定测试的起始块号,允许测试从磁盘中间开始。如果没有指定,则使用磁盘上的第一个块作为默认值。
重要提示:如果
badblocks
的输出要被送入e2fsck
或mke2fs
程序,正确指定块大小是很重要的,因为生成的块数非常依赖于文件系统所使用的块大小,因此强烈建议用户不要直接运行badblocks
,而是使用e2fsck
和mke2fs
程序的-c
选项。
选项说明
-
b
: `block_size指定块的大小,单位为字节。默认值是1024。
-
c
: 块的数量是指每次测试的块数。默认值是64。
-
d
: 读取延迟因子这个参数如果有且不为零,如果在读操作中没有遇到错误,将导致坏块在读之间休眠;延迟时间将按读操作所需时间的百分比计算。换句话说,值为100时,将使每次读的延迟时间为前一次读所花费的时间,值为200时,则延迟时间为前一次读所花费的时间的两倍。
-
e
: 最大坏块数 指定中止测试前的最大坏块数。默认值是0,意味着测试将继续进行,直到达到测试范围的终点。 -
f
:force
通常情况下,
badblocks
会拒绝对已挂载的设备进行读/写或非破坏性测试,因为即使它是只读挂载,也会导致系统潜在的崩溃和/或损坏文件系统。这个选项可以用-f
标志覆盖,但几乎不应该使用—如果你认为你比badblocks
程序更聪明,那你肯定不是。只有当/etc/mtab
文件不正确,并且设备确实没有被挂载的时候,这个选项才可以安全使用。 -
i
:input_file
读取已经存在的已知坏块的列表。
Badblocks
将跳过对这些块的测试,因为它们是已知的坏块。如果input_file
被指定为 “-“,那么这个列表将从标准输入中读取。该列表中列出的块将从标准输出或输出文件中产生的新坏块列表中被省略。dumpe2fs(8)
的-b
选项可以用来检索当前在现有文件系统中被标记为坏块的列表,其格式适用于这个选项。 -
n
使用非破坏性读写模式。默认情况下,只进行非破坏性的只读测试。这个选项不能和-w选项结合使用,因为它们是相互排斥的。
-
o
:output_file
将坏块的列表写入指定的文件。如果没有这个选项,
badblocks
会在它的标准输出中显示这个列表。这个文件的格式适合e2fsck(8)
或mke2fs(8)
的-l
选项使用。 -
p
:num_passes
重复扫描磁盘,直到在连续扫描磁盘的
num_passes
中没有发现新的块。默认值是0,意味着坏块将在第一次扫描后退出。 -
s
通过写出当前
badblocks
在磁盘上的大致完成百分比来显示扫描的进度。请注意,badblocks
可能会在磁盘上进行多次测试,特别是当用户要求使用-p
或-w
选项时。 -
t
:test_pattern
指定一个要读(和写)到磁盘块的测试模式。
test_pattern
可以是一个介于0和ULONG_MAX-1
之间的数值,也可以是 “random”一词,指定磁盘块应该用一个随机的比特模式来填充。对于读/写(-w)和非破坏性(-n)模式,可以通过为每个需要的测试模式指定-t选项来指定一个或多个测试模式。对于只读模式,只能指定一个模式,而且不能是”随机”的。使用只读模式测试假定指定的模式已经被写入磁盘–如果没有,大量的块将无法通过验证。如果指定了多个模式,那么在进入下一个模式之前,所有的块都将用一个模式进行测试。 -
v
Verbose
模式,将读取错误、写入错误和数据损坏的数量写入stderr
-
w
使用写入模式测试。使用该选项,
badblocks
会通过在设备的每个块上写入一些模式(0xaa、0x55、0xff、0x00
)来扫描坏块,读取每个块并比较其内容。此选项不可与-n
选项结合使用,因为它们是相互排斥的。 -
B
使用缓冲
I/O
,不要使用Direct I/O
,即使它是可用的。 -
X
仅由
e2fsck(8)
和mke2fs(8)
使用的内部标志。它绕过了独占模式下的使用中设备安全检查。
警告 切勿在包含现有文件系统的设备上使用
-w
选项。这个选项会删除数据 如果你想在现有的文件系统上进行写模式测试,请使用-n
选项。它的速度较慢,但它会保存你的数据。-e
选项会导致badblocks
输出一个可能不完整的坏块列表。因此,建议只在想知道设备上是否有坏块时使用,而不是在想要坏块列表时使用。
编译配置
cd e2fsprogs-1.45.6/build
# 配置好编译选项
../configure --prefix=/home/wilson/gitRepos/e2fsprogs-1.45.6/build CC=/KIDE/tools/gcc-arm-linux-gnueabi/bin/arm-linux-gnueabihf-gcc --host=arm-linux-gnu
# 编译
make -j8
# 安装
make install
根据GNU惯例,软件构建中涉及到三个平台:
build
构建平台:编译工具执行的平台host
主机平台:编译出来的程序将在其上运行的平台target
目标平台:只有在构建编译器时,这才是编译器生成程序运行的平台
所以
- 对于
e2fsprogs
项目,构建平台是x86_64-pc-linux-gnu
- 对于
e2fsprogs
项目,最终编译出来的程序是运行在arm
板上的,根据编译工具链,可以知道host = arm-linux-gnu
- 对于
e2fsprogs
项目,它不是编译器,涉及不到target
目标平台
完成安装后,可以找到 e2fsprogs-1.45.6/build/sbin/badblocks
程序
tasks.json
通过 build.sh
脚本先构建要调试的程序 badblocks
{
// 有关 tasks.json 格式的文档,请参见
// https://go.microsoft.com/fwlink/?LinkId=733558
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "gcc build active file",
"command": "${fileDirname}/build.sh",
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}
launch.json 的配置
在 vscode 中通过 gdb 下载编译好的代码并开始调试,launch.json
的设置如下
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "gcc - 生成和调试活动文件",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/sbin/badblocks",
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "为 gdb 启用整齐打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "连接下位机gdbserver",
"text": "target extended-remote 128.249.182.116:9091"
},
{
"description": "读取符号信息",
"text": "file ${workspaceFolder}/build/sbin/badblocks"
},
{
"description": "删除调试程序",
"text": "remote delete badblocks",
"ignoreFailures": true
},
{
"description": "下载编译好的程序",
"text": "remote put ${workspaceFolder}/build/sbin/badblocks badblocks",
},
{
"description": "连接调试程序",
"text": "set remote exec-file badblocks"
},
{
"description": "设置参数",
"text": "set args -s -v /dev/mmcblk0"
}
],
"preLaunchTask": "gcc build active file",
"miDebuggerPath": "/home/wilson/.wgdb/gdb",
}
]
}