Recovering Data from a Corrupted SD Card

SD cards are used in digital cameras, phones and other devices, where their speed and large capacity makes them useful for storing pictures, video and other voluminous multi-media items. It is quite common these days for a mobile device to contain a 16 Gb or 32 Gb SD card.

With the devices being so mobile, backups are easily overlooked. And it is quite easy for an SD card to become corrupted, for example if the card is removed while the device is on, or the battery is taken out while a video is being shot.

I was given a corrupted 16 Gb card and asked to recover the files, if possible. The rest of this post explains how the data was safely restored using simple Linux tools.

The SD card was a 16 Gb Sandisk model from a digital camera. The user’s Windows 7 desktop would not read the card and offered only to reformat it, which was not a viable option as it would have destroyed all the data.

General Plan

As is usual with this sort of recovery, the plan was to take an exact image of the SD card and recover data from that, while leaving the original card untouched.

Safety First

To prevent any further data corruption, I set the card’s read-write tab to “read only“, then inserted it into a Linux laptop.

First Look at the Data

Linux recognised the card straight away and its files were actually visible in the file browser (Thunar in this case), though according to df it was not mounted. I/O errors appeared in the /var/log/messages file however, confirming corruption in the file system. At this point, an attempt could have been made to recover the data by simply copying all of the files off the card using the GUI. But that would have been to risk perpetuating the corruption and/or losing some of the recoverable data. It is better to fix the corruption first, then restore the corrected data.

Identify the File System

The next step is to gather some basic information about the file system.

Ran fdisk:

[root@Acer ~]# fdisk -l

Disk /dev/mmcblk0: 15.9 GB, 15931539456 bytes
255 heads, 63 sectors/track, 1936 cylinders, total 31116288 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1            8192    31116287    15554048    c  W95 FAT32 (LBA)

The device associated with the SD card itself is /dev/mmcblk0. More importantly, /dev/mmcbk0p1 is the device associated with the card’s file system. It looks like the type is FAT32, but that is just an indication derived from the type flag on the partition, and isn’t necessarily the correct file system type. Use blkid for that:

[root@Acer ~]# blkid
/dev/mmcblk0p1: UUID="6564-6530" TYPE="vfat"
/dev/loop0: UUID="6564-6530" TYPE="vfat"

So the file system type is definitely VFAT. And the associated device node is /dev/mmcblk0p1.

Attempt to Mount the File System

I was curious to see if the file system would mount. This was to gather more information about the corruption and was not strictly necessary for the data recovery. If you are in a similar situation, you could just skip forward to the step “Taking an Image of the File system”

Proceeded as follows.

[root@Acer ~]# mount /dev/mmcblk0p1 /mnt2
mount: block device /dev/mmcblk0p1 is write-protected, mounting read-only

It mounted but put these errors into /var/adm/messages:

Jan 4 00:48:18 Acer kernel: [26294.572758] mmcblk0: error -110 transferring data, sector 10847, nr 1, cmd response 0x900, card status 0x0
Jan 4 00:48:18 Acer kernel: [26294.572765] end_request: I/O error, dev mmcblk0, sector 10847
Jan 4 00:48:18 Acer kernel: [26294.700808] mmcblk0: error -110 transferring data, sector 10844, nr 1, cmd response 0x900, card status 0x0
Jan 4 00:48:18 Acer kernel: [26294.700813] end_request: I/O error, dev mmcblk0, sector 10844
Jan 4 00:48:18 Acer kernel: [26294.700847] FAT-fs (mmcblk0p1): FAT read failed (blocknr 2652)

I kicked of a “cp” command to copy the files from the SD card mounted at /mnt2. It gave these errors:

Jan 4 01:08:53 Acer kernel: [27529.518134] mmcblk0: error -110 transferring data, sector 10844, nr 1, cmd response 0x900, card status 0x0
Jan 4 01:08:53 Acer kernel: [27529.518143] end_request: I/O error, dev mmcblk0, sector 10844
Jan 4 01:08:53 Acer kernel: [27529.518182] FAT-fs (mmcblk0p1): FAT read failed (blocknr 2652)
Jan 4 01:08:53 Acer kernel: [27529.646174] mmcblk0: error -110 transferring data, sector 10844, nr 1, cmd response 0x900, card status 0x0
Jan 4 01:08:53 Acer kernel: [27529.646180] end_request: I/O error, dev mmcblk0, sector 10844
Jan 4 01:08:53 Acer kernel: [27529.646236] FAT-fs (mmcblk0p1): FAT read failed (blocknr 2652)
Jan 4 01:08:53 Acer kernel: [27529.776694] mmcblk0: error -110 transferring data, sector 10844, nr 1, cmd response 0x900, card status 0x0
Jan 4 01:08:53 Acer kernel: [27529.776700] end_request: I/O error, dev mmcblk0, sector 10844

and finally:

