Программирование ARM Сборка и использование MCUboot вместе с приложением Zephyr Tue, October 08 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Сборка и использование MCUboot вместе с приложением Zephyr Печать
Добавил(а) microsin   

MCUboot начал свою жизнь как загрузчик для Mynewt. С тех пор он также приобрел возможность применения в качестве загрузчика и для приложений Zephyr. В этой статье (перевод [1]) описаны несколько значимых отличий в том, как приложения собираются для Zephyr для загрузки под управлением MCUBoot.

См. документ design.md репозитория [2] или [3] для документации по разработке и принципу работы самого загрузчика. Этот функционал должен быть одинаковым для всех поддерживаемых RTOS.

В качестве первого шага, необходимого для Zephyr, нужно убедиться, что ваша плата имеет несколько flash-разделов, определенных в дереве устройств (board device tree). Вот эти разделы:

boot_partition: раздел для самого MCUboot
image_0_primary_partition (или slot0_partition): первичный слот Image 0
image_0_secondary_partition (или slot1_partition): вторичный слот Image 0
scratch_partition: scratch-слот (его наличие необязательно, см. примечание).

Примечание: не рекомендуется использовать алгоритм "переключение разделов с использованием временной области" (swap-using-scratch), однако если нужен этот рабочий режим, то также нужен раздел scratch_partition (в конце этого документа описаны подробности создания scratch partition, и как его использовать для алгоритма swap-using-scratch).

В настоящее время соседние слоты образа должны быть смежными. Если вы запускаете MCUboot как загрузчик первого уровня (stage 1 bootloader), то `boot_partition` должен быть сконфигурирован для запуска, когда ваш SoC/MCU выходит из состояния сброса. Если нужно несколько обновляемых образов, то соответствующие primary и secondary разделы должны быть определены также и для остальных образов, например image_1_primary_partition и image_1_secondary_partition для Image 1 (или slot2_partition и slot3_partition для Image 1).

Разделы flash обычно определяются в Zephyr-папке boards, и получают имена файлов boards/ < arch>/< board>/< board>.dts. Например, .dts-файл с flash-разделами для платы frdm_k64f определяется как boards/arm/frdm_k64f/frdm_k64f.dts. Убедитесь, что метки узлов дерева устройств (DT node labels) в .dts-файле вашей платы соответствуют используемым там меткам.

[Удовлетворение требований и установка зависимостей]

Установите дополнительные пакеты, необходимые для разработки с использованием MCUboot:

cd ~/mcuboot  # или cd на вашу директорию, куда склонирован MCUboot
pip3 install --user -r scripts/requirements.txt

[Сборка самого загрузчика]

Загрузчик это обычное приложение Zephyr, как минимум с точки зрения системы Zephyr. Перед сборкой нужно выполнить некоторую конфигурацию. Большинство опций можно настроить, как задокументировано в файле CMakeLists.txt, находящемся в папке boot/zephyr. Здесь следует сделать несколько замечаний. Важно выбрать алгоритм подписи и принять решение, должен ли быть проверен primary-слот при каждой загрузке.

Чтобы собрать MCUboot, создайте директорию build в папке boot/zephyr, и выполните сборку как обычно:

cd boot/zephyr
west build -b < имяплаты>

Примечание: альтернативно вместо опции -b можно определить переменную окружения BOARD=имяплаты, например командой export BOARD=nrf52840dk_nrf52840. Список имен поддерживаемых платок можно подсмотреть командой west boards.

В дополнение к разделам, определенным в DTS (DeviceTree Source [4]), в настоящее время для сборки самого MCUboot должна быть дополнительная информация по разметке flash. Вся необходимая конфигурация собрана в boot/zephyr/include/target.h. В зависимости от платы, эта информация может поступать от заголовочных файлов, специфичных для платы, от Device Tree, или она конфигурируется в MCUboot на основе выбранного семейства SoC/MCU.

