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

bootutil: Add support for devices without erase #2114

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

Conversation

de-nordic
Copy link
Collaborator

@de-nordic de-nordic commented Nov 11, 2024

Commits:

  • bootutil: add support for not calling erase when device does not require it and MCUBOOT_DEV_WITHOUT_ERASE_THEN_NO_ERASE option that controls this; add MCUBOOT_MINIMAL_SCRAMBLE that allows to reduce amount of removed data, where applicable;
  • Zephyr: Kconfig options and supporting code
  • Zephyr: switch to flash_area_flatten in bs_custom_storage_erase
  • Zephyr: switch to boot_set_next, from flash_area_erase, for Zephyr builds of bootutil_public.

The first MCUboot option allows to improve life time of devices for which erase is emulated by write, and is not really required by the device design and the second MCUboot option allows to just remove enough of data, where needed, by either reduced range of erase or reduced write; for example by scrambling only image header, rather than removing the entire image.

Tested on nrf52840dk and nrf54l15. In case of nrf54l it reduces swap time by half, in comparison to code using erase.

@de-nordic de-nordic force-pushed the improve-no-erase-device-time branch 14 times, most recently from bedea40 to cf8def0 Compare November 15, 2024 12:15
The commit adds two MCUboot configuration options:
  - MCUBOOT_DEV_WITHOUT_ERASE_THEN_NO_ERASE
  - MCUBOOT_MINIMAL_SCRAMBLE

The first one should be enabled to support devices that do not require erase.
When such devices are used in system then MCUboot will avoid erasing such
device, which is not needed by hardware, and will just write data to it.
This allows to both improve device lifetime and reduce time of operations
like swap.

The second option allows to reduce amount of removed data. When enabled,
MCUboot will remove enough of data, depending on the purpose of the removal,
to just fulfill the purpose; for example if removal of data is done to
make image unrecognizable for MCUboot, with this option, it will only
remove header.

Signed-off-by: Dominik Ermel <[email protected]>
@de-nordic de-nordic marked this pull request as ready for review November 15, 2024 13:48
Add Kconfig options:
  - CONFIG_MCUBOOT_STORAGE_NO_UNNEEDED_ERASE that enables MCUboot
    configuration MCUBOOT_DEV_WITHOUT_ERASE_THEN_NO_ERASE
  - CONFIG_MCUBOOT_STORAGE_MINIMAL_SCRAMBLE that enables MCUboot
    configuration MCUBOOT_MINIMAL_SCRAMBLE

Adds implementation of flash_area_erase_required, which is required when
MCUBOOT_DEV_WITHOUT_ERASE_THEN_NO_ERASE is enabled.

Signed-off-by: Dominik Ermel <[email protected]>
The intention of bs_custom_storage_erase is to remove data from device;
to support devices that do not require erase, without calling erase,
so that devices that do not implement such functions could work,
the flash_area_erase has been replaced with flash_area_flatten.

Signed-off-by: Dominik Ermel <[email protected]>
Switch from using flash_area_erase to flash_area_flatten.
The later function uses write on devices that do not have erase by
design, to scramble data.

Signed-off-by: Dominik Ermel <[email protected]>
int boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz);
/* SImilar to boot_erase_region but will alwasy remove data */
Copy link
Collaborator

Choose a reason for hiding this comment

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

-I+i, *always

Comment on lines +1228 to +1239
uint8_t buf[BOOT_MAX_ALIGN];
size_t size_done = 0;

memset(buf, flash_area_erased_val(fa), sizeof(buf));

while (size_done < size) {
ret = flash_area_write(fa, size_done + off, buf, sizeof(buf));
if (ret != 0) {
break;
}
size_done += sizeof(buf);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

this just assumes max align will not overflow the size but makes no checks to ensure that, it should reduces buffer on final write to ensure it does not overflow

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, that was intentional as I have assumes that MCUboot should write at BOOT_MAX_ALIGN pace anyway, but maybe that should be fixed.

} else {
size = MAX(sizeof(((struct image_header *)0)->ih_magic),
BOOT_MAX_ALIGN);
size = (size + BOOT_MAX_ALIGN - 1) & ~(BOOT_MAX_ALIGN - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should do the same for footer data because it might contain swap status or mcuboot flags for swapping images and those should always be cleared

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah right, header and slot trailer are verified separately.

Comment on lines +856 to +858
The same can be achieved with just removal of header, leaving the
rest of image untouched, as without header MCUboot will not be able
to recognize image in slot as bootable.
Copy link
Collaborator

Choose a reason for hiding this comment

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

include footer

Comment on lines +551 to +553
#if !defined(CONFIG_MCUBOOT) && defined(__ZEPHYR__)
flash_area_flatten(fa, 0, flash_area_get_size(fa));
#else
Copy link
Collaborator

Choose a reason for hiding this comment

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

think it was mentioned in a previous PR that OS specific code should not be present in here

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I can fix that although MCUboot has significant problem where we are coupled with Flash Map API which means that this has to be replaced with a function that is implemented for every supported system. I will figure way around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants