WB Firmware Update Details: различия между версиями

Материал из Wiren Board
Метка: visualeditor-switched
 
(не показано 9 промежуточных версий 2 участников)
Строка 1: Строка 1:
=== Дисклеймер ===
{{DISPLAYTITLE: Обновление прошивки, информация для разработчиков}}


Информация ниже предназначена для разработчиков, планирующих вносить изменения в систему обновления контроллеров Wiren Board.
=== Предупреждение ===
 
Информация на этой странице предназначена для разработчиков, планирующих вносить изменения в систему обновления контроллеров Wiren Board.


Информация для пользователей находится на странице [[Обновление прошивки]].
Информация для пользователей находится на странице [[Обновление прошивки]].
Строка 9: Строка 11:


Преимущества FIT:
Преимущества FIT:
* Легкий доступ к содержимому как из Linux, так и из u-boot
* Легкий доступ к содержимому как из Linux, так и из u-boot.
* Хранение метаданных и нескольких бинарных блобов в одном и том же файле
* Хранение метаданных и нескольких бинарных блобов в одном и том же файле.
* Поддержка контрольных сумм (SHA1) и криптографических подписей (RSA) для каждой части образа
* Поддержка контрольных сумм (SHA1) и криптографических подписей (RSA) для каждой части образа.
* Скорость работы из-за возможности случайного доступа к любой части
* Высокая скорость работы из-за возможности случайного доступа к любой части.


