Reputation: 49473
I need to create a utility to check for bad sectors in flash memory.
I started out with an old flash drive that I have, I stuck it in my Ubuntu laptop and checked the dmesg
to see it was mounted as /dev/sdb
, I then ran fdisk
to see the number/size of the sectors:
mike@mike-Qosmio-X770:~$ sudo fdisk -l [sudo] password for mike:
Disk /dev/sdb: 127 MB, 127926272 bytes 16 heads, 32 sectors/track, 488 cylinders, total 249856 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: 0x6b3ee723Device Boot Start End Blocks Id System /dev/sdb1 * 32 249854 124911+ b W95 FAT32
So great, I know a sector is 512 bytes and there should be a total of 249,856 of them. Based on that I wrote this small test program to double check:
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
FILE * fp = NULL;
char buffer[512] = {0}; // size of a sector, 512 bytes
long sector_count = 0;
fp = fopen("/dev/sdb", "rb"); // open the flash device as binary
if(fp == NULL) {
printf("Can't open the flash drive!\n");
return -1;
}
while(!feof(fp) && (fread(buffer, sizeof(buffer), 1, fp) > 0)){
sector_count++;
}
fclose(fp);
printf("Sectors: %ld\n", sector_count);
return 0;
}
Worked wonderfully, reported 249856. Now I'm stuck thinking how to proceed. Would it work to write a series of 0xFF
's to the drive (512x249856 1
bit's), then read it back to make sure it got set to 1? Then write the same number of 0
s to make sure it can be cleared?
Would that verify that everything's working? Is there any chance I could overwrite the FTL (Flash translation layer) code or is that protected even from me messing around with the drive like this?
<background for interested parties>
This is for a project where we have a uCLinux 2.4 kernel with strange behavior.. we suspect bad hardware (specificly the flash) but I can't find good tools that work on 2.4 to test the flash fs so I thought I'd try to write my own.
</background>
Upvotes: 3
Views: 3508
Reputation: 61027
Modern hardware can usually recognize data corruption, i.e. you are more likely to encounter an I/O error than actually reading bad data from a device. Furthermore, the devices usually contain some amount of redundancy, so bad blocks will be detected and replaced with good ones. For modern hard discs, S.M.A.R.T. will give information on the bad block count. Not sure whether this works for common flash devices as well, but I'd guess so.
Upvotes: 0
Reputation: 9169
I'm guessing that since your device is mounted on /dev/sdb1
we're dealing with some kind of removable flash media device such as a USB-stick or media-card. If you are dealing with an SATA attached SSD, similar considerations apply.
In these devices, the block-interface is an abstraction for a complex device controller that sits on top of the flash.
Flash devices typically have very large blocks (called erase units, 128kB is not uncommon as a size) which can be written once before a much slower erase takes place. The device's controller implements a logical<->physical mapping between the block interface - as seen by the host - and erase-units on the physical device. As part of the management process, the controller will implemented error detection and correction and manage defective erase units. This entire process is invisible at the block interface.
Consequently, as logical blocks never have a permanent mapping to physical erase units, it is impossible to perform a meaningful bad-block scan from the block-interface.
If you happen to have a directly attached flash array managed by the mtd
layer, mtd-tools
is what you want, along with the corresponding kernel-modules. Documentation can be found here
Upvotes: 2