aboutsummaryrefslogtreecommitdiff
path: root/embassy-boot/src/firmware_updater
diff options
context:
space:
mode:
authorBadr Bouslikhin <[email protected]>2024-02-12 23:24:21 +0100
committerBadr Bouslikhin <[email protected]>2024-02-12 23:24:21 +0100
commit56e6b6bee6bd6087b35857e8aa1a011f6e83f703 (patch)
tree2ed1d435e2b8461a690ea7933fb98ff77a17f941 /embassy-boot/src/firmware_updater
parent333b2afe6d5319317b2679e634c3cf242bab0e73 (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.rs14
-rw-r--r--embassy-boot/src/firmware_updater/blocking.rs14
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
13pub struct FirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { 13pub 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> {
258pub struct FirmwareState<'d, STATE> { 259pub 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
264impl<'d, STATE: NorFlash> FirmwareState<'d, STATE> { 264impl<'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
13pub struct BlockingFirmwareUpdater<'d, DFU: NorFlash, STATE: NorFlash> { 13pub 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>
293pub struct BlockingFirmwareState<'d, STATE> { 294pub 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
299impl<'d, STATE: NorFlash> BlockingFirmwareState<'d, STATE> { 299impl<'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.