Более подробно о FIT можно узнать из [https://lxr.missinglinkelectronics.com/#uboot/doc/uImage.FIT/howto.txt документации u-boot].
Более подробно о FIT можно узнать из [https://lxr.missinglinkelectronics.com/#uboot/doc/uImage.FIT/howto.txt документации u-boot].


Обновление для Wiren Board в формате FIT содержит следующие элементы:
Обновление для Wiren Board в формате FIT содержит следующие элементы:
* '''Метаданные''': описание, версия, информация о модели для которой предназначено обновление, и т.д. Эта информация хранится в свойствах (properties) корневого узла и на данный момент не используется
* '''Метаданные''': описание, версия, информация о модели для которой предназначено обновление, и т.д. Эта информация хранится в свойствах (properties) корневого узла и пока не используется.
* '''install''': bash-скрипт, который запускается в Linux после загрузки образа. Этот скрипт и производит всю работу по обновлению
* '''install''': bash-скрипт, который запускается в Linux после загрузки образа. Этот скрипт и производит всю работу по обновлению.
* Прочие образы, используемые скриптом '''install'''. Текущая реализация этого скрипта поддерживает один образ '''rootfs''', содержащий корневую файловую систему в виде tar.gz
* Прочие образы, используемые скриптом '''install'''. Текущая реализация этого скрипта поддерживает один образ '''rootfs''', содержащий корневую файловую систему в виде tar.gz.


=== Схема разделов microSD/eMMC ===
=== Схема разделов microSD/eMMC ===


* /dev/mmcblk0p1 (16M): содержит загрузчик u-boot
* <code>/dev/mmcblk0p1</code> 16 Мб, содержит загрузчик u-boot.
* /dev/mmcblk0p2 (1024M): первая rootfs
* <code>/dev/mmcblk0p2</code> 1024 Мб, первая rootfs.
* /dev/mmcblk0p3 (1024M): вторая rootfs
* <code>/dev/mmcblk0p3</code> 1024 Мб, вторая rootfs.
* /dev/mmcblk0p4: расширенный раздел FAT, напрямую не используется
* <code>/dev/mmcblk0p4</code> расширенный раздел MBR, напрямую не используется.
* /dev/mmcblk0p5 (256M): swap
* <code>/dev/mmcblk0p5</code> 256 Мб, swap.
* /dev/mmcblk0p6 (остальное место): общие для обоих rootfs данные (конфиги, логи, ...), монтируется в /mnt/data
* <code>/dev/mmcblk0p6</code> остальное место общие для обоих rootfs данные: конфиги, логи и т.п., монтируется в <code>/mnt/data</code>.


Наличие двух независимых экземпляров rootfs позволяет в случае многократной неудачной загрузки с одной из них переключиться на другой экземпляр (например, при неудачном обновлении или порче файловой системы), а отдельный раздел /mnt/data позволяет при этом сохранить пользовательские настройки.
Наличие двух независимых экземпляров rootfs позволяет при многократной неудачной загрузке с одного из них переключиться на другой. Это может быть полезным при неудачном обновлении или порче файловой системы. Отдельный раздел <code>/mnt/data</code> позволяет сохранить пользовательские настройки.


Отдельный общий для двух rootfs раздел /mnt/data позволяет иметь некоторые части системной конфигурации одинаковыми. Например, это важно для настроек сети и авторизации. Так же на этом разделе хранятся логи, база данных MQTT, кэш apt и директория закачек веб-сервера (чтоб не занимать место на rootfs).
Отдельный раздел <code>/mnt/data</code> является общим для двух rootfs, что позволяет иметь некоторые части системной конфигурации одинаковыми: настройки сети и параметры авторизации. Так же на этом разделе хранятся логи, база данных MQTT, кэш apt и директория закачек веб-сервера. Такой подход позволяет уменьшить размер каждой из rootfs.


Образ SD-карты, создаваемый скриптом ''image/create_image.sh'' содержит только uboot и первую rootfs. Остальные разделы создаются при необходимости при первой загрузке.
Образ SD-карты, создаваемый скриптом <code>image/create_image.sh</code> содержит только uboot и первую rootfs. Остальные разделы создаются при первой загрузке.


При первой загрузке rootfs некоторые файлы переносятся в /mnt/data с сохранением бэкапов в rootfs и заменой оригиналов симлинками. Это происходит в скрипте /etc/rc.local, выполняющимся последним при загрузке. Если нужный файл уже существует в /mnt/data, то он используется без замены - это необходимо для использования имеющейся конфигурации при загрузке "свежей" rootfs после обновления прошивки. Также этот раздел можно очистить, при этом после перезагрузки будет восстановлена стандартная конфигурация.
При первой загрузке rootfs некоторые файлы переносятся в <code>/mnt/data</code> с сохранением бэкапов в rootfs и заменой оригиналов симлинками. Это происходит в скрипте <code>/etc/rc.local</code>, выполняющимся последним при загрузке. Если нужный файл уже существует в <code>/mnt/data</code>, то он используется без замены это необходимо для использования имеющейся конфигурации при загрузке «свежей» rootfs после обновления прошивки. Также этот раздел можно очистить, при этом после перезагрузки будет восстановлена стандартная конфигурация.


=== Переключение rootfs при ошибках загрузки ===
=== Переключение rootfs при ошибках загрузки ===


Реализована с помощью функции u-boot [http://www.denx.de/wiki/view/DULG/UBootBootCountLimit Boot Count Limit]
Реализована с помощью функции u-boot [http://www.denx.de/wiki/view/DULG/UBootBootCountLimit Boot Count Limit]
Используются следующие переменные окружения:
Используются следующие переменные окружения:
* '''bootcount''' - счетчик попыток загрузки, увеличивается на 1 при каждом входе в u-boot
* '''bootcount''' счетчик попыток загрузки, увеличивается на 1 при каждом входе в u-boot.
* '''bootlimit''' - максимальное значение '''bootcount''' при превышении которого происходит переключение активной rootfs
* '''bootlimit''' максимальное значение '''bootcount''' при превышении которого происходит переключение активной rootfs.
* '''mmcpart''' - хранит номер раздела текущей активной rootfs (2 или 3)
* '''mmcpart''' хранит номер раздела текущей активной rootfs (2 или 3).
* '''altbootcmd''' - команда, выполняющяяся при превышении '''bootlimit''': изменяет '''mmcpart''' и обнуляет '''bootcount''' для того, чтоб попытки загрузки с альтернативной rootfs считались заново
* '''altbootcmd''' команда, выполняющяяся при превышении '''bootlimit''': изменяет '''mmcpart''' и обнуляет '''bootcount''' для того, чтоб попытки загрузки с альтернативной rootfs считались заново.
* '''upgrade_available''' - должна быть равна 1 чтобы весь этот механизм работал
* '''upgrade_available''' должна быть равна 1 чтобы весь этот механизм работал.


При удачной загрузке переменная bootcount устанавливается в 0 из скрипта /etc/init.d/wb-init, выполняющимся предпоследним перед rc.
При удачной загрузке переменная bootcount устанавливается в «0» из скрипта <code>/etc/init.d/wb-init</code>, выполняющимся предпоследним перед rc.


=== Сборка FIT-образа обновления ===
=== Сборка FIT-образа обновления ===
Строка 59: Строка 62:
</syntaxhighlight>
</syntaxhighlight>


При этом в апдейт включается '''install''' из файла '''image/install_update.sh''' и собирается tar.gz с rootfs из указанной директории (также можно указать уже имеющийся tar.gz).
При этом в апдейт включается '''install''' из файла '''image/install_update.sh''' и собирается tar.gz с rootfs из указанной директории (также можно указать уже имеющийся tar.gz).  
[[Сборка_образов_прошивки | Подробная инструкция]]
 
Подробную инструкцию можете прочитать в статье «[[Сборка_образов_прошивки|Сборка образов прошивки]]».


=== Загрузка обновления на контроллер ===
=== Загрузка обновления на контроллер ===
Строка 68: Строка 72:
</syntaxhighlight>
</syntaxhighlight>


Загруженный файл попадает в ''/var/www/uploads/'', где обнаруживается скриптом '''wb-watch-update''' и при полной загрузке (проверяется наличие сигнатуры в конце файла) - запускается скрипт '''wb-run-update''' (оба этих скрипта лежат в пакете ''wb-utils''), который проверяет контрольную сумму скрипта '''install''' и запускает его на исполнение.
Загруженный файл попадает в <code>/var/www/uploads/</code>, где обнаруживается скриптом '''wb-watch-update''' и при полной загрузке (проверяется наличие сигнатуры в конце файла) запускается скрипт '''wb-run-update''' (оба этих скрипта лежат в пакете <code>wb-utils</code>), который проверяет контрольную сумму скрипта '''install''' и запускает его на исполнение.


Лог выполнения обновления сохраняется в файл ''/var/log/update.log'' (он же ''/mnt/data/var/log/update.log'')
Лог выполнения обновления сохраняется в файл <code>/var/log/update.log</code>, он же <code>/mnt/data/var/log/update.log</code>.

Текущая версия на 10:29, 14 апреля 2023


Предупреждение

Информация на этой странице предназначена для разработчиков, планирующих вносить изменения в систему обновления контроллеров Wiren Board.

Информация для пользователей находится на странице Обновление прошивки.

Формат файла обновления

Используется Flattened Image Table (FIT). Это современный формат используемый u-boot для хранения нескольких частей прошивки в одном файле. Фактически этот формат совместим с Device Tree (DTB) и для работы с ним используются те же утилиты (dtc, fdtget, ...).

Преимущества FIT:

  • Легкий доступ к содержимому как из Linux, так и из u-boot.
  • Хранение метаданных и нескольких бинарных блобов в одном и том же файле.
  • Поддержка контрольных сумм (SHA1) и криптографических подписей (RSA) для каждой части образа.
  • Высокая скорость работы из-за возможности случайного доступа к любой части.

Более подробно о FIT можно узнать из документации u-boot.

Обновление для Wiren Board в формате FIT содержит следующие элементы:

  • Метаданные: описание, версия, информация о модели для которой предназначено обновление, и т.д. Эта информация хранится в свойствах (properties) корневого узла и пока не используется.
  • install: bash-скрипт, который запускается в Linux после загрузки образа. Этот скрипт и производит всю работу по обновлению.
  • Прочие образы, используемые скриптом install. Текущая реализация этого скрипта поддерживает один образ rootfs, содержащий корневую файловую систему в виде tar.gz.

Схема разделов microSD/eMMC

  • /dev/mmcblk0p1 16 Мб, содержит загрузчик u-boot.
  • /dev/mmcblk0p2 1024 Мб, первая rootfs.
  • /dev/mmcblk0p3 1024 Мб, вторая rootfs.
  • /dev/mmcblk0p4 расширенный раздел MBR, напрямую не используется.
  • /dev/mmcblk0p5 256 Мб, swap.
  • /dev/mmcblk0p6 остальное место — общие для обоих rootfs данные: конфиги, логи и т.п., монтируется в /mnt/data.

Наличие двух независимых экземпляров rootfs позволяет при многократной неудачной загрузке с одного из них переключиться на другой. Это может быть полезным при неудачном обновлении или порче файловой системы. Отдельный раздел /mnt/data позволяет сохранить пользовательские настройки.

Отдельный раздел /mnt/data является общим для двух rootfs, что позволяет иметь некоторые части системной конфигурации одинаковыми: настройки сети и параметры авторизации. Так же на этом разделе хранятся логи, база данных MQTT, кэш apt и директория закачек веб-сервера. Такой подход позволяет уменьшить размер каждой из rootfs.

Образ SD-карты, создаваемый скриптом image/create_image.sh содержит только uboot и первую rootfs. Остальные разделы создаются при первой загрузке.

При первой загрузке rootfs некоторые файлы переносятся в /mnt/data с сохранением бэкапов в rootfs и заменой оригиналов симлинками. Это происходит в скрипте /etc/rc.local, выполняющимся последним при загрузке. Если нужный файл уже существует в /mnt/data, то он используется без замены — это необходимо для использования имеющейся конфигурации при загрузке «свежей» rootfs после обновления прошивки. Также этот раздел можно очистить, при этом после перезагрузки будет восстановлена стандартная конфигурация.

Переключение rootfs при ошибках загрузки

Реализована с помощью функции u-boot 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.

$ cd wirenboard
$ ./image/create_update.sh <path_to_roots> <update file>

При этом в апдейт включается install из файла image/install_update.sh и собирается tar.gz с rootfs из указанной директории (также можно указать уже имеющийся tar.gz).

Подробную инструкцию можете прочитать в статье «Сборка образов прошивки».

Загрузка обновления на контроллер

$ curl -v -F "file=@wb-update.fit" http://192.168.0.33/fwupdate/upload

Загруженный файл попадает в /var/www/uploads/, где обнаруживается скриптом wb-watch-update и при полной загрузке (проверяется наличие сигнатуры в конце файла) — запускается скрипт wb-run-update (оба этих скрипта лежат в пакете wb-utils), который проверяет контрольную сумму скрипта install и запускает его на исполнение.

Лог выполнения обновления сохраняется в файл /var/log/update.log, он же /mnt/data/var/log/update.log.