Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Hooks to support choosing image to boot in runtime #2161

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

edersondisouza
Copy link
Contributor

[An alternative to https://github.com//pull/2044]

In order to allow an MCUBoot user to have more control on where to get image to boot - eventually bypassing all of MCUBoot compare and swap mechanism - but still preserving integrity (and other) checks provided by MCUBoot, this PR introduces a few hooks that an application can implement to achieve such control.

The main hooks introduced allow one to modify boot_go - the method that effectively selects an image to boot and some methods related to Flash Area ID/Device ID - so that applications are no constrained to statically defined flash partitions, but have some runtime leeway - enabling, for instance, images to decide which flash partition is going to be used based on GPIO state.

New configurations are used to enable these hooks, so they can be enabled independently from currently available hooks.

This PR also provides a sample of how those hooks could be used.

Finally, there are some patches exposing "RAM loading" functions so they can be used by an external module - while not strictly needed on this PR, they are used in the sample. If deemed better, I can extract those patches to another PR.

As always, comments and suggestions on how to better achieve this are highly appreciated =D

Copy link
Collaborator

@nordicjm nordicjm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits. in the sample with styling, other than that looks good

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

if (NOT DEFINED FROM_WHO)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (NOT DEFINED FROM_WHO)
if(NOT DEFINED FROM_WHO)

Comment on lines 2 to 4
chosen {
zephyr,code-partition = &slot1_partition;
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tab indents for dts

Comment on lines +2 to +3

CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will be the default so can be dropped

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... got this when removed this line:

CMake Warning at /home/ederson/work/zephyr/zephyr-west/zephyr/cmake/mcuboot.cmake:28 (message):
  Neither CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE or
  CONFIG_MCUBOOT_SIGNATURE_KEY_FILE are set, the generated build will not be
  bootable by MCUboot unless it is signed manually/externally.

So I kept it.

{
printk("Hello World from %s on %s, slot %s!\n",
MCUBOOT_HELLO_WORLD_FROM, CONFIG_BOARD,
DT_PROP(DT_CHOSEN(zephyr_code_partition), label));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tab for main indent then spaces to align

@@ -0,0 +1,15 @@
/*
* Copyright (c) 2017 Linaro, Ltd.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might want to update copyright


fih_ret boot_go_hook(struct boot_rsp *rsp)
{
int rc;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tabs

}

int flash_area_id_from_multi_image_slot_hook(int image_index, int slot,
int *area_id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

align to int image_index

@@ -0,0 +1,8 @@
CONFIG_FLASH_RUNTIME_SOURCES=y
CONFIG_SINGLE_APPLICATION_SLOT=y
CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs a sample.yml file so that twister will build this

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nordicjm
Copy link
Collaborator

rebase will fix the CI error too

@nordicjm nordicjm requested a review from d3zd3z December 30, 2024 07:43
Add `boot_get_loader_state()` to allow one have a reference to current
bootloader state. While this state is internal - and struct is opaque -
it will be important to be able to "pass it around" when using hooks
that will be introduced in future patches.

While at it, make Zephyr single loader also expose it.

Signed-off-by: Ederson de Souza <[email protected]>
RAM loading methods are currently private, which prevents external
modules with hooks from using them. This patch makes them public.

An interesting note is that a new method,
`boot_load_image_from_flash_to_sram()`, is added so that code can
actually set the image to be loaded - currently, that is inferred from
current boot loader state, but external code can't directly access
members of relevant `struct boot_loader_state`.

Signed-off-by: Ederson de Souza <[email protected]>
This new hook allows external modules to override the choice of which
image to boot - it can be used, for instance, to load an image based on
some GPIO state.

If the hook returns FIH_BOOT_HOOK_REGULAR, then normal platform
boot_go() will be run to choose image to boot.

This hook is shielded by a different configuration than other hooks -
MCUBOOT_BOOT_GO_HOOKS, so that it can be enabled independently from
other available hooks.

Support for this new hook was added to Zephyr port.

Signed-off-by: Ederson de Souza <[email protected]>
For users that customise (for instance, via boot_go() hook) from where
images are being loaded from, having those hardcoded to
`slot_partitionX` (when using Zephyr) can be problematic. New hooks,
`flash_area_id_from_multi_image_slot_hook` and
`flash_area_get_device_id_hook` allow some customisation around these
processes.

Support for these hooks is shielded by a different configuration than
other hooks - MCUBOOT_FLASH_AREA_HOOKS, so that it can be enabled
independently from other available hooks.

Support for this new hook was added to the Zephyr port.

Signed-off-by: Ederson de Souza <[email protected]>
A sample for runtime chose image on FRDM K64F. It provides implementation
for boot_go and flash area id related hooks, showing how an external
module implementing hooks can influence which images end up being booted
on the platform.

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 <[email protected]>
Signed-off-by: Tom Burdick <[email protected]>
This sample has two parts: hooks for an mcuboot instance and a target
application. For the first, a new entry at boot/zephyr/sample.yaml is
added as well as a corresponding change at boot/zephyr/CMakeLists.txt to
include the hook as a module. For the second, added a sample.yaml as
well as invoke it from the github workflow.

Signed-off-by: Ederson de Souza <[email protected]>
@edersondisouza
Copy link
Contributor Author

v2:

  • Fixed style issues;
  • Made sample build-able by twister.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: core Affects core functionality area: zephyr Affects the Zephyr port
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants