Вы находитесь на странице: 1из 4

Обработка дефектных блоков

Как известно, flash-накопитель не бывает идеальным. От частой перезаписи ячейки изнашиваются и перестают
достоверно записываться. А некоторые ячейки могут быть дефектными сразу после изготовления кристалла. На
заводе производится тщательное тестирование всех ячеек микросхемы, и выявляются дефектные ячейки.
Заметьте, что тестирование в заводских условиях — это не просто запись-чтение секторов. На заводе условия
тестирование очень жесткие — например, процесс происходит в термокамере при повышенной температуре. В
домашних условиях адекватно процесс не воспроизвести, и те ячейки, которые признали дефектными на заводе,
могут совершенно нормально писаться в готовом устройстве — но вызвать проблемы в будущем. Поэтому
очень важно не потерять заводской список дефектных ячеек.
Поскольку минимальной единицей стирания является блок, то, при наличии всего одной дефектной ячейки в
пределах блока, весь блок отмечается как дефектный блок (badblock в оригинальной терминологии). Помечая
блок как дефектный, в него на заводе записывают специальный маркер дефектного блока — байт 00 в самой
первой позиции OOB каждой страницы блока. В хороших блоках в этой позиции расположен FF, а все значения,
отличные от FF, считаются признаком дефектного блока. Но, поскольку квалкоммовцы используют свой формат
хранения данных на флешке, то заводской маркер дефектного блока в устройствах, построенных на данной
платформе, не используется. Вместо этого в качестве маркера используется байт данных в середине каждого
сектора (обычно по смещению +1D1 от начала сектора). Если он не равен FF, то весь блок, содержащий данный
сектор, объявляется дефектным. Данный маркер аппаратно обрабатывается контроллером — при чтении сектора
он не копируется в буфер данных, а переносится в специальный регистр NAND_BUFFER_STATUS, откуда
впоследствии может быть взят для анализа. Позиция маркера настраивается программно — это значение можно
увидеть среди параметров флешки, выводимых в процессе инициализации загрузчика:

Положение маркера дефектных блоков: user+1d1

user — означает, что маркер находится в области данных сектора (если же он расположен в области OOB,
как это делается на заводе, то вместо user будет указано spare). 1D1 — смещение от начала сектора до
маркера.

В процессе чтения данных, если игнорировать признак дефектного блока, то такой блок прочитается как
обычные данные, но будет состоять практически из одних нулей. Если затем полученный дамп записать в
другое устройство — то блок запишется туда уже как хороший (не дефектный) блок данных, состоящий из
нулей. Это вызовет нарушение формата записываемого раздела, и приведет к неработоспособности устройства.
Кроме того, если не обращать внимание на признаки дефектных блоков целевого устройства — то заводские
маркеры будут стерты, и заводской дефектный блок потеряется навсегда — вместо него получится хороший
блок, содержащий данные. Однако, поскольку блок потенциально дефектный, то данные в процессе хранения
запросто могут исказиться и также нарушить работу устройства.
Из всего вышесказанного можно сделать следующий вывод. Метод восстановления прошивки устройства-
пациента путем заливки полной посекторной копии флешки другого аналогичного устройства-донора (в народе
называемого фуллдампом), так любимый некоторыми ремонтниками — это порочный и достаточно опасный
метод. Можно получить как полностью неработоспособное устройство, так и работающее, но потенциально в
любой момент готовое дать непредсказуемый сбой. Правильный способ — это заливка отдельных разделов, с
пропуском заводских дефектных блоков как пациента, так и донора. И вот теперь комплекс qtools научился
наконец корректно работать с дефектными блоками.

qbadblock — утилита для работы с дефектными блоками


Для поиска дефектных блоков, а также для управления маркерами отдельных блоков в составе комплекса
имеется специальная уитлита — qbadblocks. Далее рассмотрены ее возможности.

Построение списка заводских дефектных блоков


Программа qbadblock позволяет быстро просканировать флешку на наличие заводских дефектных блоков, и
составить их список. Для этого используется ключ -d:

$ ./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. Я настоятельно рекомендую перед
началом экспериментов с новым устройством составить для него этот список и сохранить его в надежном месте.
Это позволит восстановить маркеры заводских блоков в случае их случайного стирания.

Установка и снятие маркера


