Skip to content

Commit 09aeaeb

Browse files
committed
sim: Add swap using offset to tests
Enables testing this new mode Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
1 parent be9b2ad commit 09aeaeb

File tree

7 files changed

+94
-34
lines changed

7 files changed

+94
-34
lines changed

.github/workflows/sim.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
matrix:
1818
features:
1919
- "sig-ecdsa,sig-ecdsa-mbedtls,sig-ed25519,enc-kw,bootstrap"
20-
- "sig-rsa,sig-rsa3072,overwrite-only,validate-primary-slot,swap-move"
20+
- "sig-rsa,sig-rsa3072,overwrite-only,validate-primary-slot,swap-move,swap-offset"
2121
- "enc-rsa,enc-rsa max-align-32"
2222
- "enc-aes256-rsa,enc-aes256-rsa max-align-32"
2323
- "enc-ec256,enc-ec256 max-align-32"
@@ -29,7 +29,7 @@ jobs:
2929
- "enc-kw overwrite-only,enc-kw overwrite-only max-align-32"
3030
- "enc-rsa overwrite-only,enc-rsa overwrite-only max-align-32"
3131
- "enc-aes256-kw overwrite-only,enc-aes256-kw overwrite-only max-align-32"
32-
- "sig-rsa enc-rsa validate-primary-slot,swap-move enc-rsa sig-rsa validate-primary-slot bootstrap"
32+
- "sig-rsa enc-rsa validate-primary-slot,swap-move enc-rsa sig-rsa validate-primary-slot bootstrap,swap-offset enc-rsa sig-rsa validate-primary-slot bootstrap"
3333
- "sig-rsa enc-kw validate-primary-slot bootstrap,sig-ed25519 enc-x25519 validate-primary-slot"
3434
- "sig-ecdsa enc-kw validate-primary-slot"
3535
- "sig-ecdsa-mbedtls enc-kw validate-primary-slot"

sim/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ sig-ecdsa-psa = ["mcuboot-sys/sig-ecdsa-psa", "mcuboot-sys/psa-crypto-api"]
1515
sig-p384 = ["mcuboot-sys/sig-p384"]
1616
sig-ed25519 = ["mcuboot-sys/sig-ed25519"]
1717
overwrite-only = ["mcuboot-sys/overwrite-only"]
18+
swap-offset = ["mcuboot-sys/swap-offset"]
1819
swap-move = ["mcuboot-sys/swap-move"]
1920
validate-primary-slot = ["mcuboot-sys/validate-primary-slot"]
2021
enc-rsa = ["mcuboot-sys/enc-rsa"]

sim/mcuboot-sys/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ sig-ed25519 = []
3636
# Overwrite only upgrade
3737
overwrite-only = []
3838

39+
# Swap using offset mode
40+
swap-offset = []
41+
42+
# Swap using move move
3943
swap-move = []
4044

4145
# Disable validation of the primary slot