После сборки загрузчика двоичные файлы должны находиться в build/zephyr/zephyr.{bin,hex,elf}, где build это директория сборки, выбранная вами при запуске cmake (или west build). Используйте flash-таргет системы сборки Zephyr (команду west flash), чтобы прошить эти бинарники (обычно west flash запускается из корневой директории проекта приложения, т. е. где находится файл CMakeLists.txt. В зависимости от целевого MCU и используемой утилиты прошивки, перед программированием самого образа загрузчика эта команда может стереть всю память flash (mass erase), или только те сектора, где находится загрузчик.

[Сборка приложений для загрузчика]

В дополнение к flash-разделам в DTS требуется некоторая дополнительная конфигурация, чтобы собрать приложения для использования вместе с MCUboot.

Это обрабатывается внутри системы конфигурирования Zephyr, и обертывается Kconfig-переменной CONFIG_BOOTLOADER_MCUBOOT, которая должна быть разрешена в файле prj.conf приложения.

Директория samples/zephyr/hello-world в дереве проекта MCUboot содержит простое приложение со всем, что вам нужно. Вы можете попробовать его на своей плате, и затем просто скопировать его и взять как отправную точку для собственного приложения; для руководства см. samples/zephyr/README.md.

Опция конфигурации Zephyr CONFIG_BOOTLOADER_MCUBOOT предоставляет дополнительные подробности касательно изменений положения образа в памяти и генерации проекта для приложения, чтобы оно могло быть загружено MCUboot.

С этим выполните сборку приложения, как обычно.

Цифровая подпись приложения. Чтобы обновиться на образ (или даже просто загрузить его, если разрешена опция MCUBOOT_VALIDATE_PRIMARY_SLOT), образы должны быть подписаны. Чтобы упростить разработку, MCUboot распространяется с примером ключей. Важно понимать, что их не следует использовать для готовой продукции, поскольку приватный ключ раскрыт и доступен в репозитории MCUboot [2]. Ниже показано, как генерировать свои собственные подписи.

Образы могут быть подписаны скриптом scripts/imgtool.py. Примеры, как это делать, см. в samples/zephyr/Makefile.

Прошивка приложения. Само приложение может быть прошито обычными утилитами программирования, однако оно должно быть записано со смещением primary-слота для этого определенного целевого MCU. В зависимости от платформы и инструментария программирования вам может понадобиться вручную указать смещение во flash, соответствующее начальному адресу primary-слота. Это обычно не относится к flash-утилитам, которые используют образы в формате Intel Hex (.hex) вместо сырых бинарных образов (.bin), поскольку HEX внутри себя описывает адреса назначения для данных. Дополнительно вам нужно убедиться, что утилита программирования не делает полное стирание flash (mass erase), иначе MCUboot может быть случайно удален. Образы могут быть помечены для апгрейда, и загружены во вторичный слот, с которого загрузчик должен осуществлять апгрейд. Перед следующей перезагрузкой следует пометить primary-слот как "image ok", иначе загрузчик откатит приложение.

[Управление ключами подписи]

Ключи подписи, используемые MCUboot, представлены в стандартных форматах, и могут быть сгенерированы и обработаны обычными утилитами. Однако scripts/imgtool.py может генерировать пары ключей во всех поддерживаемых форматах. См. imgtool.md для дополнительной информации по утилите imgtool.py.

Генерация новой пары ключей. Генерация пары ключей с помощью imgtool решается указанием подкоманды keygen:

$ ./scripts/imgtool.py keygen -k mykey.pem -t rsa-2048

Аргумент -t указывает желаемый тип ключа. Подробнее о типах ключей см. imgtool.md.

Извлечение публичного ключа. Сгенерированная пара ключей содержит как публичный, так и приватный ключ. Необходимо извлечь из пары публичный ключ и вставить его в загрузчик. Используйте Kconfig-опцию CONFIG_BOOT_SIGNATURE_KEY_FILE, чтобы предоставить путь до файла ключа, так система сборки может извлечь публичный ключ в формате, подходящем для компилятора C. Сгенерированный публичный ключ сохранен в build/zephyr/autogen-pubkey.h, который подключается из boot/zephyr/keys.c.

Ключи, которые находятся в boot/zephyr/keys.c, могут быть распакованы с помощью imgtool. Пример извлечения публичного ключа:

$ ./scripts/imgtool.py getpub -k mykey.pem

Эта команда выведет публичный ключ как C-массив, который можно напрямую вставить в файл keys.c.

Как только это завершено, новый файл пары ключей (в этом примере mykey.pem) может использоваться для подписи образов.

В настоящий момент порт Zephyr RTOS ограничивает использование только одной пары ключей, хотя инфраструктура управления ключами MCUboot поддерживает несколько пар ключей.

[Использование алгоритма прошивки swap-using-scratch]

Чтобы применить алгоритм swap-using-scratch flash, в целевой плате должен присутствовать scratch-раздел, который хранит данные свапа из обоих слотов. Эта секция flash должна быть, по меньшей мере, такой же большой, как самый большой размер сектора двух разделов (например, если у устройства есть primary слот в основной flash с размером сектора 512 байт, и secondary слот во внешней flash с размером сектора 4KB, то область scratch должна быть как минимум 4KB). Размер в байтах также должен нацело делиться на размер этого сектора, например разрешается использовать 4KB, 8KB, 12KB, 16KB, но не 7KB, 7.5KB. Этот scratch-раздел должен быть добавлен в .dts-файл платы, например для платы nrf52dk_nrf52832 потребуется обновить < zephyr>/boards/arm/nrf52dk_nrf52832/nrf52dk_nrf52832.dts следующим:

    boot_partition: partition@0 {
        label = "mcuboot";
        reg = < 0x00000000 0xc000>;
    };
    slot0_partition: partition@c000 {
        label = "image-0";
        reg = < 0x0000C000 0x37000>;
    };
    slot1_partition: partition@43000 {
        label = "image-1";
        reg = < 0x00043000 0x37000>;
    };
    storage_partition: partition@7a000 {
        label = "storage";
        reg = < 0x0007a000 0x00006000>;
    };

Этот пример делает размер приложения 220KB и размер scratch 24KB (у чипа nRF52832 размер сектора 4KB, поэтому размер раздела scratch может быть уменьшен ценой трат времени жизни flash, например обновление 32KB firmware с помощью 8KB области scratch она будет стерта и перепрограммирована 8 раз на один апгрейд или откат образа). Чтобы сконфигурировать MCUboot для работы swap-using-scratch, нужно установить значение Kconfig: CONFIG_BOOT_SWAP_USING_SCRATCH=y.

Обратите внимание, что приложение может войти в состояние зависания, когда используется swap-using-scratch, из за того что приложеие загрузило обновление firmware и пометило его как проверенное (test/confirmed), но MCUboot не поменял образы, и стирание secondary слота из приложения zephyr вернет ошибку, так как слот был помечен для апгрейда.

[Ссылки]

1. Building and using MCUboot with Zephyr site:docs.mcuboot.com.
2. mcu-tools / mcuboot.
3. Загрузчик MCUboot.
4. Introduction to devicetree site:zephyrproject.org.

 

Добавить комментарий


Защитный код
Обновить

Top of Page