Files
2026-07-08 10:00:27 -04:00

129 lines
3.8 KiB
Markdown

# MCUBoot Implementation Guide
Documentation of the steps taken to implement MCUBoot on a Nucleo G431RB development board.
## Environnment config
Use the environment written in flake.nix by running `nix develop`
## Set up Zephyr
Zephyr is the RTOS that uses the MCUboot bootloader being set up.
[Getting started with Zephyr](https://docs.zephyrproject.org/latest/develop/getting_started/index.html)
```sh
west init zephyrproject
cd zepyhrproject
west update
west zephyr-export
cd zepyhr
west sdk install
```
## MCUBoot POC Implementation
MCUBoot is a bootloader for Zephyr, which allows multiple firmwares to exist on a board. MCUBoot can dynamically switch which firmware is active. This is useful in the event of one firmware failing.
[Abstract MCUBoot Guide](https://docs.mcuboot.com/readme-zephyr.html)
```sh
west build -p always -b nucleo_g431rb samples/basic/blinky
west flash --runner pyocd # had to su root first to run this (after running nix develop)
```
## Configure partition sizes
The devicetree specification file declares the hardware configuration. The flash storage needs three partitions, one for boot, and two for the two firmwares it will hold.
[DeviceTree Specification documentation](https://docs.zephyrproject.org/latest/build/dts/intro-scope-purpose.html)
[Partitioning examples](https://docs.zephyrproject.org/latest/build/dts/api/bindings/mtd/fixed-partitions.html)
The board I'm using has its DeviceTree Specification in `zephyr/boards/st/nucleo_g431rb/nucleo_g431rb.dts`
I created a partition for MCUBoot, two firmware slots, and additional storage in the flash storage.
```c
&flash0 {
partitions {
#address-cells = <1>;
#size-cells = <1>;
ranges;
boot_partition: partition@0 {
compatible = "zephyr,mapped-partition";
label = "mcuboot";
reg = <0x00000000 0x00008000>;
};
slot0_partition: partition@8000 {
compatible = "zephyr,mapped-partition";
label = "image-0";
reg = <0x00008000 0x00010000>;
};
slot1_partition: partition@10000 {
compatible = "zephyr,mapped-partition";
label = "image-1";
reg = <0x00010000 0x0018000>;
};
storage_partition: partition@18000 {
compatible = "zephyr,mapped-partition";
label = "storage";
reg = <0x00018000 0x00020000>;
};
};
};
```
## Try to build MCUBoot
```sh
west build -p always -b nucleo_g431rb bootloader/mcuboot/boot/zephyr
```
old below
```
# Create a private key: https://docs.mcuboot.com/readme-zephyr.html
python ./bootloader/mcuboot/scripts/imgtool.py keygen -k private.pem -t rsa-2048
# Create its public key
openssl rsa -in private.pem -pubout > public.pem
# Set up signing: https://docs.mcuboot.com/readme-zephyr.html
# ./bootloader/mcuboot/samples/zephyr/Makefile
python bootloader/mcuboot/scripts/imgtool.py sign \
--key mykey.pem \
--header-size 0x200 \
--align 8 \
--version 1.2 \
--slot-size 0x8000 \
./
# Add the key file path to the KConfig https://docs.zephyrproject.org/latest/build/kconfig/setting.html
echo "
# Set the key file
CONFIG_BOOT_SIGNATURE_KEY_FILE=public.pem" >> "./zephyr/boards/st/nucleo_g431rb/nucleo_g431rb_defconfig"
west build -p always -b nucleo_g431rb bootloader/mcuboot/boot/zephyr -d build/mcuboot -- -DEXTRA_CONF_FILE=mcuboot-nucleo-g431rb.conf
west flash -d build/mcuboot --runner pyocd # (as root, with nix develop)
cd zephyr
# Package 1
west build -p always -b nucleo_g431rb samples/basic/blinky -d build/app -- -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y
west flash -d build/app --runner pyocd # (as root, with nix develop)
# Package 2
west build -p always -b nucleo_g431rb samples/basic/blinkyslow -d build/blinkyslow -- -DCONFIG_BOOTLOADER_MCUBOOT=y -DCONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y
pyocd flash --target stm32g431rbtx --base-address 0x08014800 build/blinkyslow/zephyr/zephyr.signed.hex
```