sim/mcuboot-sys/build.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ fn main() {
2020
let sig_ed25519 = env::var("CARGO_FEATURE_SIG_ED25519").is_ok();
2121
let overwrite_only = env::var("CARGO_FEATURE_OVERWRITE_ONLY").is_ok();
2222
let swap_move = env::var("CARGO_FEATURE_SWAP_MOVE").is_ok();
23+
let swap_offset = env::var("CARGO_FEATURE_SWAP_OFFSET").is_ok();
2324
let validate_primary_slot =
2425
env::var("CARGO_FEATURE_VALIDATE_PRIMARY_SLOT").is_ok();
2526
let enc_rsa = env::var("CARGO_FEATURE_ENC_RSA").is_ok();
@@ -253,7 +254,9 @@ fn main() {
253254
conf.conf.define("MCUBOOT_OVERWRITE_ONLY", None);
254255
}
255256

256-
if swap_move {
257+
if swap_offset {
258+
conf.conf.define("MCUBOOT_SWAP_USING_OFFSET", None);
259+
} else if swap_move {
257260
conf.conf.define("MCUBOOT_SWAP_USING_MOVE", None);
258261
} else if !overwrite_only && !direct_xip && !ram_load {
259262
conf.conf.define("CONFIG_BOOT_SWAP_USING_SCRATCH", None);
@@ -461,6 +464,7 @@ fn main() {
461464
conf.file("../../boot/bootutil/src/swap_misc.c");
462465
conf.file("../../boot/bootutil/src/swap_scratch.c");
463466
conf.file("../../boot/bootutil/src/swap_move.c");
467+
conf.file("../../boot/bootutil/src/swap_offset.c");
464468
conf.file("../../boot/bootutil/src/caps.c");
465469
conf.file("../../boot/bootutil/src/bootutil_misc.c");
466470
conf.file("../../boot/bootutil/src/bootutil_public.c");

sim/src/caps.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub enum Caps {
3030
DirectXip = (1 << 17),
3131
HwRollbackProtection = (1 << 18),
3232
EcdsaP384 = (1 << 19),
33+
SwapUsingOffset = (1 << 20),
3334
}
3435

3536
impl Caps {

sim/src/image.rs

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -235,20 +235,20 @@ impl ImagesBuilder {
235235
let (primaries,upgrades) = if img_manipulation == ImageManipulation::CorruptHigherVersionImage && !higher_version_corrupted {
236236
higher_version_corrupted = true;
237237
let prim = install_image(&mut flash, &slots[0],
238-
maximal(42784), &ram, &*dep, ImageManipulation::None, Some(0));
238+
maximal(42784), &ram, &*dep, ImageManipulation::None, Some(0), false);
239239
let upgr = match deps.depends[image_num] {
240240
DepType::NoUpgrade => install_no_image(),
241241
_ => install_image(&mut flash, &slots[1],
242-
maximal(46928), &ram, &*dep, ImageManipulation::BadSignature, Some(0))
242+
maximal(46928), &ram, &*dep, ImageManipulation::BadSignature, Some(0), true)
243243
};
244244
(prim, upgr)
245245
} else {
246246
let prim = install_image(&mut flash, &slots[0],
247-
maximal(42784), &ram, &*dep, img_manipulation, Some(0));
247+
maximal(42784), &ram, &*dep, img_manipulation, Some(0), false);
248248
let upgr = match deps.depends[image_num] {
249249
DepType::NoUpgrade => install_no_image(),
250250
_ => install_image(&mut flash, &slots[1],
251-
maximal(46928), &ram, &*dep, img_manipulation, Some(0))
251+
maximal(46928), &ram, &*dep, img_manipulation, Some(0), true)
252252
};
253253
(prim, upgr)
254254
};
@@ -299,9 +299,9 @@ impl ImagesBuilder {
299299
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
300300
let dep = BoringDep::new(image_num, &NO_DEPS);
301301
let primaries = install_image(&mut bad_flash, &slots[0],
302-
maximal(32784), &ram, &dep, ImageManipulation::None, Some(0));
302+
maximal(32784), &ram, &dep, ImageManipulation::None, Some(0), false);
303303
let upgrades = install_image(&mut bad_flash, &slots[1],
304-
maximal(41928), &ram, &dep, ImageManipulation::BadSignature, Some(0));
304+
maximal(41928), &ram, &dep, ImageManipulation::BadSignature, Some(0), true);
305305
OneImage {
306306
slots,
307307
primaries,
@@ -322,9 +322,9 @@ impl ImagesBuilder {
322322
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
323323
let dep = BoringDep::new(image_num, &NO_DEPS);
324324
let primaries = install_image(&mut bad_flash, &slots[0],
325-
maximal(32784), &ram, &dep, ImageManipulation::None, Some(0));
325+
maximal(32784), &ram, &dep, ImageManipulation::None, Some(0), false);
326326
let upgrades = install_image(&mut bad_flash, &slots[1],
327-
ImageSize::Oversized, &ram, &dep, ImageManipulation::None, Some(0));
327+
ImageSize::Oversized, &ram, &dep, ImageManipulation::None, Some(0), true);
328328
OneImage {
329329
slots,
330330
primaries,
@@ -345,7 +345,7 @@ impl ImagesBuilder {
345345
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
346346
let dep = BoringDep::new(image_num, &NO_DEPS);
347347
let primaries = install_image(&mut flash, &slots[0],
348-
maximal(32784), &ram, &dep,ImageManipulation::None, Some(0));
348+
maximal(32784), &ram, &dep,ImageManipulation::None, Some(0), false);
349349
let upgrades = install_no_image();
350350
OneImage {
351351
slots,
@@ -368,7 +368,7 @@ impl ImagesBuilder {
368368
let dep = BoringDep::new(image_num, &NO_DEPS);
369369
let primaries = install_no_image();
370370
let upgrades = install_image(&mut flash, &slots[1],
371-
maximal(32784), &ram, &dep, ImageManipulation::None, Some(0));
371+
maximal(32784), &ram, &dep, ImageManipulation::None, Some(0), true);
372372
OneImage {
373373
slots,
374374
primaries,
@@ -390,7 +390,7 @@ impl ImagesBuilder {
390390
let dep = BoringDep::new(image_num, &NO_DEPS);
391391
let primaries = install_no_image();
392392
let upgrades = install_image(&mut flash, &slots[1],
393-
ImageSize::Oversized, &ram, &dep, ImageManipulation::None, Some(0));
393+
ImageSize::Oversized, &ram, &dep, ImageManipulation::None, Some(0), true);
394394
OneImage {
395395
slots,
396396
primaries,
@@ -412,9 +412,9 @@ impl ImagesBuilder {
412412
let images = self.slots.into_iter().enumerate().map(|(image_num, slots)| {
413413
let dep = BoringDep::new(image_num, &NO_DEPS);
414414
let primaries = install_image(&mut flash, &slots[0],
415-
maximal(32784), &ram, &dep, ImageManipulation::None, security_cnt);
415+
maximal(32784), &ram, &dep, ImageManipulation::None, security_cnt, false);
416416
let upgrades = install_image(&mut flash, &slots[1],
417-
maximal(41928), &ram, &dep, ImageManipulation::None, security_cnt.map(|v| v + 1));
417+
maximal(41928), &ram, &dep, ImageManipulation::None, security_cnt.map(|v| v + 1), true);
418418
OneImage {
419419
slots,
420420
primaries,
@@ -451,7 +451,7 @@ impl ImagesBuilder {
451451

452452
let mut flash = SimMultiFlash::new();
453453
flash.insert(dev_id, dev);
454-
(flash, Rc::new(areadesc), &[Caps::SwapUsingMove])
454+
(flash, Rc::new(areadesc), &[Caps::SwapUsingMove, Caps::SwapUsingOffset])
455455
}
456456
DeviceName::K64f => {
457457
// NXP style flash. Small sectors, one small sector for scratch.
@@ -482,7 +482,7 @@ impl ImagesBuilder {
482482

483483
let mut flash = SimMultiFlash::new();
484484
flash.insert(dev_id, dev);
485-
(flash, Rc::new(areadesc), &[Caps::SwapUsingMove])
485+
(flash, Rc::new(areadesc), &[Caps::SwapUsingMove, Caps::SwapUsingOffset])
486486
}
487487
DeviceName::Nrf52840 => {
488488
// Simulating the flash on the nrf52840 with partitions set up so that the scratch size
@@ -511,7 +511,20 @@ impl ImagesBuilder {
511511

512512
let mut flash = SimMultiFlash::new();
513513
flash.insert(dev_id, dev);
514-
(flash, Rc::new(areadesc), &[Caps::SwapUsingScratch, Caps::OverwriteUpgrade])
514+
(flash, Rc::new(areadesc), &[Caps::SwapUsingScratch, Caps::OverwriteUpgrade, Caps::SwapUsingOffset])
515+
}
516+
DeviceName::Nrf52840UnequalSlotsLargerSlot1 => {
517+
let dev = SimFlash::new(vec![4096; 128], align as usize, erased_val);
518+
519+
let dev_id = 0;
520+
let mut areadesc = AreaDesc::new();
521+
areadesc.add_flash_sectors(dev_id, &dev);
522+
areadesc.add_image(0x008000, 0x03b000, FlashId::Image0, dev_id);
523+
areadesc.add_image(0x043000, 0x03c000, FlashId::Image1, dev_id);
524+
525+
let mut flash = SimMultiFlash::new();
526+
flash.insert(dev_id, dev);
527+
(flash, Rc::new(areadesc), &[Caps::SwapUsingScratch, Caps::OverwriteUpgrade, Caps::SwapUsingMove, Caps::RamLoad, Caps::DirectXip])
515528
}
516529
DeviceName::Nrf52840SpiFlash => {
517530
// Simulate nrf52840 with external SPI flash. The external SPI flash
@@ -530,7 +543,7 @@ impl ImagesBuilder {
530543
let mut flash = SimMultiFlash::new();
531544
flash.insert(0, dev0);
532545
flash.insert(1, dev1);
533-
(flash, Rc::new(areadesc), &[Caps::SwapUsingMove])
546+
(flash, Rc::new(areadesc), &[Caps::SwapUsingMove, Caps::SwapUsingOffset])
534547
}
535548
DeviceName::K64fMulti => {
536549
// NXP style flash, but larger, to support multiple images.
@@ -653,7 +666,7 @@ impl Images {
653666
}
654667

655668
fn is_swap_upgrade(&self) -> bool {
656-
Caps::SwapUsingScratch.present() || Caps::SwapUsingMove.present()
669+
Caps::SwapUsingScratch.present() || Caps::SwapUsingMove.present() || Caps::SwapUsingOffset.present()
657670
}
658671

659672
pub fn run_basic_revert(&self) -> bool {
@@ -1738,7 +1751,7 @@ fn image_largest_trailer(dev: &dyn Flash) -> usize {
17381751
// This computation is incorrect, and we need to figure out the correct size.
17391752
// c::boot_status_sz(dev.align() as u32) as usize
17401753
16 + 4 * dev.align()
1741-
} else if Caps::SwapUsingMove.present() {
1754+
} else if Caps::SwapUsingOffset.present() || Caps::SwapUsingMove.present() {
17421755
let sector_size = dev.sector_iter().next().unwrap().size as u32;
17431756
align_up(c::boot_trailer_sz(dev.align() as u32), sector_size) as usize
17441757
} else if Caps::SwapUsingScratch.present() {
@@ -1754,13 +1767,19 @@ fn image_largest_trailer(dev: &dyn Flash) -> usize {
17541767
/// fields used by the given code. Returns a copy of the image that was written.
17551768
fn install_image(flash: &mut SimMultiFlash, slot: &SlotInfo, len: ImageSize,
17561769
ram: &RamData,
1757-
deps: &dyn Depender, img_manipulation: ImageManipulation, security_counter:Option<u32>) -> ImageData {
1758-
let offset = slot.base_off;
1770+
deps: &dyn Depender, img_manipulation: ImageManipulation, security_counter:Option<u32>, secondary_slot:bool) -> ImageData {
1771+
let mut offset = slot.base_off;
17591772
let slot_len = slot.len;
17601773
let dev_id = slot.dev_id;
17611774
let dev = flash.get_mut(&dev_id).unwrap();
17621775

17631776
let mut tlv: Box<dyn ManifestGen> = Box::new(make_tlv());
1777+
1778+
if Caps::SwapUsingOffset.present() && secondary_slot {
1779+
let sector_size = dev.sector_iter().next().unwrap().size as usize;
1780+
offset += sector_size;
1781+
}
1782+
17641783
if img_manipulation == ImageManipulation::IgnoreRamLoadFlag {
17651784
tlv.set_ignore_ram_load_flag();
17661785
}
@@ -1798,11 +1817,19 @@ fn install_image(flash: &mut SimMultiFlash, slot: &SlotInfo, len: ImageSize,
17981817
ImageSize::Oversized => {
17991818
let trailer = image_largest_trailer(dev);
18001819
let tlv_len = tlv.estimate_size();
1820+
let mut sector_offset = 0;
1821+
1822+
if Caps::SwapUsingOffset.present() && secondary_slot {
1823+
// This accounts for when both slots have the same size, it will not work where
1824+
// the second slot is one sector larger than the primary
1825+
sector_offset = dev.sector_iter().next().unwrap().size as usize;
1826+
}
1827+
18011828
info!("slot: 0x{:x}, HDR: 0x{:x}, trailer: 0x{:x}",
18021829
slot_len, HDR_SIZE, trailer);
18031830
// the overflow size is rougly estimated to work for all
18041831
// configurations. It might be precise if tlv_len will be maked precise.
1805-
slot_len - HDR_SIZE - trailer - tlv_len + dev.align()*4
1832+
slot_len - HDR_SIZE - trailer - tlv_len - sector_offset + dev.align()*4
18061833
}
18071834

18081835
};
@@ -2046,17 +2073,37 @@ fn verify_image(flash: &SimMultiFlash, slot: &SlotInfo, images: &ImageData) -> b
20462073
let dev = flash.get(&dev_id).unwrap();
20472074
dev.read(offset, &mut copy).unwrap();
20482075

2049-
if buf != &copy[..] {
2050-
for i in 0 .. buf.len() {
2051-
if buf[i] != copy[i] {
2052-
info!("First failure for slot{} at {:#x} ({:#x} within) {:#x}!={:#x}",
2053-
slot.index, offset + i, i, buf[i], copy[i]);
2054-
break;
2076+
if Caps::SwapUsingOffset.present() && (slot.index % 2) == 1 {
2077+
let sector_size = dev.sector_iter().next().unwrap().size as usize;
2078+
let mut copy_offset = vec![0u8; buf.len()];
2079+
let offset_offset = slot.base_off + sector_size;
2080+
dev.read(offset_offset, &mut copy_offset).unwrap();
2081+
2082+
if buf != &copy[..] && buf != &copy_offset[..] {
2083+
for i in 0 .. buf.len() {
2084+
if buf[i] != copy[i] && buf[i] != copy_offset[i] {
2085+
info!("First failure for slot{} at {:#x} ({:#x} within) {:#x}!=({:#x} or {:#x})",
2086+
slot.index, offset + i, i, buf[i], copy[i], copy_offset[i]);
2087+
break;
2088+
}
20552089
}
2090+
false
2091+
} else {
2092+
true
20562093
}
2057-
false
20582094
} else {
2059-
true
2095+
if buf != &copy[..] {
2096+
for i in 0 .. buf.len() {
2097+
if buf[i] != copy[i] {
2098+
info!("First failure for slot{} at {:#x} ({:#x} within) {:#x}!={:#x}",
2099+
slot.index, offset + i, i, buf[i], copy[i]);
2100+
break;
2101+
}
2102+
}
2103+
false
2104+
} else {
2105+
true
2106+
}
20602107
}
20612108
}
20622109

@@ -2294,6 +2341,7 @@ trait AsRaw : Sized {
22942341
/// Returns an ImageSize representing the best size to test, possibly just with the given size.
22952342
fn maximal(size: usize) -> ImageSize {
22962343
if Caps::OverwriteUpgrade.present() ||
2344+
Caps::SwapUsingOffset.present() ||
22972345
Caps::SwapUsingMove.present()
22982346
{
22992347
ImageSize::Given(size)

sim/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct Args {
6464
#[derive(Copy, Clone, Debug, Deserialize)]
6565
pub enum DeviceName {
6666
Stm32f4, K64f, K64fBig, K64fMulti, Nrf52840, Nrf52840SpiFlash,
67-
Nrf52840UnequalSlots,
67+
Nrf52840UnequalSlots, Nrf52840UnequalSlotsLargerSlot1,
6868
}
6969

7070
pub static ALL_DEVICES: &[DeviceName] = &[
@@ -75,6 +75,7 @@ pub static ALL_DEVICES: &[DeviceName] = &[
7575
DeviceName::Nrf52840,
7676
DeviceName::Nrf52840SpiFlash,
7777
DeviceName::Nrf52840UnequalSlots,
78+
DeviceName::Nrf52840UnequalSlotsLargerSlot1,
7879
];
7980

8081
impl fmt::Display for DeviceName {
@@ -87,6 +88,7 @@ impl fmt::Display for DeviceName {
8788
DeviceName::Nrf52840 => "nrf52840",
8889
DeviceName::Nrf52840SpiFlash => "Nrf52840SpiFlash",
8990
DeviceName::Nrf52840UnequalSlots => "Nrf52840UnequalSlots",
91+
DeviceName::Nrf52840UnequalSlotsLargerSlot1 => "Nrf52840UnequalSlotsLargerSlot1",
9092
};
9193
f.write_str(name)
9294
}

0 commit comments

Comments
 (0)