在开发板上使用有坏块的SD卡

树莓派已经搞坏了我 3 张 SD 卡了,虽然其中有两次直接戳 SanDisk 和三星客服,直接根据保修条款无条件更换了 SD 卡。

但事实上 SD(TF) 卡并不能承受多少次写入。根据闪存颗粒类型不同,MLC 颗粒的寿命要高于 TLC 颗粒,较为廉价的 SD 卡一般使用 TLC 颗粒,擦写次数不过千次。常规的 Linux 系统会在使用中删除、写入大量的 Log 数据,SD 卡无法长期稳定使用。

这次尝试以一些奇怪的方式利用坏掉的SD卡启动板子。

修复损坏的文件

最近我的一块 Orange Pi One 无法正常工作,连接 UART 后发现 Kernel 可以正常载入但 SSH 服务的部分文件丢失导致 SSH 服务无法正常启动。

在没有 SD 卡读卡器的情况下,我尝试过使用 Root 后的安卓手机对 EXT4 格式分区数据做修复:

  • 删除密码:在 /etc/rc.local 中写入 passwd -d root

  • 重启后通过 TTL 线连接并登录,创建 SSH 服务所需的文件

再次重启板子正常工作。

然而一天过去再次重启板子又炸了。这说明损坏的数据应该有相当一部分了。

跳过坏块刷写数据

我使用了一张 32GB 的 SD 卡,然而实际频繁写入数据的最多也不超过 8GB 。那么我们跳过这 8GB ,就不会碰到坏损的数据块了。

这里我使用 Armbian 。下载镜像后使用 WinHex 打开镜像文件,发现第一个 Block 是 MBR 数据。读分区数据后发现只有一个数据分区(block8192 - block1826816)。block1 - block8191的数据应该是Bootloader。

这里直接跳过前 8GB,将 MBR 表中的分区开头block8192改为block16777216。然后 dd if=armbian.img of=/dev/sdb bs=512 count=8192 将 MBR 数据和 Bootloader 写入 SD 卡。之后只需要将分区数据写入:dd if=armbian.img of=/dev/sdb bs=512 count=1818624 skip=8192 seek=16777216

插入卡后正常启动。

尽量避免写入

将/tmp、/var/log等挂载到RAM

关闭SWAP分区或SWAP文件,并挂载 tmpfs 分区。编辑 /etc/fstab 文件,为分区添加 noatime 省掉更新文件修改时间带来的磁盘写入。

1
2
3
4
none        /var/run        tmpfs   size=1M,noatime         0 0
none /var/log tmpfs size=1M,noatime 0 0
none /var/tmp tmpfs size=1M,noatime 0 0
none /tmp tmpfs size=1M,noatime 0 0

使用 overlayfs

参考 Armbian 文档:

1
2
3
apt-get install overlayroot
echo 'overlayroot="tmpfs"' >> /etc/overlayroot.conf
reboot

在需要保存修改的时候:

1
overlayroot-chroot