diff options
| author | Badr Bouslikhin <[email protected]> | 2024-02-12 23:24:21 +0100 |
|---|---|---|
| committer | Badr Bouslikhin <[email protected]> | 2024-02-12 23:24:21 +0100 |
| commit | 56e6b6bee6bd6087b35857e8aa1a011f6e83f703 (patch) | |
| tree | 2ed1d435e2b8461a690ea7933fb98ff77a17f941 /embassy-boot/src/firmware_updater | |
| parent | 333b2afe6d5319317b2679e634c3cf242bab0e73 (diff) | |
refactor(boot): move page erase index out of state
Diffstat (limited to 'embassy-boot/src/firmware_updater')
| -rw-r--r-- | embassy-boot/src/firmware_updater/asynch.rs | 14 | ||||
| -rw-r--r-- | embassy-boot/src/firmware_updater/blocking.rs | 14 |
2 files changed, 10 insertions, 18 deletions
diff --git a/embassy-boot/src/firmware_updater/asynch.rs b/embassy-boot/src/firmware_updater/asynch.rs index d31eff005..b76668136 100644 --- a/embassy-boot/src/firmware_updater/asynch.rs +++ b/embassy-boot/src/firmware_updater/asynch.rs | |||
| @@ -13,6 +13,7 @@ use crate::{FirmwareUpdaterError, State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERA | |||
| 13 | pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { | 13 | pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { |
| 14 | dfu: DFU, | 14 | dfu: DFU, |
| 15 | state: FirmwareState<'d, STATE>, | 15 | state: FirmwareState<'d, STATE>, |
| 16 | last_erased_dfu_page_index: Option<usize>, | ||
| 16 | } | 17 | } |
| 17 | 18 | ||
| 18 | #[cfg(target_os = "none")] | 19 | #[cfg(target_os = "none")] |
| @@ -56,6 +57,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> { | |||
| 56 | Self { | 57 | Self { |
| 57 | dfu: config.dfu, | 58 | dfu: config.dfu, |
| 58 | state: FirmwareState::new(config.state, aligned), | 59 | state: FirmwareState::new(config.state, aligned), |
| 60 | last_erased_dfu_page_index: None, | ||
| 59 | } | 61 | } |
| 60 | } | 62 | } |
| 61 | 63 | ||
| @@ -72,7 +74,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> FirmwareUpdater<'d, DFU, STATE> { | |||
| 72 | /// proceed with updating the firmware as it must be signed with a | 74 | /// proceed with updating the firmware as it must be signed with a |
| 73 | /// corresponding private key (otherwise it could be malicious firmware). | 75 | /// corresponding private key (otherwise it could be malicious firmware). |
| 74 | /// | 76 | /// |
| 75 | /// Mark to trigger firmware swap on next boot if verify suceeds. | 77 | /// Mark to trigger firmware swap on next boot if verify succeeds. |
| 76 | /// | 78 | /// |
| 77 | /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have | 79 | /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have |
| 78 | /// been generated from a SHA-512 digest of the firmware bytes. | 80 | /// 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> { | |||
| 213 | let sector_end = sector_start + DFU::ERASE_SIZE; | 215 | let sector_end = sector_start + DFU::ERASE_SIZE; |
| 214 | // Determine if the current sector needs to be erased before writing. | 216 | // Determine if the current sector needs to be erased before writing. |
| 215 | let need_erase = self | 217 | let need_erase = self |
| 216 | .state | ||
| 217 | .last_erased_dfu_page_index | 218 | .last_erased_dfu_page_index |
| 218 | .map_or(true, |last_erased_sector| current_sector != last_erased_sector); | 219 | .map_or(true, |last_erased_sector| current_sector != last_erased_sector); |
| 219 | 220 | ||
| 220 | // If the sector needs to be erased, erase it and update the last erased sector index. | 221 | // If the sector needs to be erased, erase it and update the last erased sector index. |
| 221 | if need_erase { | 222 | if need_erase { |
| 222 | self.dfu.erase(sector_start as u32, sector_end as u32).await?; | 223 | self.dfu.erase(sector_start as u32, sector_end as u32).await?; |
| 223 | self.state.last_erased_dfu_page_index = Some(current_sector); | 224 | self.last_erased_dfu_page_index = Some(current_sector); |
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | // Calculate the size of the data chunk that can be written in the current iteration. | 227 | // 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> { | |||
| 258 | pub struct FirmwareState<'d, STATE> { | 259 | pub struct FirmwareState<'d, STATE> { |
| 259 | state: STATE, | 260 | state: STATE, |
| 260 | aligned: &'d mut [u8], | 261 | aligned: &'d mut [u8], |
| 261 | last_erased_dfu_page_index: Option<usize>, | ||
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> { | 264 | impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> { |
| @@ -280,11 +280,7 @@ impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> { | |||
| 280 | /// and follow the alignment rules for the flash being read from and written to. | 280 | /// and follow the alignment rules for the flash being read from and written to. |
| 281 | pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self { | 281 | pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self { |
| 282 | assert_eq!(aligned.len(), STATE::WRITE_SIZE.max(STATE::READ_SIZE)); | 282 | assert_eq!(aligned.len(), STATE::WRITE_SIZE.max(STATE::READ_SIZE)); |
| 283 | Self { | 283 | Self { state, aligned } |
| 284 | state, | ||
| 285 | aligned, | ||
| 286 | last_erased_dfu_page_index: None, | ||
| 287 | } | ||
| 288 | } | 284 | } |
| 289 | 285 | ||
| 290 | // Make sure we are running a booted firmware to avoid reverting to a bad state. | 286 | // Make sure we are running a booted firmware to avoid reverting to a bad state. |
diff --git a/embassy-boot/src/firmware_updater/blocking.rs b/embassy-boot/src/firmware_updater/blocking.rs index 5b8076f81..eb96a9523 100644 --- a/embassy-boot/src/firmware_updater/blocking.rs +++ b/embassy-boot/src/firmware_updater/blocking.rs | |||
| @@ -13,6 +13,7 @@ use crate::{FirmwareUpdaterError, State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERA | |||
| 13 | pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { | 13 | pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { |
| 14 | dfu: DFU, | 14 | dfu: DFU, |
| 15 | state: BlockingFirmwareState<'d, STATE>, | 15 | state: BlockingFirmwareState<'d, STATE>, |
| 16 | last_erased_dfu_page_index: Option<usize>, | ||
| 16 | } | 17 | } |
| 17 | 18 | ||
| 18 | #[cfg(target_os = "none")] | 19 | #[cfg(target_os = "none")] |
| @@ -91,6 +92,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE> | |||
| 91 | Self { | 92 | Self { |
| 92 | dfu: config.dfu, | 93 | dfu: config.dfu, |
| 93 | state: BlockingFirmwareState::new(config.state, aligned), | 94 | state: BlockingFirmwareState::new(config.state, aligned), |
| 95 | last_erased_dfu_page_index: None, | ||
| 94 | } | 96 | } |
| 95 | } | 97 | } |
| 96 | 98 | ||
| @@ -107,7 +109,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> BlockingFirmwareUpdater<'d, DFU, STATE> | |||
| 107 | /// proceed with updating the firmware as it must be signed with a | 109 | /// proceed with updating the firmware as it must be signed with a |
| 108 | /// corresponding private key (otherwise it could be malicious firmware). | 110 | /// corresponding private key (otherwise it could be malicious firmware). |
| 109 | /// | 111 | /// |
| 110 | /// Mark to trigger firmware swap on next boot if verify suceeds. | 112 | /// Mark to trigger firmware swap on next boot if verify succeeds. |
| 111 | /// | 113 | /// |
| 112 | /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have | 114 | /// If the "ed25519-salty" feature is set (or another similar feature) then the signature is expected to have |
| 113 | /// been generated from a SHA-512 digest of the firmware bytes. | 115 | /// 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> | |||
| 248 | let sector_end = sector_start + DFU::ERASE_SIZE; | 250 | let sector_end = sector_start + DFU::ERASE_SIZE; |
| 249 | // Determine if the current sector needs to be erased before writing. | 251 | // Determine if the current sector needs to be erased before writing. |
| 250 | let need_erase = self | 252 | let need_erase = self |
| 251 | .state | ||
| 252 | .last_erased_dfu_page_index | 253 | .last_erased_dfu_page_index |
| 253 | .map_or(true, |last_erased_sector| current_sector != last_erased_sector); | 254 | .map_or(true, |last_erased_sector| current_sector != last_erased_sector); |
| 254 | 255 | ||
| 255 | // If the sector needs to be erased, erase it and update the last erased sector index. | 256 | // If the sector needs to be erased, erase it and update the last erased sector index. |
| 256 | if need_erase { | 257 | if need_erase { |
| 257 | self.dfu.erase(sector_start as u32, sector_end as u32)?; | 258 | self.dfu.erase(sector_start as u32, sector_end as u32)?; |
| 258 | self.state.last_erased_dfu_page_index = Some(current_sector); | 259 | self.last_erased_dfu_page_index = Some(current_sector); |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | // Calculate the size of the data chunk that can be written in the current iteration. | 262 | // 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> | |||
| 293 | pub struct BlockingFirmwareState<'d, STATE> { | 294 | pub struct BlockingFirmwareState<'d, STATE> { |
| 294 | state: STATE, | 295 | state: STATE, |
| 295 | aligned: &'d mut [u8], | 296 | aligned: &'d mut [u8], |
| 296 | last_erased_dfu_page_index: Option<usize>, | ||
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> { | 299 | impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> { |
| @@ -315,11 +315,7 @@ impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> { | |||
| 315 | /// and written to. | 315 | /// and written to. |
| 316 | pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self { | 316 | pub fn new(state: STATE, aligned: &'d mut [u8]) -> Self { |
| 317 | assert_eq!(aligned.len(), STATE::WRITE_SIZE); | 317 | assert_eq!(aligned.len(), STATE::WRITE_SIZE); |
| 318 | Self { | 318 | Self { state, aligned } |
| 319 | state, | ||
| 320 | aligned, | ||
| 321 | last_erased_dfu_page_index: None, | ||
| 322 | } | ||
| 323 | } | 319 | } |
| 324 | 320 | ||
| 325 | // Make sure we are running a booted firmware to avoid reverting to a bad state. | 321 | // Make sure we are running a booted firmware to avoid reverting to a bad state. |
