Table of Contents
Введение
Новые устройства от Pa1mOne предложили новую концепцию использования памяти. Популярные статьи на новостных сайтах породили целую мифологию вокруг новых устройств. Настоящая статья пытается объяснить как TT5 и Treo 650 в действительности используют память.
Как было раньше?
Напомню организацию памяти на остальных устройствах с PalmOS.
Вся память находится в адресном пространстве и делится на две области: динамическая куча и хранилище. В хранилище хранятся базы. Базы состоят из отдельных записей, каждая из которых хранится в отдельном блоке памяти. Динамическая куча используется для рабоих данных запущенной программы. Программы тоже хранятся как базы. Принцип организации программы позволяет не копировать исполняемый код в динамическую кучу, а исполнять его из записи в базе. Такое исполнение называется XIP, eXecution in place, стоит учесть что у термина есть и другое значение.
Для программиста работа с записью и временным блоком памяти совершенно аналогична, это позволяет считывать данные непосредственно из записи.
Такая организация очень экономна и позволяет использовать минимум памяти. Так, модель Clie NX-60 имеет 4Mb динамической кучи и 12Mb для хранилища.
Эта память отличается от флеш-памяти на MMC / SD / CF / MS карточке, которая выглядит для устройства как диск с файловой системой FAT. Память на карточке несколько “чужеродна” для PalmOS, в частности программы на карте не могут выставлять алармы и вызывать свои кондуиты при хотсинке. Исполнить программу с карты невозможно, ее нужно предварительно скопировать в хранилище и только после этого запустить.
Новая флеш-память
Даже сейчас оперативная память дорога и требует сравнительно много энергии. Современные технологии предлагают дешевую альтернативу в виде NAND флеш-памяти. Эта память аналогична используемым в картах памяти, но в отличии от них встаивается напрямую в устройство и может использовать более быструю шину для обмена данными. NAND-память сохраняет свое состояние после отключения питания и стоит значительно дешевле.
У NAND-памяти есть ряд существенных ограничений. Первое ограничение - это то, что она не может напрямую использоваться процессором. Таким образом программа, записанная во флеш не может в принципе исполняться на месте ( это второй смысл термина XIP - память, которая адресуется процессором для исполнения), данные из флеша не могут быть извлечены напрямую, и должен существовать буфер, в который будут копироваться данные и исполняемый код.
Второе ограничение - невозможность изменения одного байта. Области могут быть перезаписаны блоками по 512 байт. (На самом деле все запутаннее - можно изменять битики с 1 на 0, но не больше 10 раз на блок. Маловероятно, что изменения данных будут именно такими).
Как организована память в TT5 и Treo 650 ?
В новых моделях есть оба вида памяти - и динамическая (DRAM) и NAND-флеш.
NAND-флеш делится на
- Служебную область (256К)
- Область, в которой хранится компрессированный ROM (14Mb у TT5 и 8Mb у Treo 650)
- Область для баз из хранилища (64Mb у TT5 и 24Mb у Treo 650)
- Область файлового пространства (64.95Mb только у TT5)
- Резерв для битых блоков (12.8Mb)
Оперативная память резделяется на
- Область для распакованного ROM (16Mb)
- Кэш для хранилища (10Mb)
- Динамическая куча (6Mb)
Как соотносятся различные области памяти?
То что раньше называлось ROM, в котором хранилась PalmOS и встроенные программы, теперь хранится во флеше. Образ ROM распаковывается из флеша при ресетах и копируется в свою область в памяти. Именно это и обуславливает долгое время загрузки новых устройств.
Хранилище баз теперь хранится во флеше. Но поскольку к нему нельзя доступиться то запрашиваемые записи баз копируется в кэш и предоставляются программам для чтения и модификации. При закрытии базы и при выключении устройства модифицированные записи записываются обратно во флеш.
Файловое пространство представляет из себя обычный RAM-диск и не отличается от SD-карты по способу работы.
Стоит проследить запуск программы из файлового пространства. Сначала программа копируется в хранилище (то есть копируется в кэш и оттуда в область хранилища, удаляясь из кэша). Из хранилища она копируется обратно в кэш и запускается. После запуска программа удаляется и из кэша и из хранилища. Надеюсь, что PalmOne догадалась соптимизировать этот процесс.
Организация хранилища в NAND-флеше называется NVFS (Non-volatile File System).
“Олдовые” пользователи пальм помнят, что во времена PalmOS 4 существовали RAM Expanders, такие как AutoCard, PiDirect и MsMount. Эти программы эмулировали псевдо-файлы, содержимое которых находилось на карточке. NVFS является хаком над PalmOS, который точно так же эмулирует отсутствующие в оперативной памяти файлы.
Как действует кэш?
Рассмотрим работу классической программы MemoPad. Перечислим операции с базами, выполняемые при работе
- При запуске программа открывает базу MemoDB.
- Из базы считывается список категорий. Это первое чтение, которые вызывает считывание данных в кэш. После считывания кэш освобождается.
- Программа проходит по всем записям из текущей категории и считывает из них первые строки (по одному считыванию в кэш для каждой записи в категории). Рисуется список считанных записей. Каждая запись особождается сразу после считывания.
- Пользователь выбирает запись.
- Программа считывает в кэш указанную запись.
- Пользователь редактирует запись. Данные в кэше изменяются.
- Пользователь закрывает запись. Программа записывает кэш во флеш.
Учтите, что новые программы хранят данные в своем формате и одновременно поддерживают базы в старом формате. То есть на каждое обновление новой записи добавляется обновление старой.
Известные минусы NVFS
- Медленные груповые команды. Архитектура PalmOS подразумевает, что все программы в хранилище могут получать групповые команды, оповещающие о глобальных событиях, таких как загрузка после сброса, глобальный поиск данных, смена времени итд. Такие операции требуют последовательного запуска всех программ из хранилища. Для NVFS это означает поочередное копирование всех программ в кэш, а для поиска еще и копирование всех баз приложения. Если на старых реализациях программы просто ничего не делали в ответ на такой запуск (который происходил быстро), то сейчас такой запуск замедляет как старт машинки, так и поиск данных.
- Неэффективное использование пространства хранилища. В текущей реализации на каждую запись каждой базы используется блок размером в 512 байт. Это означает, что запись в 20 байт все равно займет 512 байт в хранилище. Рассмотрим пример: DateBk5 занимает 750Kb в виде prc. Он содержит 605 записей. Запись файла в классическое хранилище добавит 7.2Kb избыточных байт (8 байт на заголовок ресурса + 4 байта на хвост ресурса). В NVFS DateBk5 займет 1.7Мег. Двухкратная потеря. Второй пример - это база лекарств ePocrates. База содержит 3500 записей и занимает 2.5Mb, что превращается в 4Mb в NVFS. Стоит заметить, что Словоед не использует мелких записей и потери будут минимальны.
- У флешки число перезаписей ограничено. Называется число 100000 перезаписей. Модуль флешки отслеживает битые блоки и переносит их в список плохих блоков, подменяя на хорошие (под это выделено 12Мб), но на сколько по времени хватит ресурса - неизвестно. Пока что никто не может сказать когда посыпятся первые флешки. К счастью для нас разработчики флешек предусмотрели равномерное распределение записей по блокам. Это позволит всем блокам “стареть” одновременно, не допуская частой перезаписи ограниченного числа блоков.
- Известна проблема с русскими именами файлов на карточках. Проблема состоит в том, что длинное имя файла хранится в юникоде, а при отсутствии “правильной” русской поддержки имя преобразуется в неправильную кодовую страницу на юникоде. Соответственно пр включенном и выключенном пилоке длинное имя файла будет разным. Аналогичная ситуация возникает с сохранением файла в обучном storage на NVFS. Имя обычной базы будет преобразовываться в юникод по правилам активной кодовой страницы. А она при включенной-выключенной поддержке русского будет разной. И восстановление из юэкапа при выключенном пилоке создаст проблемы с русскими именами баз.
Жизнь после смерти или что происходит после нажатия на кнопку питания?
Вспомним классические пальмы. При нажатии на кнопку питания происходило следующее:
- Выключался экран.
- Частично выключалась периферия: контроллер карт памяти, диджитайзер, встроенные клавиатуры итд. Список выключаемых устройств зависел от модели.
- Процессор погружался в режим спячки, реагируя только на прерывания от активных устройств: кнопок и, возможно, порта.
- Устройство потребляло минимум питания, которое тратилось на подпитку памяти и подпитку схем, генерирующих прерывание от кнопок.
Отключение питания приводило к потере данных из памяти, в том числе и из хранилища и вызывало hard reset.
Новые устройства декларируют сохранность данных. Как показали опыты, TT5 в выключенном состоянии дольше держит заряд. Но это вовсе не означает, что устройству не нужно подпитывать DRAM. Почему?
Потому что программы могут запускаться только из оперативной памяти. А что там у нас лежало перед выключением? Можем ли мы это стереть?
- Область для распакованного ROM. Очевидно эта область важна. Выключив ее мы потеряем PalmOS. При включениии можно заново скопировать ее из флеша, но это длительный процесс (вспомните время, требующееся на ресет)
- Кэш для хранилища. Это область будет почти пуста. При выключении сохраняются грязные данные, но это не означает что кэш можно выключить. Там может лежать программа, которая имеет полное право реагировать на оповещении о включении.
- Динамическая куча. Здесь лежат рабочие данные активной программы. Откуда их взять?
Таким образом динамическая память требует подпитки даже на TT5 для сохранения рабочего состояния устройства. С другой стороны потеря питания приводит нас не к hard reset, а к обычному reset с сохранением всех данных в хранилище.
Формат хранилища (тех.)
В каком формате содержатся данные в хранилище? Хранилище - это еще один VFS диск с файловой системой FAT. В каталоге /PALM_DM хранятся базы, каждая в своем файле. В отличии от обычого VFS-диска файл - это не образ .prc файла, это структура, хранящая указатели на отдельные ресурсы и ресурсы, выровненные на 512-байтовую границу.
Такая структура была выбрана для эффективной работы с ресурсами. При использовании стандартного “плоского” prc файла для увеличения ресурса в середине пришлось бы сдвигать все последующие записи в файле.
Почему так криво? (тех.)
Технические специалисты задают вопрос - а почему так “неграмотно” организовано хранение данных? почему не использовали существующие файловые системы для флеша: JFFS или YAFFS? На мой взгляд это обусловлено следующими факторами.
- Во-первых разработчики были привязаны к существующей структуре баз. Каждая запись должна легко редактироваться. Все существующие FFS рассчитаны на классические плоские файлы.
- Во-вторых разработчики привязаны к интерфейсу, который предоставляет DiskOnChip. То есть нельзя миновать уровень трансляции, предлагаемый разработчикам чипов
Представим себе, что разработчики упаковали несколько записей в один блок. Чем это чревато?
- Возрастут расходы на адресацию: к номеру блока добавится еще и смещение в нем.
- Возрастут расходы на поддержание списка свободного места. Кроме списка блоков возникнет еще и список пустых мест в частично занятых блоках. А это сразу приведет к необходимости дефрагментации свободных подблоков.
- Возрастет сложность модификации записи. Если запись превысит остаток свободного места в блоке, то придется перемещать не только запись, но и соседей по блоку.
- Возрастет зависимость между соседними записями. При сбое в записи могут испортиться соседние записи.
Скорее всего PalmOne частично реализует хранение нескольких записей в одном блоке, но только для редкоизменяющихся баз. Разработчик должен будет явно указывать режим сохранения новых записей.