-
Notifications
You must be signed in to change notification settings - Fork 685
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] Support image sources other than flash #2031
Conversation
RAM loading code is currently under bootutil/loader.c, and it's not accessible for different loaders, such as the single loaders. Future patches will make use of the RAM loading code outside the bootutil/loader.c context, and this patch prepares for that by making it standalone on boot/bootutil/src/ram_load.c Signed-off-by: Ederson de Souza <[email protected]>
Now that RAM load code is not dependent on bootutil/loader.c, it can be used independently of !SINGLE_APPLICATION_SLOT configurations. Move the related Kconfigs accordingly, so that applications configured to use single loader can do RAM loading. Signed-off-by: Ederson de Souza <[email protected]>
MCUboot assumes that the images being booted live on a flash (or will be loaded to it, in case of serial support). However, some devices may end up loading an image from a different source, such as an I2C/eSPI storage, using some appropriate protocol. In these cases, usually the image is then loaded directly to RAM. This patch adds support for such scenarios, currently only on Zephyr port. It expects Zephyr CONFIG_FLASH_MAP_CUSTOM_BACKEND is used to provide Flash Map API to access the image in the non-flash device (but doesn't mandate it). This allows for an integration that is less intrusive on MCUboot code. It uses single loader to load an image from a set of "sources". The single loader loops through available sources and the first one to succeed signature/validation boots. To access the images, weak functions flash_map_id_get_next() and flash_map_id_get_current() are used. Default implementation keeps current behaviour for single loader, i.e. just loads from FLASH_AREA_IMAGE_PRIMARY(0). It is expected applications will reimplement these functions, allowing them to define a priority of different sources. As these different storage media may be ready only, MCUboot won't attempt to update them to record last source to succeed or so, it's application responsibility to define the correct priority of sources on every boot. Signed-off-by: Ederson de Souza <[email protected]>
A sample for non-flash-source on MEC17 EVB. 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. For the I2C device simulation, an Aardvark I2C host adapter is needed, and a script is provided to make the image loadable via I2C. An implementation for an "Aardvark driver" on top of I2C is also provided. Finally, a sample application to be loaded is also available. For more details on how to build and test the samples, check the provided README.md. Signed-off-by: Ederson de Souza <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just do a proper Zephyr Flash Driver for this thing and use Flash API with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is an example, in sdk-nrf, how virtual flash driver to transport data over IPC is implemented: nrfconnect/sdk-nrf#13917 . Device with such definition can easily be assigned partitions or directly used with Flash API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it - did a test locally, and things were simple enough. Thanks for the input!
Guess this RFC has two parts: one about loading from non-flash sources and another about being able to chose the image to run in runtime. The first part can be dropped following @de-nordic comments, but the second use case still makes sense. I guess I'll go with a new RFC for the second part, as there was a lot related to the first part on this one. |
Sure, I was only commenting on the Flash part. I do not know how you plan to implement the drivers, but consider using DTS phandles to point to other devices as one of possible solutions.
|
MCUboot assumes that the images being booted live on a flash (or will be loaded to it, in case of serial support). However, some devices may end up loading an image from a different source, such as an I2C/eSPI storage, using some appropriate protocol. In these cases, usually the image is then loaded directly to RAM.
This PR adds support for such scenarios, currently only on Zephyr port. It expects Zephyr CONFIG_FLASH_MAP_CUSTOM_BACKEND is used to provide Flash Map API to access the image in the non-flash device (but doesn't mandate it). This allows for an integration that is less intrusive on MCUboot code.
It uses single loader to load an image from a set of "sources". The single loader loops through available sources and the first one to succeed signature/validation boots. To access the images, weak functions flash_map_id_get_next() and flash_map_id_get_current() are used. Default implementation keeps current behaviour for single loader, i.e. just loads from FLASH_AREA_IMAGE_PRIMARY(0).
It is expected applications will reimplement these functions, allowing them to define a priority of different sources. As these different storage media may be ready only, MCUboot won't attempt to update them to record last source to succeed or so, it's application responsibility to define the correct priority of sources on every boot.
This PR also moves RAM loading code to its own file, so it's available for single loaders, as well as provide one example of such device, using I2C and Aardvark.
Note that this approach of "pretending devices are all flash" was chosen because I believe it's simpler to integrate. An alternative approach would be to rename all
flash_*
API to something likestorage_
, and have the current flash be an implementation of that. Not sure this path would be viable, as using and expecting flash idiosyncrasies is widespread on MCUboot code.Please review - comments and suggestions on how to better achieve this are highly appreciated =D
Note that this patch depends on zephyrproject-rtos/zephyr#76856. Still a draft, and suggestions here and there will probably reshape this proposal a bit.