refactor(boot): move page erase index out of state

This commit is contained in:
Badr Bouslikhin 2024-02-12 23:24:21 +01:00
parent 333b2afe6d
commit 56e6b6bee6
No known key found for this signature in database
GPG Key ID: 3B081233DD4DE99B
2 changed files with 10 additions and 18 deletions

View File

@ -13,6 +13,7 @@ use crate::{FirmwareUpdaterError, State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERA
pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> {
dfu: DFU, dfu: DFU,
state: FirmwareState<'d, STATE>, state: FirmwareState<'d, STATE>,
last_erased_dfu_page_index: Option<usize>,
} }
#[cfg(target_os = "none")] #[cfg(target_os = "none")]
@ -56,6 +57,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
Self { Self {
dfu: config.dfu, dfu: config.dfu,
state: FirmwareState::new(config.state, aligned), state: FirmwareState::new(config.state, aligned),
last_erased_dfu_page_index: None,
} }
} }
@ -72,7 +74,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
/// proceed with updating the firmware as it must be signed with a /// proceed with updating the firmware as it must be signed with a
/// corresponding private key (otherwise it could be malicious firmware). /// corresponding private key (otherwise it could be malicious firmware).
/// ///
/// Mark to trigger firmware swap on next boot if verify suceeds. /// Mark to trigger firmware swap on next boot if verify succeeds.
/// ///
/// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have
/// been generated from a SHA-512 digest of the firmware bytes. /// been generated from a SHA-512 digest of the firmware bytes.
@ -213,14 +215,13 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
let sector_end = sector_start + DFU::ERASE_SIZE; let sector_end = sector_start + DFU::ERASE_SIZE;
// Determine if the current sector needs to be erased before writing. // Determine if the current sector needs to be erased before writing.
let need_erase = self let need_erase = self
.state
.last_erased_dfu_page_index .last_erased_dfu_page_index
.map_or(true, |last_erased_sector| current_sector != last_erased_sector); .map_or(true, |last_erased_sector| current_sector != last_erased_sector);
// If the sector needs to be erased, erase it and update the last erased sector index. // If the sector needs to be erased, erase it and update the last erased sector index.
if need_erase { if need_erase {
self.dfu.erase(sector_start as u32, sector_end as u32).await?; self.dfu.erase(sector_start as u32, sector_end as u32).await?;
self.state.last_erased_dfu_page_index = Some(current_sector); self.last_erased_dfu_page_index = Some(current_sector);
} }
// Calculate the size of the data chunk that can be written in the current iteration. // Calculate the size of the data chunk that can be written in the current iteration.
@ -258,7 +259,6 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> {
pub struct FirmwareState<'d, STATE> { pub struct FirmwareState<'d, STATE> {
state: STATE, state: STATE,
aligned: &'d mut [u8], aligned: &'d mut [u8],
last_erased_dfu_page_index: Option<usize>,
} }
impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> { impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> {
@ -280,11 +280,7 @@ impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> {
/// and follow the alignment rules for the flash being read from and written to. /// and follow the alignment rules for the flash being read from and written to.
pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self { pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self {
assert_eq!(aligned.len(), STATE::WRITE_SIZE.max(STATE::READ_SIZE)); assert_eq!(aligned.len(), STATE::WRITE_SIZE.max(STATE::READ_SIZE));
Self { Self { state, aligned }
state,
aligned,
last_erased_dfu_page_index: None,
}
} }
// Make sure we are running a booted firmware to avoid reverting to a bad state. // Make sure we are running a booted firmware to avoid reverting to a bad state.

View File

@ -13,6 +13,7 @@ use crate::{FirmwareUpdaterError, State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERA
pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> {
dfu: DFU, dfu: DFU,
state: BlockingFirmwareState<'d, STATE>, state: BlockingFirmwareState<'d, STATE>,
last_erased_dfu_page_index: Option<usize>,
} }
#[cfg(target_os = "none")] #[cfg(target_os = "none")]
@ -91,6 +92,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
Self { Self {
dfu: config.dfu, dfu: config.dfu,
state: BlockingFirmwareState::new(config.state, aligned), state: BlockingFirmwareState::new(config.state, aligned),
last_erased_dfu_page_index: None,
} }
} }
@ -107,7 +109,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
/// proceed with updating the firmware as it must be signed with a /// proceed with updating the firmware as it must be signed with a
/// corresponding private key (otherwise it could be malicious firmware). /// corresponding private key (otherwise it could be malicious firmware).
/// ///
/// Mark to trigger firmware swap on next boot if verify suceeds. /// Mark to trigger firmware swap on next boot if verify succeeds.
/// ///
/// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have
/// been generated from a SHA-512 digest of the firmware bytes. /// been generated from a SHA-512 digest of the firmware bytes.
@ -248,14 +250,13 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
let sector_end = sector_start + DFU::ERASE_SIZE; let sector_end = sector_start + DFU::ERASE_SIZE;
// Determine if the current sector needs to be erased before writing. // Determine if the current sector needs to be erased before writing.
let need_erase = self let need_erase = self
.state
.last_erased_dfu_page_index .last_erased_dfu_page_index
.map_or(true, |last_erased_sector| current_sector != last_erased_sector); .map_or(true, |last_erased_sector| current_sector != last_erased_sector);
// If the sector needs to be erased, erase it and update the last erased sector index. // If the sector needs to be erased, erase it and update the last erased sector index.
if need_erase { if need_erase {
self.dfu.erase(sector_start as u32, sector_end as u32)?; self.dfu.erase(sector_start as u32, sector_end as u32)?;
self.state.last_erased_dfu_page_index = Some(current_sector); self.last_erased_dfu_page_index = Some(current_sector);
} }
// Calculate the size of the data chunk that can be written in the current iteration. // Calculate the size of the data chunk that can be written in the current iteration.
@ -293,7 +294,6 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE>
pub struct BlockingFirmwareState<'d, STATE> { pub struct BlockingFirmwareState<'d, STATE> {
state: STATE, state: STATE,
aligned: &'d mut [u8], aligned: &'d mut [u8],
last_erased_dfu_page_index: Option<usize>,
} }
impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> { impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> {
@ -315,11 +315,7 @@ impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> {
/// and written to. /// and written to.
pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self { pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self {
assert_eq!(aligned.len(), STATE::WRITE_SIZE); assert_eq!(aligned.len(), STATE::WRITE_SIZE);
Self { Self { state, aligned }
state,
aligned,
last_erased_dfu_page_index: None,
}
} }
// Make sure we are running a booted firmware to avoid reverting to a bad state. // Make sure we are running a booted firmware to avoid reverting to a bad state.