Как известно, flash-накопитель не бывает идеальным. От частой перезаписи ячейки изнашиваются и перестают
достоверно записываться. А некоторые ячейки могут быть дефектными сразу после изготовления кристалла. На
заводе производится тщательное тестирование всех ячеек микросхемы, и выявляются дефектные ячейки.
Заметьте, что тестирование в заводских условиях — это не просто запись-чтение секторов. На заводе условия
тестирование очень жесткие — например, процесс происходит в термокамере при повышенной температуре. В
домашних условиях адекватно процесс не воспроизвести, и те ячейки, которые признали дефектными на заводе,
могут совершенно нормально писаться в готовом устройстве — но вызвать проблемы в будущем. Поэтому
очень важно не потерять заводской список дефектных ячеек.
Поскольку минимальной единицей стирания является блок, то, при наличии всего одной дефектной ячейки в
пределах блока, весь блок отмечается как дефектный блок (badblock в оригинальной терминологии). Помечая
блок как дефектный, в него на заводе записывают специальный маркер дефектного блока — байт 00 в самой
первой позиции OOB каждой страницы блока. В хороших блоках в этой позиции расположен FF, а все значения,
отличные от FF, считаются признаком дефектного блока. Но, поскольку квалкоммовцы используют свой формат
хранения данных на флешке, то заводской маркер дефектного блока в устройствах, построенных на данной
платформе, не используется. Вместо этого в качестве маркера используется байт данных в середине каждого
сектора (обычно по смещению +1D1 от начала сектора). Если он не равен FF, то весь блок, содержащий данный
сектор, объявляется дефектным. Данный маркер аппаратно обрабатывается контроллером — при чтении сектора
он не копируется в буфер данных, а переносится в специальный регистр NAND_BUFFER_STATUS, откуда
впоследствии может быть взят для анализа. Позиция маркера настраивается программно — это значение можно
увидеть среди параметров флешки, выводимых в процессе инициализации загрузчика:
Положение маркера дефектных блоков: user+1d1
user — означает, что маркер находится в области данных сектора (если же он расположен в области OOB,
как это делается на заводе, то вместо user будет указано spare). 1D1 — смещение от начала сектора до
маркера.
В процессе чтения данных, если игнорировать признак дефектного блока, то такой блок прочитается как
обычные данные, но будет состоять практически из одних нулей. Если затем полученный дамп записать в
другое устройство — то блок запишется туда уже как хороший (не дефектный) блок данных, состоящий из
нулей. Это вызовет нарушение формата записываемого раздела, и приведет к неработоспособности устройства.
Кроме того, если не обращать внимание на признаки дефектных блоков целевого устройства — то заводские
маркеры будут стерты, и заводской дефектный блок потеряется навсегда — вместо него получится хороший
блок, содержащий данные. Однако, поскольку блок потенциально дефектный, то данные в процессе хранения
запросто могут исказиться и также нарушить работу устройства.
Из всего вышесказанного можно сделать следующий вывод. Метод восстановления прошивки устройства-
пациента путем заливки полной посекторной копии флешки другого аналогичного устройства-донора (в народе
называемого фуллдампом), так любимый некоторыми ремонтниками — это порочный и достаточно опасный
метод. Можно получить как полностью неработоспособное устройство, так и работающее, но потенциально в
любой момент готовое дать непредсказуемый сбой. Правильный способ — это заливка отдельных разделов, с
пропуском заводских дефектных блоков как пациента, так и донора. И вот теперь комплекс qtools научился
наконец корректно работать с дефектными блоками.
$ ./badblock d
Построение списка дефектных блоков в интервале 00000000 00001000
Проверка блока 00000312 badblock (BSPFOTA+5f)
Проверка блока 00000384 badblock (APPSBL+4)
Проверка блока 0000052a badblock (SCRUB+151)
Проверка блока 0000080f badblock (USERDATA+ac)
Проверка блока 00000a2e badblock (RECOVERY+52)
Проверка блока 00000b0e badblock (ZTEDATA+d4)
Проверка блока 00000e6a badblock (RECOVERYFS+19f)
Проверка блока 00000f36 badblock (RECOVERYFS+26b)
Проверка блока 00000fab badblock (RECOVERYFS+2e0)
* Всего дефектных блоков: 9
В списке приводится абсолютный номер блока, а также номер относительно начала раздела, в котором
расположен блок (если доступна карта разделов). Как обычно, с помощью ключей -b и -l можно задать интервал
проверяемых блоков. Копия списка сохранияется в файл badblocks.lst. Я настоятельно рекомендую перед
началом экспериментов с новым устройством составить для него этот список и сохранить его в надежном месте.
Это позволит восстановить маркеры заводских блоков в случае их случайного стирания.
Может так случиться, что загрузчик в процессе инициализации флешки некорректно определяет положение
маркера дефектного блока. В этом случае можно принудительно установить позицию маркера на нужный байт
поля данных сектора с помощью ключа -s, например:
qbadblock s 1d1
Эта команда установит позицию маркера на байт 1D1. Установка будет действовать до перезагрузки устройства,
или до установки новой позиции маркера.
При чтении с помощью qrflash, как разделов, так и произвольного набора блоков, режим обработки дефектных
блоков задается с помощью ключа -u. Доступны следующие режимы:
-us — пропуск дефектных блоков. Если при чтении блока он окажется дефектным, то в выходной файл ничего
не запишется. Это режим по умолчанию для чтения разделов — он позволяет получить чистый дамп раздела,
пригодный для записи на любое другое устройство.
-uf — заполнение дефектных блоков. В этом режиме в выходной файл на место дефектного блока записывается
блок, полностью заполненный байтом 0xbb. Поскольку такие блоки данных в реальном устройстве скорее всего
не встретятся никогда, то по данному признаку можно гарантированно судить, что на флешке-доноре в этом
месте был дефектный блок. Данный режим используется по умолчанию при неформатном чтении (по номерам
блоков).
-ui — игнорирование дефектов. Программа будет вести себя как раньше — читать дефектные блоки как
обычные блоки данных. Этот режим практической пользы, видимо, не имеет, хотя некоторые специалисты
утверждают, что так можно спасти частично убитые данные. Для них режим и оставлен.
-ux — отключить аппаратный контроль дефектных блоков. Маркер дефектных блоков будет читаться как
обычный байт данных и попадать в выходной файл. Данный режим — единственный, позволяющий сделать
достоверный полный образ флешки донора (тот самый фуллдамп), пригодный для записи в другие устройства.
Однако, по вышеизложенным причинам пользоваться фуллдампами крайне не рекомендуется. Исключение —
запись фуллдампа на то же самое устройство, с которого он был снят (для полного восстановления прошивки,
например) — при этом маркеры бедблоков будут записаны на свои родные места, и заводской список дефектов
не нарушится.
-us - игнорировать признаки дефектных блоков, отмеченные во входном файле. Когда qrflash при чтении
встречает дефектный блок, то в выходной дамп (если данный режим установлен) записывает специальный блок,
состоящих из байта 0xbb. Если такой блок встречается во входном файле, то qwdrect по умолчанию просто
пропускает его и продолжает чтение входного файла. Однако при записи полного дампа (фуллдампа) блоки
пропускать нельзя, поскольку пропуск входных блоков автоматически приведет к нарушению границ разделов.
Пропуск блоков можно использовать только для записи образов конкретных разделов, вырезанных из
фуллдампа. Поэтому, используя ключ -us, можно записывать данные без сдвигов и нарушения абсолютных
адресов блоков. При этом, на флешку будет записан мусор (блок из всех байтов 0xbb) на месте дефектных
блоков исходного дампа. Это, скорее всего, приведет к частичной или полной неработоспособности устройства.
-uc - симулировать дефектные блоки входного файла. В этом режиме, если во входном файле встретился блок,
помеченый как дефектный (байтами 0xbb), то на целевой флешке создается фиктивный дефектный блок. То есть
вполне исправный и живой блок будет помечен как дефектный. Это позволяет (при одновременном указании
ключа -ub) адекватно записать чужой фуллдамп в свою флешку. При этом все дефектные блоки исходной
флешки-донора будут объявлены дефектными и на целевой флешке. Естественно, этот режим достаточно
подлый - созданые псевдодефектный блоки практически ничем не будут отличаться от заводских. И
использовать его следует только в САМЫХ КРАЙНИХ случаях, когда восстановить работу устройства надо
быстро и любой ценой, а в налиии имеется только чужой фуллдамп.
-um - проверять соответствие дефектных блоков файла и флешки. Это достаточно полезный режим,
предназначенный для заливки фуллдампа в ту же самую флешку, с которой он считывался. Поскольку заводские
дефектные блоки дампа и флешки совпадают полностью, то такой способ заливки дампа позволяет быстро и без
потерь восстановить работу устройства. В этом режиме qwdirect, встречая помеченный в файле дефектный
блок, проверяет, является ли дефектным соответствующий ему блок на флешке. Если да, то блок просто
пропускается , и запись продолжается со следующего блока. Заводской маркер дефекта не затрагивается. Если
соответствующий блок флешки — не дефектный, то процесс записи аварийно завершается, поскольку в этом
случае дамп не соответствует флешке (является чужим) и дальнейшая запись становится бессмысленной.
-ux - отключить аппаратный контроль дефектных блоков. В этом режиме блок входного дампа записывается
на флешку полностью, включая маркер дефектного блока. Исходный дамп для такой записи должен сниматься с
помощью qrflash также с ключом -ux. Данный режим также позволяет адекватно записать дамп в ту флешку, с
которой он был считан. Но использовать его крайне не рекомендуется. Во-первых, производить любые действия
(и особенно стирание) с заводскими дефектными блоками достаточно опасно — раз блок дефектный, то не факт,
что при следующей записи адекватно пропишется маркер. Во-вторых, в этом режиме невозможно призвести
контроль соответствия дефектных блоков дампа и флешки, в результате чего можно случайно залить в
устройство чужой дамп и затереть все заводские маркеры. Лучше в качестве фуллдампа использовать дамп,
снятый с помощью qrflash -uf, и записывать его с ключом -um.
-ub - не проверять дефектность блоков флешки перед записью. Это ОЧЕНЬ ОПАСНЫЙ режим. В нормальном
режиме работы qwdirect, перед тем как записать очередной блок, проверяет, не является ли блок дефектным. С
помощью данного ключа можно запретить эту проверку — целевой блок будет стерт и записан как обычный
блок, даже если является дефектным. Это гарантированно приведет к уничтожению заводских маркеров. По
сути, данный режим к применению настоятельно НЕ рекомендован. Он может использоваться только при
отладке, для перезаписи созданных вручную псевдодефектных блоков (например, с помощью qbadblock -m).
Именно этот режим использовался программой qwdirect до того, как в нее были встроены средства контроля
дефектных блоков. Запись фулдампов с использованием этого режима — грубое и ничем не оправданное
вмешательство, приводящее к массе потенциальных проблем из-за использования заводских дефектных блоков
для хранения данных.
2. Донор и пациент — разные устройства, и мы пытаемся склонировать прошивку. Если на флешках донора и
пациента нет ни одного дефектного блока — никаких проблем, фуллдамп считается, зальется и пациет оживет.
Если же на любой из флешек есть хотя бы один дефектный блок — то использовать фуллдамп НЕЛЬЗЯ.
Но если нельзя, но очень хочется… Можно считать прошивку с помощью qrflash -ux, и записать ее также с
помощью qwdirect -ux. При этом дефектные маркеры флешки-донора запишутся на флешку пациента как есть, и
вполне живые блоки пациента будут объявлены дефектными. Хотя, при этом все запишется правильно и
пациент заработает. Хуже, если дефектные блоки имеются на флешке пациента. При таком способе записи
заводские маркеры будут стерты, и в дефектные блоки будут записаны реальные данные. Результат такой записи
непредсказуем — от полной неработоспособности устройства до феерически неуловимых сбоев в работе
устройства в далеком будущем. Так что такой способ клонирования прошивки следует признать крайне
неудачным. Гораздо более правильным будет способ копирования прошивки по разделам.
Копирование по разделам — это правильный способ заливки прошивки. Именно его используют фирменные
программы обновления прошивки и технологические утилиты типа QPST. При этом все заводские дефектные
блоки аккуратно обходятся без всяких сдвигов адресации. Рассмотрим оба этапа — чтение прошивки с
устройства-донора и запись ее в устройство-пациент.
Чтение делается с помощью утилиты qrflash в режиме работы с разделами. Вначале читаем все разделы с
устройства (естественно, с ООВ) , пропуская дефектные блоки:
qrflash s@ x
Ключ -us, включающий режим пропуска дефектных блоков, в режиме работы с разделами включается по
умолчанию — можно его не указывать. Затем сохраняем карту разделов устройства в отдельный файл:
qrflash s@ m >part.lst
Теперь все прочитанные файл *.oob и файл part.lst будут составлять образ прошивки, пригодный для заливки в
любое аналогичное устройство. Можно их собрать в архив и положить на хранение.
Запись делается с помощью qwdirect, но полной автоматизации, как при чтении, здесь не будет. Для каждого
раздела придется дать отдельную команду записи:
qwdirect fi b<start> <file>
Номер стартового блока можно посмотреть в карте разделов, предварительно сохраненной при чтении. А номер
раздела в карте — это первые 2 цифры имени файла, содержащего дамп раздела. Таким образом можно записать
все разделы, или только некоторые, нуждающиеся в восстановлении. Все дефектные блоки, найденные на
флешке пациента, будут пропущены при записи. В результате заводские дефекты не потеряются, и адресация
блоков не нарушится, поскольку запись начинается не с начала флешки, а с границы раздела.