-
Notifications
You must be signed in to change notification settings - Fork 2.1k
sys/riotboot: riotboot header v2 #21825
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
base: master
Are you sure you want to change the base?
Conversation
|
I first wanted that the |
crasbe
left a comment
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 some preliminary high-level styling related comments. The static test also has some warnings left.
core/lib/init.c
Outdated
| #include "stdio_base.h" | ||
|
|
||
| #if IS_USED(MODULE_RIOTBOOT) | ||
| #include "riotboot/wdt.h" |
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.
| #include "riotboot/wdt.h" | |
| # include "riotboot/wdt.h" |
| #if defined(MODULE_RIOTBOOT_HDR_V2) | ||
| #define RIOTBOOT_MAGIC RIOTBOOT_MAGIC_V2 | ||
| #else | ||
| #define RIOTBOOT_MAGIC RIOTBOOT_MAGIC_V1 | ||
| #endif |
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.
| #if defined(MODULE_RIOTBOOT_HDR_V2) | |
| #define RIOTBOOT_MAGIC RIOTBOOT_MAGIC_V2 | |
| #else | |
| #define RIOTBOOT_MAGIC RIOTBOOT_MAGIC_V1 | |
| #endif | |
| #if defined(MODULE_RIOTBOOT_HDR_V2) | |
| # define RIOTBOOT_MAGIC RIOTBOOT_MAGIC_V2 | |
| #else | |
| # define RIOTBOOT_MAGIC RIOTBOOT_MAGIC_V1 | |
| #endif |
| #ifndef CONFIG_RIOTBOOT_MAX_ATTEMPTS | ||
| #define CONFIG_RIOTBOOT_MAX_ATTEMPTS 3u | ||
| #endif |
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.
| #ifndef CONFIG_RIOTBOOT_MAX_ATTEMPTS | |
| #define CONFIG_RIOTBOOT_MAX_ATTEMPTS 3u | |
| #endif | |
| #ifndef CONFIG_RIOTBOOT_MAX_ATTEMPTS | |
| # define CONFIG_RIOTBOOT_MAX_ATTEMPTS 3u | |
| #endif |
sys/include/riotboot/wdt.h
Outdated
| * The timeout is doubled on each unsuccessful attempt. | ||
| */ | ||
| #ifndef CONFIG_RIOTBOOT_WDT_TIMEOUT_MSEC | ||
| #define CONFIG_RIOTBOOT_WDT_TIMEOUT_MSEC 4000 |
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.
| #define CONFIG_RIOTBOOT_WDT_TIMEOUT_MSEC 4000 | |
| # define CONFIG_RIOTBOOT_WDT_TIMEOUT_MSEC 4000 |
sys/riotboot/hdr.c
Outdated
| switch (riotboot_hdr->v1.magic_number) { | ||
| case RIOTBOOT_MAGIC_V1: | ||
| return &riotboot_hdr->v1.version; | ||
| case RIOTBOOT_MAGIC_V2: | ||
| return &riotboot_hdr->v2.version; | ||
| default: | ||
| return NULL; |
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.
| switch (riotboot_hdr->v1.magic_number) { | |
| case RIOTBOOT_MAGIC_V1: | |
| return &riotboot_hdr->v1.version; | |
| case RIOTBOOT_MAGIC_V2: | |
| return &riotboot_hdr->v2.version; | |
| default: | |
| return NULL; | |
| switch (riotboot_hdr->v1.magic_number) { | |
| case RIOTBOOT_MAGIC_V1: | |
| return &riotboot_hdr->v1.version; | |
| case RIOTBOOT_MAGIC_V2: | |
| return &riotboot_hdr->v2.version; | |
| default: | |
| return NULL; |
As per our Coding Convention: https://github.com/RIOT-OS/RIOT/blob/master/CODING_CONVENTIONS.md#indentation-and-braces
sys/riotboot/hdr.c
Outdated
| case RIOTBOOT_MAGIC_V1: | ||
| return &riotboot_hdr->v1.start_addr; | ||
| case RIOTBOOT_MAGIC_V2: | ||
| return &riotboot_hdr->v2.start_addr; | ||
| default: | ||
| return NULL; |
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.
| case RIOTBOOT_MAGIC_V1: | |
| return &riotboot_hdr->v1.start_addr; | |
| case RIOTBOOT_MAGIC_V2: | |
| return &riotboot_hdr->v2.start_addr; | |
| default: | |
| return NULL; | |
| case RIOTBOOT_MAGIC_V1: | |
| return &riotboot_hdr->v1.start_addr; | |
| case RIOTBOOT_MAGIC_V2: | |
| return &riotboot_hdr->v2.start_addr; | |
| default: | |
| return NULL; |
sys/riotboot/hdr.c
Outdated
| case RIOTBOOT_MAGIC_V1: | ||
| return &riotboot_hdr->v1.chksum; | ||
| case RIOTBOOT_MAGIC_V2: | ||
| return &riotboot_hdr->v2.chksum; | ||
| default: | ||
| return NULL; |
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.
| case RIOTBOOT_MAGIC_V1: | |
| return &riotboot_hdr->v1.chksum; | |
| case RIOTBOOT_MAGIC_V2: | |
| return &riotboot_hdr->v2.chksum; | |
| default: | |
| return NULL; | |
| case RIOTBOOT_MAGIC_V1: | |
| return &riotboot_hdr->v1.chksum; | |
| case RIOTBOOT_MAGIC_V2: | |
| return &riotboot_hdr->v2.chksum; | |
| default: | |
| return NULL; |
sys/include/riotboot/hdr.h
Outdated
| uint32_t riotboot_hdr_get_flags(const riotboot_hdr_t *riotboot_hdr); | ||
|
|
||
| /** | ||
| * @brief Calculate header checksum |
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.
| * @brief Calculate header checksum | |
| * @brief Getter for the header checksum |
If I understand the code correctly, it does not calculate the checksum when calling this function, right?
|
Are the riotboot images somehow compatible with the SUIT ecosystem? If not, wouldn't it make sense to converge towards that instead of introducing yet another custom format? |
|
What contradiction do you see in SUIT? From a SUIT perspective there is only binary payload. |
|
Disclaimer: I haven't looked much into SUIT. But from my understanding, your proposed riotboot header includes metadata information about the image, that I would have expected in a SUIT manifest such as https://datatracker.ietf.org/doc/draft-ietf-suit-manifest/. But it can well be that that metadata is disjoint from what would be carried in a SUIT manifest, in that case please just disregard my comment. |
|
SUIT manifest can only hold static info about the image because it is used only during installation as far as I know. This PR adds flags which change after an installation |
dbcdc7e to
904e0cc
Compare
904e0cc to
bf983c9
Compare
Contribution description
Introducing
riotboot_hdr_v2.We want to test boot an image and have an automatic revert to a previous image if a new image fails to boot.
For example due to an unexpected endless loop or compromised firmware or kernel panic.
This adds a flags field to the header to encode an image state and a number of boot attempts.
The watchdog is started in the bootloader. An image has to confirm that it booted successfully to not be labeled as
DISMISSEDby the bootloader.Testing procedure
I test with: #21565 because this is just more convenient for me.
Run the SUIT example.
Run the SUIT coap server.
Flash with new header and watchdog timer
Auto Image Activation
riotboot_hdr_v2 + riotboot_wdt
Note that the image state is confirmed to boot.
Compile and push an update using riotboot_hdr_v2 + riotboot_wdt.
Fetch the update.
Check that the otehr slot is booted and the image state is "confirmed" and it booted after 1 attempts.
No Automatic Image Activation
Flash
Push update
Fetch update
Note after reboot it has booted slot 0 again because slot 1 is not activated.
Activate slot 1:
Reboot and it will boot slot 1:
Auto Revert
Flash riotboot_hdr_v2 + riotboot_wdt
Modify the firmware and include a
panic()before the image is confirmed.Push bad image update with
DEVELHELP=0to get#define CONFIG_CORE_REBOOT_ON_PANIC (1)Fetch manifest and observe that after 3 reboots the old image is successfully booted and the other image is dismissed.
Issues/PRs references