|
|
Строка 42: |
Строка 42: |
|
| |
|
| == Информация для разработчиков == | | == Информация для разработчиков == |
| === Формат файла обновления ===
| |
| Используется Flattened Image Table (FIT). Это современный формат используемый u-boot для хранения нескольких частей прошивки в одном файле. Фактически этот формат совместим с Device Tree (DTB) и для работы с ним используются те же утилиты (dtc, fdtget, ...).
| |
|
| |
|
| Преимущества FIT:
| | Информация о внутреннем устройстве системы обновлений находится на [[WB Firmware Update Details|отдельной странице]]. |
| * Легкий доступ к содержимому как из Linux, так и из u-boot
| |
| * Хранение метаданных и нескольких бинарных блобов в одном и том же файле
| |
| * Поддержка контрольных сумм (SHA1) и криптографических подписей (RSA) для каждой части образа
| |
| * Скорость работы из-за возможности случайного доступа к любой части
| |
| | |
| Более подробно о FIT можно узнать из [https://lxr.missinglinkelectronics.com/#uboot/doc/uImage.FIT/howto.txt документации u-boot].
| |
| | |
| Обновление для Wiren Board в формате FIT содержит следующие элементы:
| |
| * '''Метаданные''': описание, версия, информация о модели для которой предназначено обновление, и т.д. Эта информация хранится в свойствах (properties) корневого узла и на данный момент не используется
| |
| * '''install''': bash-скрипт, который запускается в Linux после загрузки образа. Этот скрипт и производит всю работу по обновлению
| |
| * Прочие образы, используемые скриптом '''install'''. Текущая реализация этого скрипта поддерживает один образ '''rootfs''', содержащий корневую файловую систему в виде tar.gz
| |
| | |
| === Схема разделов microSD/eMMC ===
| |
| | |
| * /dev/mmcblk0p1 (16M): содержит загрузчик u-boot
| |
| * /dev/mmcblk0p2 (1024M): первая rootfs
| |
| * /dev/mmcblk0p3 (1024M): вторая rootfs
| |
| * /dev/mmcblk0p4: расширенный раздел FAT, напрямую не используется
| |
| * /dev/mmcblk0p5 (256M): swap
| |
| * /dev/mmcblk0p6 (остальное место): общие для обоих rootfs данные (конфиги, логи, ...), монтируется в /mnt/data
| |
| | |
| Наличие двух независимых экземпляров rootfs позволяет в случае многократной неудачной загрузки с одной из них переключиться на другой экземпляр (например, при неудачном обновлении или порче файловой системы), а отдельный раздел /mnt/data позволяет при этом сохранить пользовательские настройки.
| |
| | |
| Отдельный общий для двух rootfs раздел /mnt/data позволяет иметь некоторые части системной конфигурации одинаковыми. Например, это важно для настроек сети и авторизации. Так же на этом разделе хранятся логи, база данных MQTT, кэш apt и директория закачек веб-сервера (чтоб не занимать место на rootfs).
| |
| | |
| Образ SD-карты, создаваемый скриптом ''image/create_image.sh'' содержит только uboot и первую rootfs. Остальные разделы создаются при необходимости при первой загрузке.
| |
| | |
| При первой загрузке rootfs некоторые файлы переносятся в /mnt/data с сохранением бэкапов в rootfs и заменой оригиналов симлинками. Это происходит в скрипте /etc/rc.local, выполняющимся последним при загрузке. Если нужный файл уже существует в /mnt/data, то он используется без замены - это необходимо для использования имеющейся конфигурации при загрузке "свежей" rootfs после обновления прошивки. Также этот раздел можно очистить, при этом после перезагрузки будет восстановлена стандартная конфигурация.
| |
| | |
| === Переключение rootfs при ошибках загрузки ===
| |
| | |
| Реализована с помощью функции u-boot [http://www.denx.de/wiki/view/DULG/UBootBootCountLimit Boot Count Limit]
| |
| Используются следующие переменные окружения:
| |
| * '''bootcount''' - счетчик попыток загрузки, увеличивается на 1 при каждом входе в u-boot
| |
| * '''bootlimit''' - максимальное значение '''bootcount''' при превышении которого происходит переключение активной rootfs
| |
| * '''mmcpart''' - хранит номер раздела текущей активной rootfs (2 или 3)
| |
| * '''altbootcmd''' - команда, выполняющяяся при превышении '''bootlimit''': изменяет '''mmcpart''' и обнуляет '''bootcount''' для того, чтоб попытки загрузки с альтернативной rootfs считались заново
| |
| * '''upgrade_available''' - должна быть равна 1 чтобы весь этот механизм работал
| |
| | |
| При удачной загрузке переменная bootcount устанавливается в 0 из скрипта /etc/init.d/wb-init, выполняющимся предпоследним перед rc.
| |
| | |
| === Сборка FIT-образа обновления ===
| |
| | |
| Все нужные скрипты есть в репозитории wirenboard.
| |
| | |
| <syntaxhighlight lang="bash">
| |
| $ cd wirenboard
| |
| $ ./image/create_update.sh <path_to_roots> <update file>
| |
| </syntaxhighlight>
| |
| | |
| При этом в апдейт включается '''install''' из файла '''image/install_update.sh''' и собирается tar.gz с rootfs из указанной директории (также можно указать уже имеющийся tar.gz).
| |
| | |
| === Загрузка обновления на контроллер ===
| |
| | |
| <syntaxhighlight lang="bash">
| |
| $ curl -v -F "file=@wb-update.fit" http://192.168.0.33/fwupdate/upload
| |
| </syntaxhighlight>
| |
| | |
| Загруженный файл попадает в ''/var/www/uploads/'', где обнаруживается скриптом '''wb-watch-update''' и при полной загрузке (проверяется наличие сигнатуры в конце файла) - запускается скрипт '''wb-run-update''' (оба этих скрипта лежат в пакете ''wb-utils''), который проверяет контрольную сумму скрипта '''install''' и запускает его на исполнение.
| |
| | |
| Лог выполнения обновления сохраняется в файл ''/var/log/update.log'' (он же ''/mnt/data/var/log/update.log'')
| |