Phison - нежадный контроллер, в смысле информации о прошивке. Он с удовольствием поделиться ею, если его хорошо попросить.
Попросить нам помогут следующие команды SCSI:
• CDB = 0x06050000 00000000 00000000 00000000. Эта команда знакома нам по определению модели контроллера. Она возвратит нам Info_Page_NULL (или просто Version_Page) - одну из трех страниц, которые сохраняет утилита GetInfo в своем закриптованном файле;
• CDB = 0x0605494E 464F0000 00000000 00000000. Эта команда возвратит нам Info_Page_INFO (или просто Info_Page) - вторую из трех страниц, которые сохраняет утилита GetInfo в своем закриптованном файле. Кстати, байты 0x49, 0x4E, 0x46, 0x4F, содержащиеся в CDB а ASCII представлении выглядят как раз как «INFO».
А путеводной звездой в наших изысканиях пусть будет полюбившаяся утилита от Phison - GetInfo
Итак, Info_Page_NULL:
И Info_Page_INFO:
Первое, с чем разберемся - это FW, а точнее, версия и дата прошивки
Для этого нам понадобится Info_Page_NULL
По смещению 0x94 находятся 3 байта версии, а по смещению 0x97 - 3 байта даты в формате YYMMDD
Следующая группа полей - Production Info
MP version (Mass Production version) все немного сложнее, т.к. расположение данных о версии зависит как раз … от MP version. Точную логику для всех версий описать словами довольно муторно, потому опишу, не совсем точно, но просто.
Итак, если версия MP = 3, то числовые значения версии (3 байта) будут по смещению 0xDC INFO_page. Для младших версий стоит попытать счастья по смещению 0xСC или 0x8D. Числовые значения версии идут справа-налево.
Определить идентификатор ПО-прошивальщика поможет байт по смещению 0xBD все той же INFO_page для MP=3 или по смещению 0x8C для младших версий.
ID расшифровываем по следующей табличке:
В нашем случае получается как раз MPALL v3.62.0A. Как в апетке!
Назначение поля с китайскими иероглифами для меня загадка. Хотя Гугл-переводчик и считает, что оно как-то связано с OEM-кодом (точнее, по версии Гугла это «храм OEM-кода»), но особой уверенности у меня в этом нет. В любом случае, значение этого поля берется из INFO_Page в байте по смещению 0xAF.
Чтобы найти размер серийника, берем байт по смещению 0x60 в INFO_page, уменьшаем его значение на 2 и делим на 2. В нашем случае, значение байта равно 0x22 и после вычислений должны получить размер серийника, равный 0x10.
Сам серийник начинается по смещению 0x62. Вначале выбираем 12 значений по четным байтам ...
и добиваем до рассчитанного ранее размера серийника значениями по нечетным байтам
В итоге получаем искомое 070728899CAA6E26
С Production Date & Time интереснее. Дата и время берутся из серийника. На самом деле, алгоритм формирования серийника задается настройками, и не во всех алгоритмах участвуют дата и время. А если и участвуют, то не совсем так, как декодируется в GetInfo. Но что вижу, о том и пишу.
Смотрим, как формируются значения этих полей в GetInfo.
Из рассчитанного ранее размера серийника вычитаем магическое число 12 (16 - 12 = 4). Пропускаем полученные 4 байта серийника и забираем 6 байт. В нашем случае это последовательность 28899C.
Первый байт - "год", начиная от 2010. Т.е. 2010 + 2 = 2012г
Второй байт - "месяц". В нашем случае - 8.
Третий байт - "день", в нашем случае 8. Но дней бывает много, поэтому необходимо кроме третьего байта забирать кусочек пятого байта, а точнее 3-тий бит (начиная от 0). Пятый байт - 9, или 1001b. Третий бит пятого байта равен 1. Таким образом, "день" равен 0x18 или 24.
Четвертый байт - "часы", в нашем случае 9. Логика такая же, как и с "днями", но забираем второй бит (начиная с 0) того же пятого байта. Второй бит пятого байта равен 0. Таким образом, "часы" равны 0x09.
Шестой байт - "минуты", в нашем случае 0xC. Логика такая же, как и с "днями", но забираем два первых бита (начиная с 0) того же пятого байта. Первые два бита пятого байта дают 01b (0x1). Таким образом, "минуты" равны 0x1С или 28.
Продолжение Начало