Тема: Надёжность флопиков и RAW NAND
Привет!
Лет 30 назад многие, работавшие с Агатом, думали или мечтали о подключении к Агату жесткого диска.
Я тоже думал об этом. Цель была не столь в объёмах, сколь в надёжности хранения.
На PC уже появились винты по 100 мег и выше и отказывали оно уже довольно редко.
Но позднее, когда я стал узнавать о кодах восстановления данных и прочих интересных штуках,
то стал задумываться о том, можно ли было бы сделать флопики более надёжными, пусть даже ценой некоторой потери объёма ?
Например, на дорожках 840ки обычно есть 21 сектор, но нередко попадаются защищенные диски с 22 секторами на каких нибудь дорожках. Поздние драйвера, поддерживающие ленивое чтение, имеют буфер для полной дорожки. Если этот буфер чуть расширить и форматировать 22 сектора на каждую дорожку, то можно в лишний сектор запихнуть XOR'ку от остальных байт на остальных секторах.
Имея такой сектор, можно будет, при ошибке чтения одного любого сектора (но только одного!), восстановить этот сектор из оставшихся 21.
Да, это будет требовать времени при записи (расчёт 22-го сектора при любом обновлении трека), но это не очень большое время.
--
Но недавно мне подумалось ещё вот о чём: а как бы сделать возможность высокой надёжности загрузки операционки с флопика ?
Ведь первой работает прога в ПЗУ, там и так места мало, да можно ли обойтись там без модификаций ?
--
История развивается по спирали. Флопики были не надёжны, жесткие диски стали получше, EEPROM стали ещё получше, потом Flash-память, достигшая рессурса едва ли не в миллион перезаписей. Но потом, в погоне за объёмами, история вернулась к ненадёжными накопителям: современная многоуровневая флеш имеет рессурс всего около 3000 перезаписей. Вроде бы много - если сравнить с флопиком, но мало, если много прог пишут что-то одновременно, часто и, при этом, постоянно перезаписываются системные области.
Тогда возникла идея о FTL (не, она раньше возникла, просто о ней меньше говорили). Flash Translation Layer - слой управления флеш-памятью, который пытается обеспечить равномерный износ ячеек памяти. Может быть организован как часть накопителя (свой контроллер внутри USB-флешки, SD-карты и т.д.) либо являться частью операционной системы (в этом случае используется т.н. RAW NAND - флеш-памяти без своего FTL).
Как работает FTL если совсем по простому: операционке нужно сохранить сектор номер 2. Она отправляет его на накопитель, там логика FTL решает: пишем в блок 12354, он сейчас свободен и отметит в своих таблицах, что сектор 2 сейчас сохранён в блоке 12354. А также увеличит счётчик износа этого блока. Если операционка снова запросит запись в сектор 2, FTL запишет данные уже в блок 12355 и отметит, что теперь сектор 2 сохранён в блоке 12355.
И вот именно этот вариант - когда используется FTL в операционке и RAW NAND в качестве накопителя - я как раз вспомнил в связи с Агатом. В чём интересное: как загрузить операционку с RAW NAND, если без операционки невозможно понять, где у тебя какой блок данных ? Т.е., например: операционка имеет начальный загрузчик в секторе 0, но в каком блоке RAW NAND находится этот сектор ?
Как это решается, например, в процессоре FreeScale imx6: ROM loader сперва читает блок RAW NAND номером 16 (точную цифру не помню, её можно уточнить в доках на проц). После этого он проверяет, что контрольная сумма блока верна и что блок имеет определённую сигнатуру. Если блок не прочитался (а реальная RAW NAND вполне может иметь несколько нечитающихся блоков даже при выходе с производства), ROM loader читает следующий блок и повторяет для него все те же операции.
Первый же блок, который будет иметь правильную CRC и сигнатуры, будет считаться загрузчиком.
В теле этого загрузчика уже будет находится что-то вроде "таблицы разделов" - это список регионов блоков RAW NAND, который будет передан ядру ОС. В соответствии с этой таблицей ядро уже будет настраивать свою подсистему FTL. Естесно, блоки, где хранится начальный загрузчик, не включаются в эту таблицу.
Как записывается начальный загрузчик ? Утилита записи, зная о ненадёжности RAW NAND, после записи каждого блока проверяет его чтением. Если блок не почитался (CRC не совпала), она повторяет запись той же информации в следующий блок.
Точно также пишется и ядро операционки, а также DTB-файл (описатель оборудования).
Всё остальное хранится уже поверх FTL, как правило, с использованием файловой системы UBIFS.
--
Возвращаясь к Агату:
ROM loader Агата работает похоже: он читает сектор 0/0, проверяет его CRC, если есть ошибка, он снова пытается найти и прочитать сектор 0/0. Поэтому, если создать примерно такой трек:
0 1 2 3 4 5 6 0 7 8 9 10 11 12 0 13 14 15 16 17 18 19
мы получим трек с трехкратным повтором сектора 0.
Так как ROM loader ищет подходящий сектор постоянно, он переберёт все сектора и те, которые будут иметь номер 0, попробует прочитать. Наверняка хотя бы одна из копий прочитается.
Можно также продублировать остальные сектора.
Интересно, что мне не встречалось в коллекциях агатовскго софта каких либо попыток повысить надёжность хранения данных на дисках программным путём, хотя, IMHO, это было вполне возможно. (Причем, например, для волковского архиватора 140кб дисков на 840ку - ввести какой-то подобный алгоритм было бы и не сложно и весьма полезно.)
Хотя эта тема на магнитофонах Спектрумов, вроде бы (поправьте, если я ошибаюсь!), вполне развивалась.