Skip to content

Commit

Permalink
samples: Add a sample for runtime chosen image
Browse files Browse the repository at this point in the history
A sample for runtime chose image on FRDM K64F. It provides implementation
for Zephyr flash_area_open_custom(), so the right flash map
implementation is used, and MCUboot flash_map_id_get_next() and
flash_map_id_get_current() to prioritize sources. It should show what is
expected from an application to be able to use non-flash sources for
images.

In this sample, one can influence from which slot image will be loaded
by pressing a button on the board.

For more details on how to build and test the samples, check the
provided README.md.

Signed-off-by: Ederson de Souza <ederson.desouza@intel.com>
  • Loading branch information
edersondisouza committed Aug 27, 2024
1 parent e997c81 commit 3a54cbc
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 0 deletions.
6 changes: 6 additions & 0 deletions boot/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,12 @@ if(CONFIG_BOOT_MAX_IMG_SECTORS_AUTO)
endif()
endif()

if(BUILD_RUNTIME_SOURCE_SAMPLE)
zephyr_library_sources(
${MCUBOOT_DIR}/samples/runtime-source/zephyr/flash_map_dispatcher.c
)
endif()

if(SYSBUILD)
if(CONFIG_SINGLE_APPLICATION_SLOT OR CONFIG_BOOT_FIRMWARE_LOADER OR CONFIG_BOOT_SWAP_USING_SCRATCH OR CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_UPGRADE_ONLY OR CONFIG_BOOT_DIRECT_XIP OR CONFIG_BOOT_RAM_LOAD)
# TODO: RAM LOAD support
Expand Down
11 changes: 11 additions & 0 deletions boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,17 @@ config FLASH_RUNTIME_SOURCES
and `flash_map_id_get_next` functions to tell mcuboot where to find
the images.

if FLASH_MAP_CUSTOM_SOURCES
config AARDVARK_I2C_FLASH
bool "Use aardvark to emulate an I2C device from where a firmware image is read"
default n
depends on I2C
help
If you have an I2C device that acts as a flash memory, you can enable this
option to read the firmware image from it.

endif

config BOOT_ENCRYPTION_SUPPORT
bool
help
Expand Down
4 changes: 4 additions & 0 deletions boot/zephyr/flash_map_extended.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include <flash_map_backend/flash_map_backend.h>
#include <sysflash/sysflash.h>

#if defined(CONFIG_FLASH_RUNTIME_SOURCES)
#include <flash_runtime_sources.h>
#endif

#include "bootutil/bootutil_log.h"

BOOT_LOG_MODULE_DECLARE(mcuboot);
Expand Down
56 changes: 56 additions & 0 deletions samples/runtime-source/zephyr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Runtime chosen image sample application

This sample demonstrates how to use a non flash storage to retrieve the image
being booted. It was tested on a FRDM K64F. Both slots are used to store two
different images. The image to be booted is selected based on a button press.

## Build

Build mcuboot. First, ensure ZEPHYR_SDK_INSTALL_DIR is defined. From the
mcuboot directory, run the following commands:

```
source <path-to-zephyr>/zephyr-env.sh
west build -p -b frdm_k64f boot/zephyr/ -- -DBUILD_RUNTIME_SOURCE_SAMPLE=1 \
-DEXTRA_CONF_FILE="../../samples/runtime-source/zephyr/sample.conf"
-DEXTRA_DTC_OVERLAY_FILE=../../samples/runtime-source/zephyr/boards/frdm_k64f.overlay
west build -t flash
```

Then, build the sample application to be loaded. We need to build it twice, one
for each slot. From the sample
app directory (mcuboot/samples/non-flash-source/zephyr/app), run:

```
west build -p -b frdm_k64f .
west flash
```

Then change the overlay file to use the second slot. For instance, open
`boards/frdm_k64f.overlay` and change the line:

```
zephyr,code-partition = &slot0_partition;
```

to:

```
zephyr,code-partition = &slot1_partition;
```

And build and flash again:

```
west build -b frdm_k64f .
west flash
```

## Run

Open a serial terminal to see the output and reset the board. It shall boot the
image on slot0 by default. By keeping the SW2 button pressed during reset, the
bootloader will randomly select the image to be booted.
14 changes: 14 additions & 0 deletions samples/runtime-source/zephyr/app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(non_flash_backend_app)

if (NOT DEFINED FROM_WHO)
set(FROM_WHO Zephyr)
endif()

target_compile_definitions(app PRIVATE "-DMCUBOOT_HELLO_WORLD_FROM=\"${FROM_WHO}\"")

target_sources(app PRIVATE src/main.c)
5 changes: 5 additions & 0 deletions samples/runtime-source/zephyr/app/boards/frdm_k64f.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/ {
chosen {
zephyr,code-partition = &slot0_partition;
};
};
3 changes: 3 additions & 0 deletions samples/runtime-source/zephyr/app/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CONFIG_BOOTLOADER_MCUBOOT=y

CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem"
15 changes: 15 additions & 0 deletions samples/runtime-source/zephyr/app/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright (c) 2017 Linaro, Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

int main(void)
{
printk("Hello World from %s on %s, slot %s!\n",
MCUBOOT_HELLO_WORLD_FROM, CONFIG_BOARD,
DT_PROP(DT_CHOSEN(zephyr_code_partition), label));
}
60 changes: 60 additions & 0 deletions samples/runtime-source/zephyr/flash_map_dispatcher.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2024 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <flash_map_backend/flash_map_backend.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
#include <zephyr/random/random.h>

#define SW1_NODE DT_ALIAS(sw1)
#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
static struct gpio_dt_spec sw1_spec = GPIO_DT_SPEC_GET(SW1_NODE, gpios);
#endif

static int curr_idx = -1;

static uint8_t known_ids[] = {
FIXED_PARTITION_ID(slot0_partition),
FIXED_PARTITION_ID(slot1_partition),
};

bool
flash_map_id_get_next(uint8_t *id, bool reset)
{
if (reset) {
curr_idx = 0;
#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
if (gpio_pin_configure_dt(&sw1_spec, GPIO_INPUT) == 0) {
if (gpio_pin_get_dt(&sw1_spec) == 1) {
curr_idx = sys_rand8_get() % ARRAY_SIZE(known_ids);
printk("Booting from curr_idx = %d\n", curr_idx);
}
}
#endif
} else {
curr_idx++;
}

if (curr_idx >= ARRAY_SIZE(known_ids)) {
return false;
}

*id = known_ids[curr_idx];

return true;
}

bool
flash_map_id_get_current(uint8_t *id)
{
if (curr_idx == -1 || curr_idx >= ARRAY_SIZE(known_ids)) {
return false;
}

*id = known_ids[curr_idx];

return true;
}
4 changes: 4 additions & 0 deletions samples/runtime-source/zephyr/sample.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CONFIG_FLASH_RUNTIME_SOURCES=y
CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
CONFIG_TEST_RANDOM_GENERATOR=y
CONFIG_ENTROPY_GENERATOR=y

0 comments on commit 3a54cbc

Please sign in to comment.