pub struct BootLoader<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> { /* private fields */ }Expand description
BootLoader works with any flash implementing embedded_storage.
Implementations§
Source§impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, STATE>
impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, STATE>
Sourcepub fn new(config: BootLoaderConfig<ACTIVE, DFU, STATE>) -> Self
pub fn new(config: BootLoaderConfig<ACTIVE, DFU, STATE>) -> Self
Create a new instance of a bootloader with the flash partitions.
- All partitions must be aligned with the PAGE_SIZE const generic parameter.
- The dfu partition must be at least PAGE_SIZE bigger than the active partition.
Sourcepub fn verify_update<D: Digest, V: VerifyingKey>(
&mut self,
aligned_buf: &mut [u8],
signature_buf: &mut [u8],
public_key: &[u8],
update_len: u32,
signature_offset: u32,
) -> Result<State, BootError>
pub fn verify_update<D: Digest, V: VerifyingKey>( &mut self, aligned_buf: &mut [u8], signature_buf: &mut [u8], public_key: &[u8], update_len: u32, signature_offset: u32, ) -> Result<State, BootError>
Verify the update in the DFU partition without copying either image.
On Swap with zero copy progress, verify the signature at signature_offset
over the digest of DFU bytes 0..update_len.
An invalid signature records and returns Revert. Other states and swaps
with recorded progress are left unchanged. Flash errors are returned.
Call this before Self::prepare_boot on every boot; successful
verification is not recorded separately from swap progress.
The signature_buf is used to hold the signature, and should be of exactly the same
length as the signature from the provided algorithm.
Furthermore it should satisfy the flashes buffer alignment requirements.
The signature at signature_offset must be readable from DFU.
aligned_buf must satisfy Self::read_state’s buffer requirements and
the hashing requirements.
Sourcepub fn prepare_boot(
&mut self,
aligned_buf: &mut [u8],
) -> Result<State, BootError>
pub fn prepare_boot( &mut self, aligned_buf: &mut [u8], ) -> Result<State, BootError>
Perform necessary boot preparations like swapping images.
The DFU partition is assumed to be 1 page bigger than the active partition for the swap algorithm to work correctly.
The provided aligned_buf argument must satisfy any alignment requirements given by the partition flashes. All flash operations will use this buffer.
§SWAPPING
Assume a flash size of 3 pages for the active partition, and 4 pages for the DFU partition.
The swap index contains the copy progress, as to allow continuation of the copy process on
power failure. The index counter is represented within 1 or more pages (depending on total
flash size), where a page X is considered swapped if index at location (X + WRITE_SIZE)
contains a zero value. This ensures that index updates can be performed atomically and
avoid a situation where the wrong index value is set (page write size is “atomic”).
| Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|---|---|---|---|---|---|
| Active | 0 | 1 | 2 | 3 | - |
| DFU | 0 | 4 | 5 | 6 | X |
The algorithm starts by copying ‘backwards’, and after the first step, the layout is as follows:
| Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|---|---|---|---|---|---|
| Active | 1 | 1 | 2 | 6 | - |
| DFU | 1 | 4 | 5 | 6 | 3 |
The next iteration performs the same steps
| Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|---|---|---|---|---|---|
| Active | 2 | 1 | 5 | 6 | - |
| DFU | 2 | 4 | 5 | 2 | 3 |
And again until we’re done
| Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
|---|---|---|---|---|---|
| Active | 3 | 4 | 5 | 6 | - |
| DFU | 3 | 4 | 1 | 2 | 3 |
§REVERTING
The reverting algorithm uses the swap index to discover that images were swapped, but that the application failed to mark the boot successful. In this case, the revert algorithm will run.
The revert index is located separately from the swap index, to ensure that revert can continue on power failure.
The revert algorithm works forwards, by starting copying into the ‘unused’ DFU page at the start.
| Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|---|---|---|---|---|---|
| Active | 3 | 1 | 5 | 6 | - |
| DFU | 3 | 4 | 1 | 2 | 3 |
| Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|---|---|---|---|---|---|
| Active | 3 | 1 | 2 | 6 | - |
| DFU | 3 | 4 | 5 | 2 | 3 |
| Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
|---|---|---|---|---|---|
| Active | 3 | 1 | 2 | 3 | - |
| DFU | 3 | 4 | 5 | 6 | 3 |