sd卡数据恢复记

每天手机关机,突然有一天(上周)早上起来开机,提示“SD卡错误,需要重新格式化!” 惊出一头汗。拒绝格式化,关机重启,还是那样。肯定是坏了。拿到Linux上查一下分区表,没了。冷静,备份整个卡先,dd了搞一个8G的映像。然后再看看怎么折腾恢复数据。

第一步,得看看原来是怎么分区的,正确恢复分区表才有可能:

$ hexdump /dev/sdX -C | grep FAT

再查查 FAT Boot Sector 的开头,手工对照一下, 发现分区以4M Bytes偏移开始,也就是8092 sect处,尝试fdisk恢复分区表,dmesg报告IO失败,也就是第一个Sector不可写:卡废了。

没办法网购一张新卡,与此同时尝试读备份映像的数据。采用losetup并且挂载文件系统试试:

$ sudo losetup -o $((4096*1024)) /dev/loop0 phonesdcardbak.img
$ sudo mount -o ro /dev/loop0 testdir

没有问题,看看有没有文件损害:

$ cd testdir
$ du

报告一堆错误外加乱码文件。手工检查一些文件,到也没问题,心里稍微舒服了一点:至少能恢复一些文件。

第二天新卡送来了,sandisk 16G, 默认是分好区的,也是4MByte偏移开始。拷贝了android相关的两个目录进去(没有拷贝完全,还是报告文件系统错误),放在手机里测试下,结果没有一个原来装在SD卡上的程序恢复!有点沮丧。

不过,那些文件系统错误也许不是错误,今天想了个新办法重新试了试:

  1. 把备份的映像原样拷贝到新SD卡上
  2. 在新卡上重新恢复分区表

把新卡装回手机上再一开机,所有程序完美恢复!

为什么?大约与挂载FAT的选项有关,adb shell连上去看看选项:

$ mount

...
/dev/block/vold/179:65 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,relatime,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
...

再尝试使用相同的选项挂载备份映像的分区,发现还是报错。看来Android上VFAT操作还是与Linux上有些不同。到底哪不同?现在不晓得。