DIR825. USB-накопитель под «ОСь».
DIR825. USB-накопитель под «ОСь».
Немного лирического отступления … «Покопавшись» с фонерой — в результате чего родилась эта статья, были обнаружены ряд аппаратных ограничений сего девайса (FON 2201), не позволяющих «в полную меру развернуться» и превратить фонеру в гибкое и универсальное устройство, хотя изначальные предпосылки к этому есть (это ведь, попросту, линуксовая машинка). Основной «загвоздкой» явилось весьма малое количество встроенной флэш-памяти (8МБайт), часть которой занимает сама операционка (операционная система, далее «ось»). Устранение данного нюанса путем расширения встроенной памяти (перепайки микросхемы на более емкую) — во-первых трудоемко, во-вторых не решает проблемы координально (максимальное увеличение в 2-4 раза, что, собственно, не много). Вариант распаивать интерфейс SPI для использования карты памяти MMC|SD — мне также не показался привлекательным — скорость этого интерфейса невелика. Да и в целом на текущий момент мне не очень хочется лезть во внутрь моей единственной фонеры (а заполучить еще одну у нас не так-то и просто). Из всего этого стало понятно, что нужен подобный девайс, но с USB-портом … Такой железкой могла бы успешно стать фонера 2.0g (FON 2202) — таже полуторная фонера (как у меня) плюс наличие USB 2.0 порта и удвоенное количество ОЗУ (32МБайта), но добыть ее в России непросто (не переплачивая двойной цены). И в данной ситуации я решил подобрать иной девайс, с целью «прошивки» под OpenWRT и с тем железом, которое нужно мне. А уж раз постановка задачи дала мне возможность выбора, а также было ясно, что по габаритам и функционалу устройств сопоставимых Fonera 2.0g нет, — то планка аппаратных требований была поднята — уже требовалось «переплюнуть» так продвигаемую в сообществе FON фонеру 2.0n (FON 2303). Соответственно требования были таковы:
- процессор Atheros (архитектура mips — поддержка со стороны OpenWRT) — так сложилось, но «броадкомы» я «недолюбливаю»;
- наличие USB 2.0 порта;
- размер ОЗУ не менее 32МБайт;
- WiFi-карта, под стандарт 802.11n (с минимум двумя антеннами);
- антенны должны быть съемным;
Выбор пал на DIR825 (HW: B1 или B2) — подробнее о нем в сравнении с разными фонерами можно прочесть в предыдущей статье. К сожалению не так просто выбрать маршрутизатор по его «начинке» — производители скрывают эту информацию, считая ее видимо не интересной для конечного пользователя — а зря …
Теперь к теме настоящей статьи. Материал будет справедлив не только для DIR825, но и для прочих устройств с операционкой OpenWRT BackFire 10.03. Тут несколько определимся в терминах. Понятие «прошивка» для беспроводных маршрутизаторов не отражает объективной картины ее внутреннего функционала. Мы привыкли «прошивать» разные устройства от системных плат и видео-карт до мобильных и стационарных телефонов, плееров и т.п. Во всех этих случаях «прошивка» представляет собой «черный» ящик с неким содержимом, которое по нашему разумению, чем свежее — тем лучше. В случае же с маршрутизаторами работающими под OpenWRT «прошивка» представляет собой сборку базового образа операционной системы, с которой в дальнейшем предстоит работать (дополнять, настраивать и пр.).
OpenWRT в настоящей редакции (для DIR825) представлен в виде двух образов, имеющих координальные различия в своей структуре:
- openwrt-ar71xx-dir-825-b1-jffs2-backup-loader.bin — На разделе с файловой системой jffs2, доступной как для чтения, так и для записи — хранится операционная система, а также имеется свободной пространство. Есть возможность не только добавлять, но и заменять или даже удалять имеющиеся файлы. Понятно что такая структура требует квалифицированного обращения, ибо некорректности могут привести к невозможности загрузки операционной системы и необходимости прошивки и настройки с нуля. Помимо этого на встроенной флэш-памяти маршрутизатора (8МБайт) хранится загрузчик и еще некоторые вещи (не описываемые в рамках данной статьи).
- openwrt-ar71xx-dir-825-b1-squashfs-backup-loader.bin — Файлы операционной системы и базовой конфигурации хранятся на файловой системе squashfs, доступной только для чтения. Также есть раздел jffs2 (доступный для чтения и записи — изначально он чист). Кроме этого применена виртуальная файловая система mini_fo — осуществляющая маскИрование раздела squashfs, данными из jffs2 (называемой также overlay). Идея такова: на разделе с jffs2 (примонтированного к /overlay) по мере работы создается копия корневой структуры, содержимое которой преволирует (имеет более высокий приоритет) над файлами из squashfs, т.е. при обращении к файлу его наличие проверяется сначала на jffs2 и лишь за тем на squashfs (если на jffs2 его не оказалось). Таким образом все изменения и дополнения сохраняются на jffs2 маскИруя базовый образ на squashfs (данные на котором, в случае их наличия остаются там «мертвым грузом»), также jffs2 может содержать метку «удаления» файла из squashfs. При подобной структуре мы всегда можем очистить jffs2 раздел и тем самым вернуться к «настройкам по умолчанию» (базовому образу) без процедуры перепрошивки. Еще раз обращаю внимание — технологию маскирования обеспечивает виртуальная файловая система mini_fo, органицующая единый системный «корень» из двух разделов: squashfs и jffs2.
Есть не мало документов на различных сайтах и обсуждений на форумах каким образом «мигрировать» работу оси на внешний USB-флэш накопитель, присутствуют примеры скриптов, в том числе и на официальном сайте OpenWRT. Но есть ряд нюансов, которые недостаточно документированы или не документированы вовсе. В большинстве случаев приводятся лишь куски скриптов, а общую картину приходится достраивать самому.
И так. С первого взгляды бы казалось с первой конфигурацией разделов (все на jffs2) мигрировать должно было бы проще, но при тестировании возникли осложнения с синхронизацией папок /var и /tmp — а на структуре с mini_fo все прошло более гладко (с удалением одной строчки относительно предыдущего варианта). Теперь по пунктам что нужно предпринять:
Перенос системы на внешний USB-флэш накопитель.
- Для начала определимся — в какую файловую систему будем форматировать флэш-накопитель (или жесткий диск). Это может быть ext2 или ext3. Предлагаю остановиться на ext2, ибо основное преимущество ext3 — журналируемость для флэш-накопителей не очевидно (требует больше операций чтение/запись, что не прибавляет шансов на сохранность данных при сравнительно невысоких скоростях). В любом случае рекомендую отключать кеш на запись (в случае с ext3 это сделать чуть сложнее — и в этом случае теряется возможная прелесть журналируемости). Размечать и форматировать накопитель можно как средствами OpenWRT, так и на компе например утилитой parted magic. Тут же можно создать swap-раздел («файл подкачки»). Как основной раздел, так и swap-раздел целесообразно организовывать в виде «основных» разделов (подробности раметки накопителей выходят за рамки данной статьи).
- Для начала установим необходимые «драйверы» — модули ядра (с префиксом kmod*) необходимые для взаимодействия с USB-портом, накопителем и файловой системой (можно ограничиться только выбранной файловой системой или сразу добавить и прочие, на будущее — места они занимают мало). Выполнить это можно например следующей командой (предварительно обновив лист репозитория: opkg update — при настроенном подключении маршрутизатора к интернету):
Данные пакеты как и все модули ядра устанавливаются на встроенную память маршрутизатора, даже после того как мы успешно мигрируем.
- Создадим файл /etc/init.d/pivotroot следующего содержания (предполагаем что флэшка видна системе как устройство /dev/sda1):
Присвоим ему права 755. Данный скрипт выполняется в самом начале загрузки оси: выполняет проверку файловой системы на внешнем накопителе на наличие логических ошибок и исправляет их, далее осуществляется монтирование внешнего накопителя и перенаправление «корня» на него (средствами встроенного в операционную систему скрипта pivot_root).
- Пропишем этот скрипт в автозапуск следующей командой:
- Скопируем файлы операционной системы на внешний накопитель — откуда они впоследствии и будут использоваться (предполагаем что флэшку уже отформатировали, драйвера установили, маршрутизатор перезагрузили). Создадим в каталоге /tmp произвольный файл, присвоим ему права на исполнение (777) и запишем в него следующее (для развертывания содержимого — кликните на стрелочку справа от заголовка):
Выполним получившийся скрипт. Эти же строки (за исключением первой) можно выполнить и покомандно.
- Модифицируем скрипт /etc/init.d/rcS к следующему виду:
Красным помечены добавленные строки.
- Создадим файл /etc/pivotroot — поместим в него произвольный текст (хоть один символ — и уже файл не пустой).
- Перезагружаемся.
- Проверяем что у нас получилось:
отображается структуру разделов оси (последняя строчка указывает, что корень системы теперь на нашем флэш-накопителе).
- Для корректности работы выполним еще пару крманд:
- В случае, если в п.1 был также создан swap-раздел, то организуем его использование. Для этого создадим демона управления в виде файла /etc/init.d/swapctrl:
Установим файлу права 755. В данном случае подразумевается что swap-раздел виден системе как /dev/sda2. Активировать swap-раздел (как и любой другой демон) можно командой:
Для автозапуска данного демона можно выполнить:
Удедиться в активности swap-раздела, а также посмотреть общий раздер доступной памяти можно командой free.
- Вот собственно и все. «Старый корень» (содержимое squashfs), при текущем корне на внешнем накопителе — имеет точку монтирования /mnt, как и прежде маскируется через mini_fo из папки /mnt/overlay (учитывая это можно вносить изменения в файлы на встроенной памяти). В случае если нам будет необходимо загрузиться со встроенной памяти (например для установки модулей ядра), то следует очистить содержимое файла /mnt/etc/pivotroot и перезагрузиться — корнем будет структура mini_fo (overlay поверх squashfs) на встроенной памяти. Сотворив необходимые операции — для возврата обратно (к использованию внешнего накопителя в качестве корня) вносим любое содержимое в файл /etc/pivotroot (на встроенной памяти). Файл /etc/pivotroot на внешнем накопителе должен быть пустым!
- Есть замечания и вопросы ? — пишем комментарии …
Продолжение (2010-09).
Не так давно (июль 2010) в OpenWrt появился новый модуль — «extroot», организующий функцию миграции корня на внешний накопитель меньшими «плясками», в сравнении с описанным выше способом (которому до этого времени альтернативы собственно и не было).
Extroot — как им воспользоваться?
Для начала можно прочитать доку с официального сайта http://wiki.openwrt.org/doc/howto/rootfsonexternalstorage. Далее обратиться к уже упомянутому мной сайту, и на этот раз статье http://dipcore.com/?p=296. Из прочитанного стоит понять, что без пересборки прошивки в данном случае не обойтись. Обзор и линки на материалы по самостоятельной компиляции прошивки из исходников описаны ранее здесь. Разобраться и собрать прошивку самому — это правильный путь, и в этом нет ничего сложного (и это под силу тем, кто выполнил первую часть этой статьи ;-) Тем немее, кто не хочет заморачиваться с данным процессом, могут воспользоваться последней версией моей компиляции, всегда доступной для скачивания: http://maslenizza.ru/ar71xx/openwrt-ar71xx-dir-825-b1-squashfs-backup-loader.bin.
Немножко подробностей.
Все статьи на разных сайтах грешат отсутствием четкого алгоритма, более того информация, порой, содержит неточности — в общем всегда приходится не тупо копи-пастить, а включать мозги и обобщать ;-) Так вот еще один элемент для обобщения создаю и я ;-)) Ориентир, как всегда, больше на понимание, чем на тупой алгоритм для «чайника».
- Создаем разделы и форматируем наш «внешний накопитель» (жесткий диск, флешку, карту памяти в ридере) любыми средствами (утилитами в маршрутизаторе, опреционкой на виртуальной машине, загрузившись с лайв-сиди) — кому как удобнее. Число разделов и их порядок — опять-таки на ваше усмотрение (лучше создавать все разделы как «основные», а не логические диски в расширенном). В принципе можно ограничиться и одним разделом — в который и мигрирует наш «корень» — и файловую систему на нем ext2 (не стоит создавать под корень раздел с ext3, тем более на накопителе флеш — из-за пресловутого «журналирования», которое для корректности придется отключать*). Также целесообразно создать swap-раздел. Ну и для упорядочения хранимых данных (в случае большой емкости внешнего накопителя) можно изначально не распределять все пространство между «корнем» и «свопом», а оставить еще местечка под раздел данных, который можно отформатировать в любую linux-систему (ext2, ext3).
- Заливаем прошивку (предложенную выше, или собранную самостоятельно). При самостоятельной сборке в образ помимо драйверов usb, внешних накопителей и файловых систем (описано вначале статьи), необходимо также включить модули block-hotplug и block-mount (автоматизация монтирования), e2fsprogs (проверка целостности файловой системы), block-extroot (ради чего все и затевалось).
- Убедиться в работоспособности ;-) Скопировать содержимое корня образа на радел внешнего накопителя (в примере подразумевается, что файловая система накопителя ext2, а подключен он как sda1), сформировать swap-раздел (находится на sda2) — при помощи следующего скрипта (или покомандно из консоли):
- И напоследок (перед перезагрузкой) для обеспечения автоматического старта всей конструкции откорректируем файл /etc/config/fstab — приведя его к следующему виду:
В нашем случае sda1 — новый корень (ext2); sda2 — swap-раздел; sda3 — пользовательская область, монтируемая в /root (ext3). Впрочем значение всех параметров легко угадывается по названию. Считаю не лишним до перезагрузки скопировать этот файл и на новый корень, после чего выполнить команду sync и umount /mnt.
- Все (правда — все значительно упростилось?).
«Лирические отступления» — по тексту .
* «Журналирование» — хитрый процесс, в теории направленный на повышение вероятности сохранения целостности данных на накопители при внезапном его отключении в самые неподходящие моменты. Под «журнал» выделяется (резервируется) часть дискового пространства (пропорциональная его емкости). Журналироваться могут как непосредственно сами данные, так и только мета-информация. В первом случае запись происходит не на предполагаемое место хранения данных на диске в отведенную область журнала (при отключении диска на этой стадии и последующем включении и проверке — данные журнала признаются недействительными, а фактическая информация на диске остается в целостности, хоть и в устаревшем виде) — в случае успеха делается пометка, что для фактических данных требуется обновление из журнала. Далее предполагается процесс обновления фактических данных по данным «журнала» (при отключении накопителя в этот момент — считаются подлинными данные журнала, попытка записи которых на фактическое место происходит повторно) — в случае успеха (проверки соответствия) делаются соответствующие пометки и журнал «очищается». Такой алгоритм в два раза снижает скорость записи на накопитель, а в случае использования флеш-накопителя существенно способствует его износу (журнал хранится в фиксированном месте и являясь буфером постоянно перезаписывается). Если же применяется алгоритм журналирования мета-информации — достичь безусловной целостности не удастся — возможно лишь зафиксировать ее нарушения (мета-информация — фактически контрольные суммы блоков данных на накопителе). Как показала практика использование системы ext3 под «корнем» на внешнем накопителе с журналированием только мета-информации (режим по умолчанию) ведет к частому нарушению целостности информации (возможно мнимому), на инфа «коцаеца» корректность работы теряется, приходится либо включать полное журналирование (что для флеш-накопителя нежелательно по описанным выше причинам), либо отключать его вовсе — тогда вопрос: зачем на ext3 без журналирования — это уже фактически ext2 (использовать которую под «корень» я и рекомендую).