Утилита qbadblocks позволяет установить или снять маркер дефекта с любого блока флешки, кроме блока 0 (он
всегда должен быть исправным). Для этого используются ключи -m и -u:
qbadblock ­m <blk>   ­ отмечает блок blk как дефектный
qbadblock ­u <blk>   ­ снимает маркер дефекта с блока blk

Управление позицией маркера

Может так случиться, что загрузчик в процессе инициализации флешки некорректно определяет положение
маркера дефектного блока. В этом случае можно принудительно установить позицию маркера на нужный байт
поля данных сектора с помощью ключа -s, например:

qbadblock ­s 1d1

Эта команда установит позицию маркера на байт 1D1. Установка будет действовать до перезагрузки устройства,
или до установки новой позиции маркера.

qrflash - Обработка дефектных блоков при чтении

При чтении с помощью qrflash, как разделов, так и произвольного набора блоков, режим обработки дефектных
блоков задается с помощью ключа -u. Доступны следующие режимы:

-us — пропуск дефектных блоков. Если при чтении блока он окажется дефектным, то в выходной файл ничего
не запишется. Это режим по умолчанию для чтения разделов — он позволяет получить чистый дамп раздела,
пригодный для записи на любое другое устройство.

-uf — заполнение дефектных блоков. В этом режиме в выходной файл на место дефектного блока записывается
блок, полностью заполненный байтом 0xbb. Поскольку такие блоки данных в реальном устройстве скорее всего
не встретятся никогда, то по данному признаку можно гарантированно судить, что на флешке-доноре в этом
месте был дефектный блок. Данный режим используется по умолчанию при неформатном чтении (по номерам
блоков).

-ui — игнорирование дефектов. Программа будет вести себя как раньше — читать дефектные блоки как
обычные блоки данных. Этот режим практической пользы, видимо, не имеет, хотя некоторые специалисты
утверждают, что так можно спасти частично убитые данные. Для них режим и оставлен.

-ux — отключить аппаратный контроль дефектных блоков. Маркер дефектных блоков будет читаться как
обычный байт данных и попадать в выходной файл. Данный режим — единственный, позволяющий сделать
достоверный полный образ флешки донора (тот самый фуллдамп), пригодный для записи в другие устройства.
Однако, по вышеизложенным причинам пользоваться фуллдампами крайне не рекомендуется. Исключение —
запись фуллдампа на то же самое устройство, с которого он был снят (для полного восстановления прошивки,
например) — при этом маркеры бедблоков будут записаны на свои родные места, и заводской список дефектов
не нарушится.

qwdirect - Обработка дефектных блоков при записи


Утилита qwdirect также имеет полный набор средств для обработки дефектных блоков. Для управления ими
также используется ключ -u. Однако здесь этот ключ можно задать в командной строке несколько раз для
установки нужных режимов. Ключ имеет следующие значения:

-us - игнорировать признаки дефектных блоков, отмеченные во входном файле. Когда qrflash при чтении
встречает дефектный блок, то в выходной дамп (если данный режим установлен) записывает специальный блок,
состоящих из байта 0xbb. Если такой блок встречается во входном файле, то qwdrect по умолчанию просто
пропускает его и продолжает чтение входного файла. Однако при записи полного дампа (фуллдампа) блоки
пропускать нельзя, поскольку пропуск входных блоков автоматически приведет к нарушению границ разделов.
Пропуск блоков можно использовать только для записи образов конкретных разделов, вырезанных из
фуллдампа. Поэтому, используя ключ -us, можно записывать данные без сдвигов и нарушения абсолютных
адресов блоков. При этом, на флешку будет записан мусор (блок из всех байтов 0xbb) на месте дефектных
блоков исходного дампа. Это, скорее всего, приведет к частичной или полной неработоспособности устройства.

-uc - симулировать дефектные блоки входного файла. В этом режиме, если во входном файле встретился блок,
помеченый как дефектный (байтами 0xbb), то на целевой флешке создается фиктивный дефектный блок. То есть
вполне исправный и живой блок будет помечен как дефектный. Это позволяет (при одновременном указании
ключа -ub) адекватно записать чужой фуллдамп в свою флешку. При этом все дефектные блоки исходной
флешки-донора будут объявлены дефектными и на целевой флешке. Естественно, этот режим достаточно
подлый - созданые псевдодефектный блоки практически ничем не будут отличаться от заводских. И
использовать его следует только в САМЫХ КРАЙНИХ случаях, когда восстановить работу устройства надо
быстро и любой ценой, а в налиии имеется только чужой фуллдамп.

