программный ремонт usb flash накопителей в linux


Довольно таки часто занимался программным восстановлением usb flash накопителей на Windows, ну и заинтересовался как можно это реализовать на Linux. Как раз под рукой лежала флэшка JetFlash TS4GJF160 на 4Gb, которая не хотела работать

И так для начала разберемся что же есть программный ремонт. В любой флэшке установлена микросхема-контроллер. Она отвечает за передачу данных между компьютером и флэш-памятью. В случае различных сбоев питания, неправильного извлечения и других причин – происходит сбой контроллера. В результате чего контроллер блокируется и не отвечает на запросы операционной системы. Также, блокировка может произойти из-за износа микросхемы памяти - появления дефектных блоков или превышения порога циклов записи (тогда контроллер сам метит блок как неиспользуемый и часто блокирует флэш на запись). И при попытке доступа к нему из операционной системы можно увидеть следующие сообщения «Вставьте диск» или «Нет доступа к диску», «Диск не отформатирован». Но при попытке отфарматировать выдается сообщение типа «Диск защищен от записи»

Так как же боротся с этим?! Весьма просто…

  1. Вставляем usb flash накопитель в компьютер и определяем какое имя ему присваивается При подключении usb flash накопителя к компьютеру, Linux присваивает ему имя типа sdX (первому устройству присваивается sda, второму sdb и так далее. Но чтобы узнать какое имя он ему присвоил наверняка, используем 1 из способов:

    • Набираем команду:

      dmesg
      

      Выведет следующее:

      [ 1676.752097] usb 1-1: new high speed USB device using ehci_hcd and address 2
      [ 1676.885083] usb 1-1: configuration #1 chosen from 1 choice
      [ 1676.886065] scsi6 : SCSI emulation for USB Mass Storage devices
      [ 1676.886393] usb-storage: device found at 2
      [ 1676.886399] usb-storage: waiting for device to settle before scanning
      [ 1681.885333] usb-storage: device scan complete
      [ 1681.886555] scsi 6:0:0:0: Direct-Access     JetFlash TS4GJF160        0.00 PQ: 0 ANSI: 2
      [ 1681.887796] sd 6:0:0:0: Attached scsi generic sg3 type 0
      [ 1681.892418] sd 6:0:0:0: [sdc] 8028160 512-byte logical blocks: (4.11 GB/3.82 GiB)
      [ 1681.893352] sd 6:0:0:0: [sdc] Write Protect is off
      [ 1681.893361] sd 6:0:0:0: [sdc] Mode Sense: 00 00 00 00
      [ 1681.893368] sd 6:0:0:0: [sdc] Assuming drive cache: write through
      [ 1681.895713] sd 6:0:0:0: [sdc] Assuming drive cache: write through
      [ 1681.895725]  sdc: sdc1
      [ 1681.972724] sd 6:0:0:0: [sdc] Assuming drive cache: write through
      [ 1681.972738] sd 6:0:0:0: [sdc] Attached SCSI removable disk
      

      Из этого всего нам нужна только 1 строка:

      [ 1681.895725] sdc: sdc1
      

      которая и говорит нам что присвоено имя устройству sdc1

    • Набираем команду:

      sudo tail /var/log/messages
      

      Выведет следующее:

      Nov 13 22:25:33 espera kernel: [ 1676.752097] usb 1-1: new high speed USB device using ehci_hcd and address 2
      Nov 13 22:25:33 espera kernel: [ 1676.885083] usb 1-1: configuration #1 chosen from 1 choice
      Nov 13 22:25:33 espera kernel: [ 1676.886065] scsi6 : SCSI emulation for USB Mass Storage devices
      Nov 13 22:25:38 espera kernel: [ 1681.886555] scsi 6:0:0:0: Direct-Access     JetFlash TS4GJF160        0.00 PQ: 0 ANSI: 2
      Nov 13 22:25:38 espera kernel: [ 1681.887796] sd 6:0:0:0: Attached scsi generic sg3 type 0
      Nov 13 22:25:38 espera kernel: [ 1681.892418] sd 6:0:0:0: [sdc] 8028160 512-byte logical blocks: (4.11 GB/3.82 GiB)
      Nov 13 22:25:38 espera kernel: [ 1681.893352] sd 6:0:0:0: [sdc] Write Protect is off
      Nov 13 22:25:38 espera kernel: [ 1681.895725]  sdc: sdc1
      Nov 13 22:25:38 espera kernel: [ 1681.972738] sd 6:0:0:0: [sdc] Attached SCSI removable disk
      

      Аналогично первой команде ищем среди последних строк:

      Nov 13 22:25:38 espera kernel: [ 1681.895725] sdc: sdc1
      
    • Набираем команду:

      mount | column -t
      

      Имхо самый оптимальный вариант, выведет весь список смонтированных устройств и в самом конце видим следующее:

      /dev/sdc1 on /media/A47B-0D0E type vfat (rw, nosuid, nodev, uhelper=udisks, uid=1000, gid=1000, shortname=mixed, dmask=0077, utf8=1, flush)
      

      Думаю тут все понятно, /dev/sdc1 то что нам и нужно

  2. Забиваем usb flash накопитель нулевыми байтами, набирая:

    sudo dd if=/dev/zero of=/dev/sdc1
    

    После чего нам выдаст следующее:

    dd: запись в «/dev/sdc1»: На устройстве кончилось место
    8028098+0 записей считано
    8028097+0 записей написано
    скопировано 4110385664 байта (4,1 GB), 97,692 c, 42,1 MB/c
    

    На ошибку можете не обращать внимание, мы же не указали необходимый размер

  3. Форматируем usb flash накопитель, командой:

    sudo fdisk /dev/sdc1
    

    Выведет следующее:

    Устройство не содержит ни верной таблицы разделов DOS, ни метки диска Sun, SGI или OSF
    Building a new DOS disklabel with disk identifier 0x1854766c.
    Changes will remain in memory only, until you decide to write them.
    After that, of course, the previous content won't be recoverable.
    ...
    Предупреждение: неверный флаг 0x0000 таблицы разделов 4 будет исправлен записью
    ...
    WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
             switch off the mode (command 'c') and change display units to
             sectors (command 'u').
    ...
    Команда (m для справки):
    

    Создаем новый раздел, командой n:

    Команда (m для справки): n
    Действие команды
       e   расширенный
       p   основной раздел (1-4)
    p
    Номер раздела (1-4): 1
    Первый цилиндр (1-1019, по умолчанию 1): 1
    Last цилиндр, +цилиндры or +size{K,M,G} (1-1019, по умолчанию 1019): 1019
    

    Просматриваем что получилось, командой p:

    Команда (m для справки): p
    ...
    Диск /dev/sdc1: 4110 МБ, 4110385664 байт
    127 heads, 62 sectors/track, 1019 cylinders
    Units = цилиндры of 7874 * 512 = 4031488 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x1854766c
    ...
    Устр-во Загр     Начало       Конец       Блоки   Id  Система
    /dev/sdc1p1               1        1019     4011772   83  Linux
    

    Так как Linux раздел нам никчему сменим его, командой t:

    Команда (m для справки): t
    Выбранный раздел 1
    Шестнадцатеричный код (введите L для получения списка кодов): l
    ...
     0  Пустой    24  NEC DOS         81  Minix / ста  bf  Solaris
     1  FAT12           39  Plan 9          82  Linux своп  c1  DRDOS/sec (FAT-
     2  XENIX root      3c  PartitionMagic  83  Linux           c4  DRDOS/sec (FAT-
     3  XENIX usr       40  Venix 80286     84  OS/2 скрыт c6  DRDOS/sec (FAT-
     4  FAT16 <32M      41  PPC PReP Boot   85  Linux расш  c7  Syrinx
     5  Расшире  42  SFS             86  NTFS набор da  Данные н
     6  FAT16           4d  QNX4.x          87  NTFS набор db  CP/M / CTOS / .
     7  HPFS/NTFS       4e  QNX4.x 2-я ч  88  Linux plaintext de  Dell Utility
     8  AIX             4f  QNX4.x 3-я ч  8e  Linux LVM       df  BootIt
     9  AIX загру  50  OnTrack DM      93  Amoeba          e1  DOS access
     a  OS/2 Boot-ме  51  OnTrack DM6 Aux 94  Amoeba BBT      e3  DOS R/O
     b  W95 FAT32       52  CP/M            9f  BSD/OS          e4  SpeedStor
     c  W95 FAT32 (LBA) 53  OnTrack DM6 Aux a0  IBM Thinkpad hi eb  BeOS фс
     e  W95 FAT16 (LBA) 54  OnTrackDM6      a5  FreeBSD         ee  GPT
     f  W95 расши  55  EZ-Drive        a6  OpenBSD         ef  EFI (FAT-12/16/
    10  OPUS            56  Golden Bow      a7  NeXTSTEP        f0  Linux/PA-RISC
    11  Скрытый  5c  Priam Edisk     a8  Darwin UFS      f1  SpeedStor
    12  Compaq диаг 61  SpeedStor       a9  NetBSD          f4  SpeedStor
    14  Скрытый  63  GNU HURD или ab  Darwin загр f2  DOS втори
    16  Скрытый  64  Novell Netware  af  HFS / HFS+      fb  VMware VMFS
    17  Скрытый  65  Novell Netware  b7  BSDI фс       fc  VMware VMKCORE
    18  AST SmartSleep  70  DiskSecure Mult b8  BSDI своп   fd  Автоопр
    1b  Скрытый  75  PC/IX           bb  Boot Wizard с  fe  LANstep
    1c  Скрытый  80  Old Minix       be  Solaris заг  ff  BBT
    1e  Скрытый
    Шестнадцатеричный код (введите L для получения списка кодов): 6
    Системный тип раздела 1 изменен на 6 (FAT16)
    

    Смотрим результат, командой p:

    Команда (m для справки): p
    ...
    Диск /dev/sdc1: 4110 МБ, 4110385664 байт
    127 heads, 62 sectors/track, 1019 cylinders
    Units = цилиндры of 7874 * 512 = 4031488 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x1854766c
    ...
    Устр-во Загр     Начало       Конец       Блоки   Id  Система
    /dev/sdc1p1               1        1019     4011772    6  FAT16
    

    Ну и записываем таблицу разделов на usb flash накопитель, командой w:

    Команда (m для справки): w
    Таблица разделов была изменена!
    ...
    Вызывается ioctl() для перечитывания таблицы разделов.
    ...
    WARNING: Re-reading the partition table failed with error 22: Недопустимый аргумент.
    The kernel still uses the old table. The new table will be used at
    the next reboot or after you run partprobe(8) or kpartx(8)
    ...
    ПРЕДУПРЕЖДЕНИЕ: Если вы создали или изменили
    какие-либо разделы DOS 6.x, пожалуйста, прочтите
    страницу руководства fdisk для получения
    дополнительной информации.
    
  4. Форматируем usb flash накопитель, командой:

    sudo mkdosfs /dev/sdc1
    

    После форматирования в раздел FAT16, выведет следующее:

    mkdosfs 3.0.7 (24 Dec 2009)
    

    Команда для форматирования в FAT32:

    sudo mkdosfs -F 32 /dev/sdc1
    
  5. После выполнения этих пунктов, в WinXP usb flash накопитель выдал «Диск не отформатирован» и только после того как я отформатировал стандартными средствами Win все заработало

Вот вообщем-то и все… Удачи в восстановлении!)

Для дополнительной информации об устройстве, введите:

sudo hdparm /dev/sdb

Выведет:

/dev/sdb:
 HDIO_DRIVE_CMD(identify) failed: Invalid exchange
 readonly      =  0 (off)
 readahead     = 256 (on)
 geometry      = 1024/0/62, sectors = 0, start = 0
comments powered by Disqus