Прошивка на основе Linux, как реализовать хороший способ обновления? - PullRequest
14 голосов
/ 02 марта 2011

Я разрабатываю устройство на основе Linux, используя alix 2d13.

Я разработал сценарий, который заботится о создании файла образа, создании разделов, установке загрузчика (syslinux), ядра и initrd, а также об установке файлов корневой файловой системы в нужный раздел.

Файлы конфигурации находятся в файловой системе tmpfs и создаются при запуске системы программным обеспечением, считывающим файл XML, который находится в собственном разделе.

Я ищу способ обновить файловую систему, и я рассмотрел два решения:

  • обновление прошивки представляет собой сжатый файл, который может содержать разделы ядра, initrd и / или rootfs, поэтому при перезагрузке initrd позаботится о том, чтобы dd образ rootfs попал в правильный раздел;
  • обновление прошивки представляет собой сжатый файл, который может содержать два архива tar: один для загрузки и один для корневой файловой системы.

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

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

Что вы думаете?

Ответы [ 3 ]

18 голосов
/ 14 августа 2013

Я использовал следующий подход. Он был основан на статье «Создание Murphy-совместимых встраиваемых Linux-систем», доступной здесь . Я использовал материал versions.conf, описанный в этой статье, а не материал cfgsh.

  • Используйте загрузочное ядро, задачей которого является обратное монтирование «основной» корневой файловой системы. Если вам нужно более новое ядро, вставьте его в новое ядро ​​сразу после его монтирования в обратном направлении. Я решил поместить в initramfs полный init загрузочного ядра вместе с busybox и kexec (оба статически связаны), и мой init был простым сценарием оболочки, который я написал.
  • Одна или несколько корневых файловых систем «основной ОС» существуют в файловой системе «Образ ОС» в виде файлов образов дисков. Загрузочное ядро ​​выбирает один из них на основе файла versions.conf. Я поддерживаю только два основных файла образа ОС: текущий и резервный. Если текущий отказывает (более подробно об обнаружении ошибок позже), то загрузочное ядро ​​загружает запасной вариант. Если оба сбоя или нет возврата, загрузочное ядро ​​предоставляет оболочку.
  • Конфигурация системы находится в отдельном разделе. Обычно это не обновляется, но нет никаких причин, по которым это не может быть.
  • Всего четыре раздела: загрузочный, образ ОС, конфиг и данные. Раздел данных предназначен для пользовательского приложения, предназначенного для частой записи. boot никогда не монтируется для чтения / записи. Образ ОС только (пере) монтируется для чтения / записи во время обновлений. Конфигурация монтируется только для чтения / записи, когда требуется изменить конфигурацию (надеюсь, никогда). данные всегда монтируются для чтения / записи.
  • Каждый файл образа диска содержит полную систему Linux, включая ядро, сценарии инициализации, пользовательские программы (например, busybox, приложения продукта) и конфигурацию по умолчанию, которая копируется в раздел конфигурации при первой загрузке. Файлы любого размера, необходимого для размещения в них всего. Пока я оставлял достаточно места для роста, чтобы раздел образа ОС всегда был достаточно большим, чтобы вместить три основных файла образа ОС (во время обновления я не удаляю старый запасной вариант до тех пор, пока новый не будет извлечен), я могу позволяют основному образу ОС расти по мере необходимости. Эти файлы изображений всегда (с обратной связью) монтируются только для чтения. Использование этих файлов также избавляет от необходимости сталкиваться с ошибками при обновлении отдельных файлов внутри rootfs.
  • Обновления выполняются путем переноса самораспаковывающегося архива в tmpfs. Начало этого сценария перемонтирует образ ОС для чтения / записи, затем извлекает новый основной образ ОС в файловую систему образа ОС, а затем обновляет файл versions.conf (используя метод переименования, описанный в документе «murphy»). После этого я касаюсь файла штампа, указывающего, что произошло обновление, и перезагружаюсь.
  • Загрузочное ядро ​​ищет этот файл штампа. Если он находит его, он перемещает его в другой файл штампа, а затем загружает новый основной файл образа ОС. Ожидается, что основной файл образа ОС удалит файл штампа при успешном запуске. Если этого не произойдет, сторожевой таймер вызовет перезагрузку, а затем загрузочное ядро ​​увидит это и обнаружит сбой.
  • Вы заметите, что существует несколько возможных точек сбоя во время обновления: синхронизация versions.conf во время обновления и касание / удаление файлов штампа (три экземпляра). Я не мог найти способ уменьшить это далее и достигнуть всего, что я хотел. Если у кого-то есть лучшее предложение, я хотел бы услышать это. Ошибки файловой системы или сбои питания при записи образа ОС также могут иметь место, но я надеюсь, что файловая система ext3 обеспечит некоторые шансы на выживание в этом случае.
2 голосов
/ 07 августа 2013

У вас может быть отдельный раздел для обновления (скажем, Side1 / Side2). Существующее ядро ​​rootfs находится в Side1, затем поместите обновление в Side2 и переключитесь. Этим вы можете уменьшить выравнивание износа и увеличить срок службы, но устройство становится дороже.

0 голосов
/ 11 марта 2011

Вы можете быстро отформатировать разделы перед извлечением файлов tar.Или воспользуйтесь решением для обработки изображений, но используйте наименьшее возможное изображение и после dd измените размер файловой системы (хотя это не является обязательным для хранения только для чтения)

...