SD cards are used in a variety of devices like digital cameras. Many times SD cards get removed from the devices, connected to a PC and reconnected back to the device. At some point, the SD card might be removed too early or the card simply starts slowly to die. This is the point where data might be unreadable and need recovery.
Symptoms
When I recently received an SD card to recover its inaccessible data, I decided to use it as an example for this article. The first indication noticed by the owner of the SD card was that it did not mount anymore.
When the SD card was first connected, the device showed up but the system could not read the partition layout.
$ parted -l ... Error: /dev/mmcblk0: unrecognised disk label Model: SD SL32G (sd/mmc) Disk /dev/mmcblk0: 31,9GB Sector size (logical/physical): 512B/512B Partition Table: unknown Disk Flags:
A quick peak into the system’s log files (/var/log/syslog on debian based distributions) revealed a lot of I/O errors like those shown below.
Mar 10 19:32:28 ProBook kernel: [17614.250406] mmcblk0: retrying using single block read Mar 10 19:32:28 ProBook kernel: [17614.250779] mmcblk0: error -84 transferring data, sector 323008, nr 8, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.251188] mmcblk0: error -84 transferring data, sector 323009, nr 7, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.251623] mmcblk0: error -84 transferring data, sector 323010, nr 6, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.252027] mmcblk0: error -84 transferring data, sector 323011, nr 5, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.252427] mmcblk0: error -84 transferring data, sector 323012, nr 4, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.252824] mmcblk0: error -84 transferring data, sector 323013, nr 3, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.253208] mmcblk0: error -84 transferring data, sector 323014, nr 2, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.253582] mmcblk0: error -84 transferring data, sector 323015, nr 1, cmd response 0x900, card status 0x0 Mar 10 19:32:28 ProBook kernel: [17614.254039] mmcblk0: error -84 transferring data, sector 323008, nr 8, cmd response 0x900, card status 0xb00 Mar 10 19:32:28 ProBook kernel: [17614.254041] mmcblk0: retrying using single block read
Long story short, an attempt to read anything from the SD card failed with only I/O errors. In an unscientific attempt, the SD card was disconnected and reconnected again a few times while watching the log file. After a few attempts, the SD card was connected and the the log showed a few lines indicating the card was detected properly.
$ less /var/log/syslog Mar 11 23:40:34 ProBook kernel: [118895.780348] mmc0: new SDHC card at address aaaa Mar 11 23:40:34 ProBook kernel: [118895.781507] mmcblk0: mmc0:aaaa SL32G 29.7 GiB (ro) Mar 11 23:40:34 ProBook kernel: [118895.793696] mmcblk0: p1
Another check with parted(8) shows a recognized partition layout.
$ parted -l ... Warning: Unable to open /dev/mmcblk0 read-write (Read-only file system). /dev/mmcblk0 has been opened read-only. Model: SD SL32G (sd/mmc) Disk /dev/mmcblk0: 31,9GB Sector size (logical/physical): 512B/512B Partition Table: msdos Disk Flags: Number Start End Size Type File system Flags 1 4194kB 31,9GB 31,9GB primary lba
With the I/O errors gone for now, the next step is important as the SD card could fail again any time.
Creating an image
To work on the corrupt data, best practice is to create a bit-by-bit copy of the affected disk or partition. To create a disc image, dd(1) can be used, or – more suitable for disks / SD cards with potential damage – is ddrescue(1).
The following will use ddrescue to create a raw disk image “SD_card_rescue.img” from the SD card represented by the device “/dev/mmcblk0”. The -f option instructs ddrescue to overwrite the output file. The last file name is the log file to be created by ddrescue.
$ sudo ddrescue -f /dev/mmcblk0 SD_card_rescue.img SD_card_rescue.log GNU ddrescue 1.19 Press Ctrl-C to interrupt rescued: 31914 MB, errsize: 81920 B, current rate: 0 B/s ipos: 2062 MB, errors: 3, average rate: 6204 kB/s opos: 2062 MB, run time: 1.42 h, successful read: 7.88 m ago Finished
Creating a disk image can be quite a time intensive task. While ddrescue is trying to create a disc image, it will attempt to read the data in multiple phases. To get more into details about those phases, check the ddrescue online documentation or run the following command.
$ info ddrescue
Using the image
As described in Mount raw image of entire disc the device can be added using the losetup(8) command.
$ sudo losetup -f -P SD_card_rescue.img
The device is attached to the first available loop device. The first partition of the attached image is assumed to be “loop0p1”. As the file-system is corrupted, it is not possible to mount it directly.
Recover data and partition
To analyse the disk and its partitions, testdisk(1) can be used. Testdisk can be directly installed via the package repository.
$ sudo apt-get install testdisk
Testdisk, when started without any parameters, would list all disks detected but would miss the loop devices. To force testdisk to recognize the attached loop device, the device can be passed as a parameter.
$ testdisk /dev/loop0
Once started, testdisk guides you through the process step by step, providing a menu at the bottom of the screen.
First testdisk will ask to confirm the disk (media) to use. Then, select “Proceed” and hit enter. This will start the detection of the partition table type.
TestDisk 7.0, Data Recovery Utility, April 2015 Christophe GRENIER <grenier@cgsecurity.org> https://www.cgsecurity.org Disk /dev/loop0 - 31 GB / 29 GiB Please select the partition table type, press Enter when done. >[Intel ] Intel/PC partition [EFI GPT] EFI GPT partition map (Mac i386, some x86_64...) [Humax ] Humax partition table [Mac ] Apple partition map [None ] Non partitioned media [Sun ] Sun Solaris partition [XBox ] XBox partition [Return ] Return to disk selection Hint: Intel partition table type has been detected. Note: Do NOT select 'None' for media with only a single partition. It's very rare for a disk to be 'Non-partitioned'.
The “Hint” shows the detected partition table which can be confirmed or changed if necessary. On the screen following, testdisk asks for the action to perform. Select “Analyse” to scan the disk.
TestDisk 7.0, Data Recovery Utility, April 2015 Christophe GRENIER <grenier@cgsecurity.org> https://www.cgsecurity.org Disk /dev/loop0 - 31 GB / 29 GiB - 62333952 sectors Current partition structure: Partition Start End Size in sectors Invalid FAT boot sector 1 P FAT32 LBA 8192 62333951 62325760 1 P FAT32 LBA 8192 62333951 62325760 Warning: Bad starting sector (CHS and LBA don't match) No partition is bootable *=Primary bootable P=Primary L=Logical E=Extended D=Deleted >[Quick Search] [ Backup ] Try to locate partition
The above output shows already an issue with the partition table. The “Quick Search” will try to locate the partition table on the disk. Warnings like the following show more details about the damaged partition table.
Disk /dev/loop0 - 31 GB / 29 GiB - 62333952 sectors Warning: the current number of heads per cylinder is 1 but the correct value may be 128. You can use the Geometry menu to change this value. It's something to try if - some partitions are not found by TestDisk - or the partition table can not be written because partitions overlaps.
At this point, testdisk detected the partition table successfully and provides details about it. Now there are two possibilities, just copy files off the image or try to restore the partition by following the next step. As the focus is to restore the data, there is no need to repair the partition if the data can be extracted directly as well.
TestDisk 7.0, Data Recovery Utility, April 2015 Christophe GRENIER <grenier@cgsecurity.org> https://www.cgsecurity.org Disk /dev/loop0 - 31 GB / 29 GiB - 62333952 sectors Partition Start End Size in sectors >P FAT32 LBA 8192 62334975 62326784 [NO NAME] Structure: Ok. Use Up/Down Arrow keys to select partition. Use Left/Right Arrow keys to CHANGE partition characteristics: *=Primary bootable P=Primary L=Logical E=Extended D=Deleted Keys A: add partition, L: load backup, T: change type, P: list files, Enter: to continue FAT32, blocksize=32768, 31 GB / 29 GiB
As the highlighted menu option shows, the files in the file-system of the disc can be listed directly from within testdisk via the “P” key.
TestDisk 7.0, Data Recovery Utility, April 2015 Christophe GRENIER <grenier@cgsecurity.org> https://www.cgsecurity.org P FAT32 LBA 8192 62334975 62326784 [NO NAME] Directory / >drwxr-xr-x 0 0 0 23-Jun-2014 01:23 DCIM *drwxr-xr-x 0 0 0 9-Apr-2015 17:53 MISC *drwxr-xr-x 0 0 0 9-Apr-2015 17:53 PRIVATE *-rwxr-xr-x 0 0 407 13-Nov-2015 13:50 MINIONS (F) - Shortcut.lnk Next Use Right to change directory, h to hide deleted files q to quit, : to select the current file, a to deselect all files C to copy the selected files, c to copy the current file
Testdisk lists the files and directories of the partition/file-system and provides the possibility to to select the files and directories (by typing “:”) to be extracted. If everything should be extracted, “a” can be pressed to select all entries, as indicated by the asterisk “*” at the beginning of the line.
By pressing capital “C”, the selected files can be copied. To select the destination directory to copy the selected files and directories to, testdisk provides a similar directory listing. Choose the destination directory and proceed.
TestDisk 7.0, Data Recovery Utility, April 2015 Christophe GRENIER <grenier@cgsecurity.org> https://www.cgsecurity.org P FAT32 LBA 8192 62334975 62326784 [NO NAME] Directory / Copy done! 2098 ok, 0 failed >drwxr-xr-x 0 0 0 23-Jun-2014 01:23 DCIM drwxr-xr-x 0 0 0 9-Apr-2015 17:53 MISC drwxr-xr-x 0 0 0 9-Apr-2015 17:53 PRIVATE Next Use Right to change directory, h to hide deleted files q to quit, : to select the current file, a to deselect all files C to copy the selected files, c to copy the current file
When the copy operation is completed, testdisk provides details about the amount of files successfully copied as well as those that failed.
After exiting from testdisk, to detach the disk image from the loop device, the -d option followed by the loop device to be detached is used with “losetup”.
$ sudo losetup -d /dev/loop0
There are many different reasons why an SD card or a HDD fails. The described recovery procedure worked in this specific case and might work for others, although of course this exact procedure might not work in all cases.
Read more of my posts on my blog at https://blog.tinned-software.net/.