Ссылка это хорошо, но мне приятнее и спокойнее если оно у нас в сообществе всё есть)))
Общение с USB-устройством
Два дня было свободных и решил написать две ознакомительные статейки. Но, чувствую, что это в первый и последний раз …… тяжеловато, особенно в этой статье, тема тяжелая, написать можно много… но уже стал путаться, ну и гложет мысль …. а кому это нужно — успокоился тем, что пойдет на пользу ребятишкам, которые частенько забегают за ответами на свои вопросы…
USB-устройства, по большей части флешки, отказывали у многих и прежде чем заниматься их восстановлением хотелось бы извлечь из этой флешки побольше информации — чем больше информации, тем лучше… А вот как поговрить с этим устройством, особо и не расписано… информация, конечно, имеется, но в основном вся проверка сводится к тестированию несколькими утилитами… А вот как общаются эти самые утилиты с устройством …. особо и неизвестно …… а общаются они посредством SCSI команд (запрос/ответ). И напрашивается вывод — а может лучше самим пообщаться с устройством без всяких посредников, напрямую?
Вот с этими способами общения и хочу ознакомить форумчан…
В основном для тестирования флешек в Linux применяют утилиту hdparm и реже sdparm.
В качестве подопытного будет 16G флешка (при возможности буду приводить похожие выводы всеми способами — обоими утилитами и SCSI командами)
# sdparm -i /dev/sdb
/dev/sdb: JetFlash Transcend 16GB 1100
malformed VPD response, VPD pages probably not supported
USB-устройство, в частности флешка, представляет собой тот же мини/микро компьютер — описывать ее устройство не собираюсь — все давно уже хорошо описано и в инете можно найти кучу схем и описаний (интересующимся даю ссылку на старую статью… там хоть и много лишнего, но хорошая схемка… что то другой похожей я у себя не нашел, а может плохо искал....)
Для начала — набор команд SCSI разрабатывался, как протокол для устройств, использующих параллельный интерфейс для малых компьютерных систем (Small Computer Systems Interface — SCSI). Команды является инструментом, позволяющим получать информацию об устройстве, менять режим его работы и читать/записывать блоки данных на носитель. Набор команд SCSI используют многие накопители данных, подключаемые через другие аппаратные интерфейсы, в том числе через USB.
Команды SCSI охватывают широкий диапазон типов устройств и задач, все заспецифицировано, а для нас важна спецификация SCSI Block Commands (SBC) — блоковые команды SCSI, которые описывает команды, используемые жёсткими дисками, флэш-дисками и другими блоковыми устройствами прямого доступа. Текущая версия — SBC-3. Кого интересует данная спецификация, формат команд, их описание и.т.п. могут обратится к первоисточнику — можно найти и скачать по названию SCSI Block Commands — 3 (SBC-3)
Ну вот, с вводной можно закончить и приступить к основной части.
SCSI команды условно можно разделить на 3 группы
— специфицированные, обязательные для всех устройств;
— специфицированные, но работающие не на всех устройствах;
— неспецифицированные, применяются разработчиками, изготовителями и, как бы сказать… наладчиками… то есть эти команды не описаны в спецификации и известны узкому кругу лиц.
Специфицированных команд около 60. Но обычным пользователям достаточно 5 базовых команд — минимум команд, которые используются устройством и хостом для начала взаимодействия/общения, чтобы начать полноценную работу. Вот эти команды я и постараюсь описать.
1. INQUIRY (12 00 00 00 60 00) — запрашивает структуру с информацией об устройстве. Устройство должно возвращать ответ даже в случае неготовности носителя и невозможности отвечать на все остальные команды. Все блоковые устройства должны поддерживать команду INQUIRY. В скобках приведен формат команды.
Ответ на команду имеет длину как минимум 36 байт и указывает периферийный тип устройства («PDT»), версию набора базовых команд SPC, идентификаторы производителя и изделия, номер модификации изделия, а также данные о возможностях устройства и поддерживаемых протоколах.
Забыл написать, что для дальнейшего тестирования должен быть установлен пакет sg3_utils и загружен модуль sg… и будем использовать утилиту sg_raw
Вставляем флешку и смотрим как она определилась
# sg_map -i
/dev/sg2 /dev/sdb JetFlash Transcend 16GB 1100
Приступаем к общению ….
# sg_raw /dev/sg2 12 00 00 00 60 00
SCSI Status: Good
или более информативный вывод
# sg_raw -vv /dev/sg2 12 00 00 00 60 00
open /dev/sg2 with flags=0x802
cdb to send: 12 00 00 00 60 00
SCSI Status: Good
No errors
Попросим дать ответ в другой форме и вывести нам всю информацию об устройстве (запросим только первые 64 байта)
# sg_raw -r 64 /dev/sg2 12 00 00 00 60 00
SCSI Status: Good
Received 64 bytes of data:
00 00 80 00 01 1f 73 6d 69 4a 65 74 46 6c 61 73 68 .....smiJetFlash
10 54 72 61 6e 73 63 65 6e 64 20 31 36 47 42 20 20 Transcend 16GB
20 31 31 30 30 00 80 02 00 00 00 00 00 00 00 00 00 1100…
30 00 00 00 00 00 00 28 00 03 01 82 06 00 15 00 00 ......(…
формат ответа описывать не буду — кому интересно, обращайтесь к спецификации (например, 8..15 байты — обозначение производителя, 16..31 байты — обозначение изделия, 32..35 байты — версия изделия и.т.д....). .....PS… чтобы увеличить количество выводимых байт, нужно вместо 64 прописать, например, 256… иногда и там имеется полезное)
……
Аналог специальных утилит пакета sg3_utils
# sg_inq /dev/sg2 или # sginfo /dev/sg2
Аналог sdparm (но менее информативный) с опцией -i (--inquiry) команда
# sdparm -i /dev/sdb
……
2. READ CAPACITY (25 00 00 00 00 00) — возвращает структуру, содержащую логический адрес (LBA) последнего блока на носителе и размер блока в байтах. Стоит уточнить, что команда запрашивает логический адрес (LBA) последнего блока, а не количество блоков на носителе. Логический адрес первого блока равен нулю, таким образом, логический адрес последнего блока на единицу меньше количества блоков. PS… команда используется, чтобы выяснить какой объём данных может хранить устройство
# sg_raw -r 8 /dev/sg2 25 00 00 00 00 00
SCSI Status: Good
00 01 e3 bf ff 00 00 02 00
( 01e3bfff=31703039 — (первые 4 байта) количество блоков, (последние 4 байта) 00000200=512 — размер блока)
Проверка
$ sudo fdisk -l /dev/sdb
Диск /dev/sdb: 15,1 GiB, 16231956480 байт, 31703040 секторов
Единицы: секторов по 1 * 512 = 512 байт
Размер сектора (логический/физический): 512 байт / 512 байт
……
Аналог специальной утилиты пакета sg3_utils — # sg_readcap /dev/sg2
3. SEND DIAGNOSTIC (1D 00 00 00 00 00) — команда предписывает устройству провести самотестирование и/или проверку логического накопителя. Для блоковых устройств (SBC) обязательна поддержка самотестирования, способ реализации которого оставляется на усмотрение разработчика.
# sg_raw /dev/sg2 1D 00 00 00 00 00
SCSI Status: Good
или
# sg_raw -vv /dev/sg2 1D 00 00 00 00 00
open /dev/sg2 with flags=0x802
cdb to send: 1d 00 00 00 00 00
SCSI Status: Good
No errors
4. REQUEST SENSE (03 00 00 00 00 00) — (запрос о состоянии) столкнувшись с проблемами при исполнении команды или получив неизвестную команду, устройство заполняет структуру, содержащую подробную информацию о состоянии и устанавливает значение поля «bCSWStatus» (CSW) равным «0x01» (ошибка исполнения). Структура с информацией о состоянии называется пояснительными данными (SENSE DATA) и передаётся в ответ на команду REQUEST SENSE (все поля формата не привожу, а только наиболее интересующие пользователей)
Запрашиваю только первые 16 байт (можно и без опции -vv, пишу для того, чтобы увидеть No errors, хотя это и не к чему… и так все видно)
# sg_raw -vv -r 16 /dev/sg2 03 00 00 00 00 00
open /dev/sg2 with flags=0x802
cdb to send: 03 00 00 00 00 00
SCSI Status: Good
Received 16 bytes of data:
00 70 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 00 p…
No errors
……
PS… Забыл отметить, что в спецификации указано, что запрос должен быть равным 252 байтам для того, чтобы устройство могло возвратить всю значимую информацию, включая внутренние данные производителя.
…
Аналог специальной утилиты пакета sg3_utils (а вот с этими двумя разными выводами руки так разобраться и не дошли, наверное, потому, что утилиты этого пакета практически не использую… нравится общаться на прямую....)
# sg_requests /dev/sg2
Decode parameter data as sense data:
Fixed format, current; Sense key: No Sense
Additional sense: No additional sense information
# sg_requests -vv /dev/sg2
open /dev/sg2 with flags=0x800
Request Sense cmd: 03 00 00 00 fc 00
Decode parameter data as sense data:
Fixed format, current; Sense key: No Sense
Additional sense: No additional sense information
Parameter data in hex
00 70 00 00 00 00 00 00 0a 00 00 00 00 00 00 00 00
10 00 00
……
Формат вывода ответа
0 байт — RESPONSE CODE — для сведений о текущих ошибках устанавливается в «0x70». Для сведений об отложенных ошибках (для команд использующих кэширование) устанавливается в «0x71»
2 байт — SENSE KEY — содержит данные, классифицирующие ошибку
7 байт — ADDITIONAL SENSE LENGTH — длина дополнительных пояснительных данных, следующих за данным полем, в байтах, 244 байта максимум
Некоторые значения поля SENSE KEY
00 — NO SENSE (нет ответа)
01 — RECOVERED ERROR (вскрытая ошибка)
02 — NOT READY (не готов)
03 — MEDIUM ERROR (ошибка носителя/средняя ошибка)
04 — HARDWARE ERROR (ошибка аппаратного обеспечения)
05 — ILLEGAL REQUEST (некорректный запрос)
06 — UNIT ATTENTION (устройство требует внимания/ предупреждение)
07 — DATA PROTECT (защищенная информация)
…… ит.п. ит.д… и, если мне не изменяет память, есть еще уточняющие коды, посмотреть можно в спецификации…
Примечание: уточнение кода SENSE KEY в части значения 05 — в случае получения неизвестной команды устройство не должно «зависать» или аварийно завершать работу. Правильный ответ на неподдерживаемую команду выглядит так:
— возвратить значение «0x01» (ошибка выполнения) в поле «bCSWStatus» (CSW);
— установить в блоке пояснительных данных («SENSE DATA») параметр «SENSE KEY» в «0x05» («Недопустимый запрос» — «ILLEGAL REQUEST»), а параметр «ADDITIONAL SENSE CODE» в «0x20» («Неверный код операции» — «INVALID COMMAND OPERATION CODE»).
Имеются и другие команды, но, если честно, что то уже устал и стал путаться (за найденные ошибки особо не пинать) — думаю для начального ознакомления этого достаточно.
PS… по ответам, напрямую посланным запросам (на низком уровне), можно судить о состоянии устройства...
+1
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.
3 комментария