-um - проверять соответствие дефектных блоков файла и флешки. Это достаточно полезный режим,
предназначенный для заливки фуллдампа в ту же самую флешку, с которой он считывался. Поскольку заводские
дефектные блоки дампа и флешки совпадают полностью, то такой способ заливки дампа позволяет быстро и без
потерь восстановить работу устройства. В этом режиме qwdirect, встречая помеченный в файле дефектный
блок, проверяет, является ли дефектным соответствующий ему блок на флешке. Если да, то блок просто
пропускается , и запись продолжается со следующего блока. Заводской маркер дефекта не затрагивается. Если
соответствующий блок флешки — не дефектный, то процесс записи аварийно завершается, поскольку в этом
случае дамп не соответствует флешке (является чужим) и дальнейшая запись становится бессмысленной.

-ux - отключить аппаратный контроль дефектных блоков. В этом режиме блок входного дампа записывается
на флешку полностью, включая маркер дефектного блока. Исходный дамп для такой записи должен сниматься с
помощью qrflash также с ключом -ux. Данный режим также позволяет адекватно записать дамп в ту флешку, с
которой он был считан. Но использовать его крайне не рекомендуется. Во-первых, производить любые действия
(и особенно стирание) с заводскими дефектными блоками достаточно опасно — раз блок дефектный, то не факт,
что при следующей записи адекватно пропишется маркер. Во-вторых, в этом режиме невозможно призвести
контроль соответствия дефектных блоков дампа и флешки, в результате чего можно случайно залить в
устройство чужой дамп и затереть все заводские маркеры. Лучше в качестве фуллдампа использовать дамп,
снятый с помощью qrflash -uf, и записывать его с ключом -um.

-ub - не проверять дефектность блоков флешки перед записью. Это ОЧЕНЬ ОПАСНЫЙ режим. В нормальном
режиме работы qwdirect, перед тем как записать очередной блок, проверяет, не является ли блок дефектным. С
помощью данного ключа можно запретить эту проверку — целевой блок будет стерт и записан как обычный
блок, даже если является дефектным. Это гарантированно приведет к уничтожению заводских маркеров. По
сути, данный режим к применению настоятельно НЕ рекомендован. Он может использоваться только при
отладке, для перезаписи созданных вручную псевдодефектных блоков (например, с помощью qbadblock -m).
Именно этот режим использовался программой qwdirect до того, как в нее были встроены средства контроля
дефектных блоков. Запись фулдампов с использованием этого режима — грубое и ничем не оправданное
вмешательство, приводящее к массе потенциальных проблем из-за использования заводских дефектных блоков
для хранения данных.

О фуллдампах и клонировании полной флешки.


Многие ремонтники и исследователи для упрощения своей жизни используют полные посекторные дампы
флешек — фуллдампы. Предполагается, что такой дамп позволяет быстро восстановить прошивку устройства.
Однако, наличие дефектных блоков на флешке устройства-донора и восстанавливаемого пациента, по
вышеизложенным причинам, полностью препятствует использованию такого простого способа.
Следует различать 2 принципиально различных ситуации.
1. Донор и пациент — одно и то же устройство, то есть мы пытаемся записать фуллдамп на устройство, с
которого этот дамп был когда-то считан. Это самый благоприятный случай. Дефектные блоки лежат в одних и
тех же местах и в дампе и на флешке, и достаточно просто обойти их при записи. Фуллдамп следует считывать с
устройства командой qrflash с ключом -uf (который и подразумевается по умолчанию при чтении без
использования карты разделов). Запись делается с помощью qwdirect с ключом -um. При этом проверяется
соответсвие дефектных маркеров в дампе и на флешке, и дефектные блоки пропускаются. Если в дампе
обнаружится признак дефектного блока, а на флешке соотвествующий блок окажется хорошим, или, наоборот,
на флешке встретися дефектный блок, не отмеченный в дампе — запись аварийно завершится. Это будет
означать, что мы пытаемся залить в устройство чужой дамп, или на флешке образовались новые дефектные
блоки. В любом случае, адекватная запись фуллдампа становится невозможной.

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 цифры имени файла, содержащего дамп раздела. Таким образом можно записать
все разделы, или только некоторые, нуждающиеся в восстановлении. Все дефектные блоки, найденные на
флешке пациента, будут пропущены при записи. В результате заводские дефекты не потеряются, и адресация
блоков не нарушится, поскольку запись начинается не с начала флешки, а с границы раздела.