aboutsummaryrefslogtreecommitdiff
path: root/embassy-boot/boot/src/boot_loader.rs
diff options
context:
space:
mode:
authorsodo <[email protected]>2024-01-02 01:37:00 +0900
committersodo <[email protected]>2024-01-02 13:34:22 +0900
commit6ee153a3e2eec284c0d9d87f31801265c0604f74 (patch)
tree8b801cbd15f9ad5052d5942c731e75736dc9d7eb /embassy-boot/boot/src/boot_loader.rs
parentb7cd7952c890f585ff876c622482534e5d58d4a4 (diff)
parent0be9b0599aaf2e425d76ec7852ff4b3535defddf (diff)
Merge remote-tracking branch 'origin'
Diffstat (limited to 'embassy-boot/boot/src/boot_loader.rs')
-rw-r--r--embassy-boot/boot/src/boot_loader.rs42
1 files changed, 16 insertions, 26 deletions
diff --git a/embassy-boot/boot/src/boot_loader.rs b/embassy-boot/boot/src/boot_loader.rs
index a8c19197b..e568001bc 100644
--- a/embassy-boot/boot/src/boot_loader.rs
+++ b/embassy-boot/boot/src/boot_loader.rs
@@ -5,7 +5,7 @@ use embassy_sync::blocking_mutex::raw::NoopRawMutex;
5use embassy_sync::blocking_mutex::Mutex; 5use embassy_sync::blocking_mutex::Mutex;
6use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind}; 6use embedded_storage::nor_flash::{NorFlash, NorFlashError, NorFlashErrorKind};
7 7
8use crate::{State, BOOT_MAGIC, STATE_ERASE_VALUE, SWAP_MAGIC}; 8use crate::{State, BOOT_MAGIC, DFU_DETACH_MAGIC, STATE_ERASE_VALUE, SWAP_MAGIC};
9 9
10/// Errors returned by bootloader 10/// Errors returned by bootloader
11#[derive(PartialEq, Eq, Debug)] 11#[derive(PartialEq, Eq, Debug)]
@@ -135,51 +135,44 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S
135 /// The provided aligned_buf argument must satisfy any alignment requirements 135 /// The provided aligned_buf argument must satisfy any alignment requirements
136 /// given by the partition flashes. All flash operations will use this buffer. 136 /// given by the partition flashes. All flash operations will use this buffer.
137 /// 137 ///
138 /// SWAPPING 138 /// ## SWAPPING
139 /// 139 ///
140 /// Assume a flash size of 3 pages for the active partition, and 4 pages for the DFU partition. 140 /// Assume a flash size of 3 pages for the active partition, and 4 pages for the DFU partition.
141 /// The swap index contains the copy progress, as to allow continuation of the copy process on 141 /// The swap index contains the copy progress, as to allow continuation of the copy process on
142 /// power failure. The index counter is represented within 1 or more pages (depending on total 142 /// power failure. The index counter is represented within 1 or more pages (depending on total
143 /// flash size), where a page X is considered swapped if index at location (X + WRITE_SIZE) 143 /// flash size), where a page X is considered swapped if index at location (`X + WRITE_SIZE`)
144 /// contains a zero value. This ensures that index updates can be performed atomically and 144 /// contains a zero value. This ensures that index updates can be performed atomically and
145 /// avoid a situation where the wrong index value is set (page write size is "atomic"). 145 /// avoid a situation where the wrong index value is set (page write size is "atomic").
146 /// 146 ///
147 /// +-----------+------------+--------+--------+--------+--------+ 147 ///
148 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | 148 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
149 /// +-----------+------------+--------+--------+--------+--------+ 149 /// |-----------|------------|--------|--------|--------|--------|
150 /// | Active | 0 | 1 | 2 | 3 | - | 150 /// | Active | 0 | 1 | 2 | 3 | - |
151 /// | DFU | 0 | 3 | 2 | 1 | X | 151 /// | DFU | 0 | 3 | 2 | 1 | X |
152 /// +-----------+------------+--------+--------+--------+--------+
153 /// 152 ///
154 /// The algorithm starts by copying 'backwards', and after the first step, the layout is 153 /// The algorithm starts by copying 'backwards', and after the first step, the layout is
155 /// as follows: 154 /// as follows:
156 /// 155 ///
157 /// +-----------+------------+--------+--------+--------+--------+
158 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | 156 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
159 /// +-----------+------------+--------+--------+--------+--------+ 157 /// |-----------|------------|--------|--------|--------|--------|
160 /// | Active | 1 | 1 | 2 | 1 | - | 158 /// | Active | 1 | 1 | 2 | 1 | - |
161 /// | DFU | 1 | 3 | 2 | 1 | 3 | 159 /// | DFU | 1 | 3 | 2 | 1 | 3 |
162 /// +-----------+------------+--------+--------+--------+--------+
163 /// 160 ///
164 /// The next iteration performs the same steps 161 /// The next iteration performs the same steps
165 /// 162 ///
166 /// +-----------+------------+--------+--------+--------+--------+
167 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | 163 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
168 /// +-----------+------------+--------+--------+--------+--------+ 164 /// |-----------|------------|--------|--------|--------|--------|
169 /// | Active | 2 | 1 | 2 | 1 | - | 165 /// | Active | 2 | 1 | 2 | 1 | - |
170 /// | DFU | 2 | 3 | 2 | 2 | 3 | 166 /// | DFU | 2 | 3 | 2 | 2 | 3 |
171 /// +-----------+------------+--------+--------+--------+--------+
172 /// 167 ///
173 /// And again until we're done 168 /// And again until we're done
174 /// 169 ///
175 /// +-----------+------------+--------+--------+--------+--------+
176 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 | 170 /// | Partition | Swap Index | Page 0 | Page 1 | Page 3 | Page 4 |
177 /// +-----------+------------+--------+--------+--------+--------+ 171 /// |-----------|------------|--------|--------|--------|--------|
178 /// | Active | 3 | 3 | 2 | 1 | - | 172 /// | Active | 3 | 3 | 2 | 1 | - |
179 /// | DFU | 3 | 3 | 1 | 2 | 3 | 173 /// | DFU | 3 | 3 | 1 | 2 | 3 |
180 /// +-----------+------------+--------+--------+--------+--------+
181 /// 174 ///
182 /// REVERTING 175 /// ## REVERTING
183 /// 176 ///
184 /// The reverting algorithm uses the swap index to discover that images were swapped, but that 177 /// The reverting algorithm uses the swap index to discover that images were swapped, but that
185 /// the application failed to mark the boot successful. In this case, the revert algorithm will 178 /// the application failed to mark the boot successful. In this case, the revert algorithm will
@@ -190,28 +183,21 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S
190 /// 183 ///
191 /// The revert algorithm works forwards, by starting copying into the 'unused' DFU page at the start. 184 /// The revert algorithm works forwards, by starting copying into the 'unused' DFU page at the start.
192 /// 185 ///
193 /// +-----------+--------------+--------+--------+--------+--------+
194 /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | 186 /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
195 //*/ 187 /// |-----------|--------------|--------|--------|--------|--------|
196 /// +-----------+--------------+--------+--------+--------+--------+
197 /// | Active | 3 | 1 | 2 | 1 | - | 188 /// | Active | 3 | 1 | 2 | 1 | - |
198 /// | DFU | 3 | 3 | 1 | 2 | 3 | 189 /// | DFU | 3 | 3 | 1 | 2 | 3 |
199 /// +-----------+--------------+--------+--------+--------+--------+
200 /// 190 ///
201 /// 191 ///
202 /// +-----------+--------------+--------+--------+--------+--------+
203 /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | 192 /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
204 /// +-----------+--------------+--------+--------+--------+--------+ 193 /// |-----------|--------------|--------|--------|--------|--------|
205 /// | Active | 3 | 1 | 2 | 1 | - | 194 /// | Active | 3 | 1 | 2 | 1 | - |
206 /// | DFU | 3 | 3 | 2 | 2 | 3 | 195 /// | DFU | 3 | 3 | 2 | 2 | 3 |
207 /// +-----------+--------------+--------+--------+--------+--------+
208 /// 196 ///
209 /// +-----------+--------------+--------+--------+--------+--------+
210 /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 | 197 /// | Partition | Revert Index | Page 0 | Page 1 | Page 3 | Page 4 |
211 /// +-----------+--------------+--------+--------+--------+--------+ 198 /// |-----------|--------------|--------|--------|--------|--------|
212 /// | Active | 3 | 1 | 2 | 3 | - | 199 /// | Active | 3 | 1 | 2 | 3 | - |
213 /// | DFU | 3 | 3 | 2 | 1 | 3 | 200 /// | DFU | 3 | 3 | 2 | 1 | 3 |
214 /// +-----------+--------------+--------+--------+--------+--------+
215 /// 201 ///
216 pub fn prepare_boot(&mut self, aligned_buf: &mut [u8]) -> Result<State, BootError> { 202 pub fn prepare_boot(&mut self, aligned_buf: &mut [u8]) -> Result<State, BootError> {
217 // Ensure we have enough progress pages to store copy progress 203 // Ensure we have enough progress pages to store copy progress
@@ -224,6 +210,7 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S
224 assert_eq!(0, aligned_buf.len() % ACTIVE::WRITE_SIZE); 210 assert_eq!(0, aligned_buf.len() % ACTIVE::WRITE_SIZE);
225 assert_eq!(0, aligned_buf.len() % DFU::WRITE_SIZE); 211 assert_eq!(0, aligned_buf.len() % DFU::WRITE_SIZE);
226 212
213 // Ensure our partitions are able to handle boot operations
227 assert_partitions(&self.active, &self.dfu, &self.state, Self::PAGE_SIZE); 214 assert_partitions(&self.active, &self.dfu, &self.state, Self::PAGE_SIZE);
228 215
229 // Copy contents from partition N to active 216 // Copy contents from partition N to active
@@ -384,6 +371,8 @@ impl<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash> BootLoader<ACTIVE, DFU, S
384 371
385 if !state_word.iter().any(|&b| b != SWAP_MAGIC) { 372 if !state_word.iter().any(|&b| b != SWAP_MAGIC) {
386 Ok(State::Swap) 373 Ok(State::Swap)
374 } else if !state_word.iter().any(|&b| b != DFU_DETACH_MAGIC) {
375 Ok(State::DfuDetach)
387 } else { 376 } else {
388 Ok(State::Boot) 377 Ok(State::Boot)
389 } 378 }
@@ -398,6 +387,7 @@ fn assert_partitions<ACTIVE: NorFlash, DFU: NorFlash, STATE: NorFlash>(
398) { 387) {
399 assert_eq!(active.capacity() as u32 % page_size, 0); 388 assert_eq!(active.capacity() as u32 % page_size, 0);
400 assert_eq!(dfu.capacity() as u32 % page_size, 0); 389 assert_eq!(dfu.capacity() as u32 % page_size, 0);
390 // DFU partition has to be bigger than ACTIVE partition to handle swap algorithm
401 assert!(dfu.capacity() as u32 - active.capacity() as u32 >= page_size); 391 assert!(dfu.capacity() as u32 - active.capacity() as u32 >= page_size);
402 assert!(2 + 2 * (active.capacity() as u32 / page_size) <= state.capacity() as u32 / STATE::WRITE_SIZE as u32); 392 assert!(2 + 2 * (active.capacity() as u32 / page_size) <= state.capacity() as u32 / STATE::WRITE_SIZE as u32);
403} 393}