Jan 4 01:09:40 Acer kernel: [27576.220548] FAT-fs (mmcblk0p1): FAT read failed (blocknr 2652)
Jan 4 01:09:40 Acer kernel: [27576.348602] mmcblk0: error -110 transferring data, sector 10844, nr 1, cmd response 0x900, card status 0x0
Jan 4 01:09:40 Acer kernel: [27576.348671] FAT-fs (mmcblk0p1): FAT read failed (blocknr 2652)
Jan 4 01:09:40 Acer kernel: [27576.476781] mmcblk0: error -110 transferring data, sector 10844, nr 1, cmd response 0x900, card status 0x0
Jan 4 01:09:40 Acer kernel: [27576.476812] FAT-fs (mmcblk0p1): FAT read failed (blocknr 2652)
cp: reading `/mnt2/DCIM/100D3100/DSC_1015.MOV’: Input/output error
cp: failed to extend `./DCIM/100D3100/DSC_1015.MOV’: Input/output error

Unmounted the card with umount /mnt2.

Taking an Image of the File System

Made image of card’s file system with dd:

dd if=/dev/mmcblk0p1 of=/home/mmcblk0p1.dd bs=1024k conv=noerror,sync

The option conv=noerror,sync tells dd what to do when it encounters any errors on the SD card. Instead of just stopping with an error message, dd will place zeros in the output file corresponding to parts of the card it could not read. (Similar behaviour to dd_rescue)

dd took maybe 45 mins to complete, and produced a large (16 Gb) file called mmcblk0p1.dd. That file contains a copy of the file system residing on the SD card, with unreadable areas replaced by zeros. The next step is to fix the corruption in the image.

Repairing the File System Image

Linux repair tools can be used on the image file just as they can be used on a “real” file system. In this case dosfsck -a was used. Note if dosfsck -a does not work for you, try dosfsck -r instead (see comment from Robert below).

[root@Acer ~]# dosfsck -a mmcblk0p1.dd
dosfsck 3.0.12, 29 Oct 2011, FAT32, LFN
FATs differ but appear to be intact. Using first FAT.
/DCIM/100D3100/DSC_1015.MOV
  Contains a free cluster (262400). Assuming EOF.
/DCIM/100D3100/DSC_1015.MOV
  File size is 1385503025 bytes, cluster chain length is 123731968 bytes.
  Truncating file to 123731968 bytes.
Performing changes.
mmcblk0p1.dd.orig: 639 files, 262398/485936 clusters

Mounting the Repaired Image and Recovering Files

Restoring the files is simple now. Mounted the file system image as a loopback mount:

mount -t vfat -o loop mmcblk0p1.dd /mnt

Unlike the first exploratory mount above, this put no errors into /var/log/messages. I copied all files from /mnt to a spare USB stick with “cp” command, again monitoring /var/log/messages and finding no errors generated. Over 600 files were restored, totalling about 8 Gb.

Handed the user his restored files on the USB stick, along with the original SD card. The SD card itself was not altered (the read-write tab still being set to “read only”). The user can reformat the card under Windows and copy the files back if he wishes, or back them up elsewhere (recommended).

Conclusion

1. The file system fix command dosfsck could have been applied directly to the card, rather than to an image taken from the card. That is: dosfsck -a /dev/mmcblk0p1 would almost certainly have fixed the card in one step. However this was not attempted due to the risks outlined at the outset of this post, and because the jeopardized data was very important to the user.

2. The damage was quite small. Just one file was lost, seemingly: a large video called DSC_1015.MOV, apparently 1.3 Gb in size (dosfsck output). Perhaps something happened while that file was being written – maybe the battery was removed while shooting the video ? Or the card might have a physical flaw, which is more serious because it will manifest more file system damage sooner or later.

3. The procedure above could apply equally to other devices, eg. thumb drives, external disks, MP3 players, even Sat Nav systems. Any “dumb” gadget that contains a file system but has only limited self-repair abilities. More intelligent items like tablets, ipads and PCs usually repair their file systems automatically.

5 thoughts on “Recovering Data from a Corrupted SD Card

  1. Thank you, you saved my day.
    I only had one more complication: dosfsck -a did not work for me (said it won’t fix it]. Fortunately, dosfsck -r did the trick.
    Thanks again,

    Robert

  2. Hi,

    Thanks for sharing the information. Do you have any idea about the status codes and its meaning? I could see many times status=0x80900. Do you have any document/link which explains about these status codes?

    mmcblk0: r/w command failed, status = 0x80900
    end_request: I/O error, dev mmcblk0, sector 777
    end_request: I/O error, dev mmcblk0, sector 778
    end_request: I/O error, dev mmcblk0, sector 779
    end_request: I/O error, dev mmcblk0, sector 780
    end_request: I/O error, dev mmcblk0, sector 781
    end_request: I/O error, dev mmcblk0, sector 782
    end_request: I/O error, dev mmcblk0, sector 783
    end_request: I/O error, dev mmcblk0, sector 784
    end_request: I/O error, dev mmcblk0, sector 785
    end_request: I/O error, dev mmcblk0, sector 786
    end_request: I/O error, dev mmcblk0, sector 787

    Thanks,
    Manoj.

    • Hi Manoj

      I’ve not encountered the 0x80900 error and can’t say what it is exactly. It might indicate that the SD card is bad or the file system is corrupted. An fsck might fix the file system. Or it may be necessary to reformat the card from scratch.

Leave a Reply

Your email address will not be published. Required fields are marked *