-
Notifications
You must be signed in to change notification settings - Fork 742
boot: bootutil: swap-move: Allow trailer area not be a multiple of the sector size #2247
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: main
Are you sure you want to change the base?
boot: bootutil: swap-move: Allow trailer area not be a multiple of the sector size #2247
Conversation
This routine will now also be useful for the swap-move strategy. The trailer size is removed from the list of parameters as it can be easily obtained using the 'state' parameter and it will be more convenient, for the swap-move strategy, not to have to compute it manually before calling 'boot_get_first_trailer_sector'. Signed-off-by: Thomas Altenbach <[email protected]>
The swap-move strategy is currently assuming the trailer is stored in dedicated sector, meaning the size of the area allocated to the trailer must be a multiple of the sector size. This commit relaxes this assumption when moving sectors up in the primary slot by allowing the last sector containing firmware data to also hold part of the trailer (or the whole trailer if it is small enough). Signed-off-by: Thomas Altenbach <[email protected]>
When using the swap-move strategy, the secondary trailer was erased just after the primary trailer, when moving the sectors up in the primary slot. This was working because it was assumed the trailer is stored in dedicated sectors, so no sector could contain both trailer and firmware data. However, if this assumption is relaxed, it means it is no more possible to erase the secondary trailer before the last sector holding firmware data has been copied to the primary slot, since that sector might also contain trailer data. So the erasure of the secondary trailer has to occur at the time the last sector containing firmware data is swapped. Signed-off-by: Thomas Altenbach <[email protected]>
When using the swap-move strategy, at the very beginning of the revert process, the secondary trailer was rewritten to make the revert look like a permanent upgrade in case an unfortunate reset occurs when rewriting the primary trailer. This was possible because the assumption was that no sector contained both part of the firmware and part of the trailer. To relax this assumption, it is necessary to avoid having to rewrite the secondary trailer at the start of the revert process, since that could also erase firmware data. The solution chosen is to rewrite the secondary trailer at the end of the upgrade process, just after that trailer is erased and to take advantage of the unused 'copy_done' flag in the secondary trailer to indicate that an upgrade has been performed and that a revert has to be started or resumed if the primary image is not confirmed. Signed-off-by: Thomas Altenbach <[email protected]>
This check is not useful because it is already done during the validation of the image and was also making sure there was no firmware data in the first trailer sector, which is no more needed. Signed-off-by: Thomas Altenbach <[email protected]>
This commit updates the computation of the maximum firmware image size for the swap-move strategy to allow the first sector containing part of the trailer to also hold firmware data. This means it is no more necessary to allocate a sector-aligned area for the trailer when using swap-move, the area to allocate is now simply equal to the maximum trailer size. Signed-off-by: Thomas Altenbach <[email protected]>
For swap-move and swap-offset strategies, the size of the images used for running the tests was hardcoded and was smaller than the maximum possible size. This was done this way because the logic used to compute the maximum image size was not taking into account the padding that is needed when using those strategies. This commit fixes the issue, making now possible to run the tests with images having the maximum possible size. Signed-off-by: Thomas Altenbach <[email protected]>
When using the swap-move strategy, the simulator now doesn't compute anymore the maximum image size so the area allocated to the trailer has a size that is a multiple of the sector size. Indeed, the swap-move strategy now supports having part of the firmware in the first sector holding trailer data, allowing larger images. Signed-off-by: Thomas Altenbach <[email protected]>
When swap-move is used, the secondary slot's trailer is no longer expected to be empty after an upgrade has been performed. Instead, the secondary slot should contain a valid trailer with only the 'copy_done' flag set. Signed-off-by: Thomas Altenbach <[email protected]>
When using the swap-move strategy, the area allocated to the trailer no more need to have a size that is a multiple of the sector size, since the area not allocated to the trailer in the first sector holding trailer data can now be used to store firmware data. Signed-off-by: Thomas Altenbach <[email protected]>
This commit updates the description of the swap tables, used to determine the type of operation to perform or resume at startup, in order to reflect the changes that were performed in the code to enable the swap-move strategy to support sectors containing both firmware and trailer data. Signed-off-by: Thomas Altenbach <[email protected]>
The swap-move strategy now support having firmware data in the first sector holding trailer data. This commit adds a release note snippet regarding this change. Signed-off-by: Thomas Altenbach <[email protected]>
The problem with this is that it introduces the inability to clear flags e.g. if a firmware update is marked for confirmation or test, once a flag is set it cannot be cleared without potentially bricking the device if power is lost during erase/re-write of that sector |
@nordicjm Have you a specific scenario in mind where there would be an issue?
Also note that the swap-scratch strategy already supports having firmware and trailer data in the same sector and this doesn't seem to cause any issue, so I don't think this should be a problem for swap-move. |
User uploads image, they mark it for test/swap (which writes the flag to the primary image, not the secondary), then they delete the secondary image without rebooting, the update image is gone, but the flag is permanently set to test/confirm |
@nordicjm Perhaps you're talking about a specific MCUboot feature I'm not aware of, but the usual flow is:
|
When using swap-move, the area allocated to the trailer has currently to be a multiple of the sector size. This is not a big deal on devices having small sectors, but on devices having a large sector size, such most STM32 MCUs, this typically means losing a significant amount of flash memory. For example, on an STM32F4 device with 128-KiB sectors, the trailer is usually only a few hundreds of bytes long but a whole 128 KiB has still to be reserved for storing the trailer and can't therefore be used for firmware data.
The idea of this PR is to relax the need of having a sector-aligned trailer area, enabling therefore to use all the bytes not needed by the trailer, in the first sector holding trailer data, to store firmware data.
To illustrate the solution, let's imagine a device having 4096-byte sectors and a primary slot composed of
N
sectors. Let's assume the trailer needs 4224 bytes. Before this MR, two entire sectors would have to be allocated to the trailer, so the layout would have been something like:With this MR, only the exact amount of bytes actually needed by the trailer have to be allocated to the trailer, so we have 3968 additional bytes available to store the firmware image:
At the beginning of an upgrade or revert process, all the sectors in the primary slot are "moved up", ending up with:
To main ideas of the solution implemented by this PR is:
The latter is the most difficult part. Indeed, at the beginning of the revert process, the secondary trailer was rewritten to make the revert look like a permanent upgrade in case an unfortunate reset occurs during the rewriting of the primary trailer. This was a clever trick, but is unfortunately no longer possible if the trailers are not stored in dedicated sectors. The solution proposed by this PR is inspired from the implementation of the swap-offset strategy, which uses the
copy_done
flag in the secondary trailer to indicate a revert process is ongoing. For the swap-move, since we cannot rewrite the trailer at the beginning of the revert process, the idea is to rewrite it at the time it is erased, at the end of the upgrade process. This means the secondary trailer is now valid after an upgrade, which required a few changes in the swap tables and in the simulator.If the improvement proposed by this MR is merged, I will try to port those changes to the swap-offset strategy, which should be quite easy, at least in theory.
Resolves #2052