diff --git a/sim/src/lib.rs b/sim/src/lib.rs
new file mode 100644
index 0000000..37b5886
--- /dev/null
+++ b/sim/src/lib.rs
@@ -0,0 +1,1002 @@
+#[macro_use] extern crate log;
+extern crate ring;
+extern crate env_logger;
+extern crate docopt;
+extern crate libc;
+extern crate pem;
+extern crate rand;
+#[macro_use] extern crate serde_derive;
+extern crate serde;
+extern crate simflash;
+extern crate untrusted;
+extern crate mcuboot_sys;
+
+use docopt::Docopt;
+use rand::{Rng, SeedableRng, XorShiftRng};
+use rand::distributions::{IndependentSample, Range};
+use std::fmt;
+use std::mem;
+use std::process;
+use std::slice;
+
+mod caps;
+mod tlv;
+
+use simflash::{Flash, SimFlash};
+use mcuboot_sys::{c, AreaDesc, FlashId};
+use caps::Caps;
+use tlv::TlvGen;
+
+const USAGE: &'static str = "
+Mcuboot simulator
+
+Usage:
+  bootsim sizes
+  bootsim run --device TYPE [--align SIZE]
+  bootsim runall
+  bootsim (--help | --version)
+
+Options:
+  -h, --help         Show this message
+  --version          Version
+  --device TYPE      MCU to simulate
+                     Valid values: stm32f4, k64f
+  --align SIZE       Flash write alignment
+";
+
+#[derive(Debug, Deserialize)]
+struct Args {
+    flag_help: bool,
+    flag_version: bool,
+    flag_device: Option<DeviceName>,
+    flag_align: Option<AlignArg>,
+    cmd_sizes: bool,
+    cmd_run: bool,
+    cmd_runall: bool,
+}
+
+#[derive(Copy, Clone, Debug, Deserialize)]
+enum DeviceName { Stm32f4, K64f, K64fBig, Nrf52840 }
+
+static ALL_DEVICES: &'static [DeviceName] = &[
+    DeviceName::Stm32f4,
+    DeviceName::K64f,
+    DeviceName::K64fBig,
+    DeviceName::Nrf52840,
+];
+
+impl fmt::Display for DeviceName {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let name = match *self {
+            DeviceName::Stm32f4 => "stm32f4",
+            DeviceName::K64f => "k64f",
+            DeviceName::K64fBig => "k64fbig",
+            DeviceName::Nrf52840 => "nrf52840",
+        };
+        f.write_str(name)
+    }
+}
+
+#[derive(Debug)]
+struct AlignArg(u8);
+
+struct AlignArgVisitor;
+
+impl<'de> serde::de::Visitor<'de> for AlignArgVisitor {
+    type Value = AlignArg;
+
+    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        formatter.write_str("1, 2, 4 or 8")
+    }
+
+    fn visit_u8<E>(self, n: u8) -> Result<Self::Value, E>
+        where E: serde::de::Error
+    {
+        Ok(match n {
+            1 | 2 | 4 | 8 => AlignArg(n),
+            n => {
+                let err = format!("Could not deserialize '{}' as alignment", n);
+                return Err(E::custom(err));
+            }
+        })
+    }
+}
+
+impl<'de> serde::de::Deserialize<'de> for AlignArg {
+    fn deserialize<D>(d: D) -> Result<AlignArg, D::Error>
+        where D: serde::de::Deserializer<'de>
+    {
+        d.deserialize_u8(AlignArgVisitor)
+    }
+}
+
+pub fn main() {
+    let args: Args = Docopt::new(USAGE)
+        .and_then(|d| d.deserialize())
+        .unwrap_or_else(|e| e.exit());
+    // println!("args: {:#?}", args);
+
+    if args.cmd_sizes {
+        show_sizes();
+        return;
+    }
+
+    let mut status = RunStatus::new();
+    if args.cmd_run {
+
+        let align = args.flag_align.map(|x| x.0).unwrap_or(1);
+
+
+        let device = match args.flag_device {
+            None => panic!("Missing mandatory device argument"),
+            Some(dev) => dev,
+        };
+
+        status.run_single(device, align);
+    }
+
+    if args.cmd_runall {
+        for &dev in ALL_DEVICES {
+            for &align in &[1, 2, 4, 8] {
+                status.run_single(dev, align);
+            }
+        }
+    }
+
+    if status.failures > 0 {
+        error!("{} Tests ran with {} failures", status.failures + status.passes, status.failures);
+        process::exit(1);
+    } else {
+        error!("{} Tests ran successfully", status.passes);
+        process::exit(0);
+    }
+}
+
+struct RunStatus {
+    failures: usize,
+    passes: usize,
+}
+
+impl RunStatus {
+    fn new() -> RunStatus {
+        RunStatus {
+            failures: 0,
+            passes: 0,
+        }
+    }
+
+    fn run_single(&mut self, device: DeviceName, align: u8) {
+        warn!("Running on device {} with alignment {}", device, align);
+
+        let (mut flash, areadesc) = match device {
+            DeviceName::Stm32f4 => {
+                // STM style flash.  Large sectors, with a large scratch area.
+                let flash = SimFlash::new(vec![16 * 1024, 16 * 1024, 16 * 1024, 16 * 1024,
+                                          64 * 1024,
+                                          128 * 1024, 128 * 1024, 128 * 1024],
+                                          align as usize);
+                let mut areadesc = AreaDesc::new(&flash);
+                areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
+                areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
+                areadesc.add_image(0x060000, 0x020000, FlashId::ImageScratch);
+                (flash, areadesc)
+            }
+            DeviceName::K64f => {
+                // NXP style flash.  Small sectors, one small sector for scratch.
+                let flash = SimFlash::new(vec![4096; 128], align as usize);
+
+                let mut areadesc = AreaDesc::new(&flash);
+                areadesc.add_image(0x020000, 0x020000, FlashId::Image0);
+                areadesc.add_image(0x040000, 0x020000, FlashId::Image1);
+                areadesc.add_image(0x060000, 0x001000, FlashId::ImageScratch);
+                (flash, areadesc)
+            }
+            DeviceName::K64fBig => {
+                // Simulating an STM style flash on top of an NXP style flash.  Underlying flash device
+                // uses small sectors, but we tell the bootloader they are large.
+                let flash = SimFlash::new(vec![4096; 128], align as usize);
+
+                let mut areadesc = AreaDesc::new(&flash);
+                areadesc.add_simple_image(0x020000, 0x020000, FlashId::Image0);
+                areadesc.add_simple_image(0x040000, 0x020000, FlashId::Image1);
+                areadesc.add_simple_image(0x060000, 0x020000, FlashId::ImageScratch);
+                (flash, areadesc)
+            }
+            DeviceName::Nrf52840 => {
+                // Simulating the flash on the nrf52840 with partitions set up so that the scratch size
+                // does not divide into the image size.
+                let flash = SimFlash::new(vec![4096; 128], align as usize);
+
+                let mut areadesc = AreaDesc::new(&flash);
+                areadesc.add_image(0x008000, 0x034000, FlashId::Image0);
+                areadesc.add_image(0x03c000, 0x034000, FlashId::Image1);
+                areadesc.add_image(0x070000, 0x00d000, FlashId::ImageScratch);
+                (flash, areadesc)
+            }
+        };
+
+        let (slot0_base, slot0_len) = areadesc.find(FlashId::Image0);
+        let (slot1_base, slot1_len) = areadesc.find(FlashId::Image1);
+        let (scratch_base, _) = areadesc.find(FlashId::ImageScratch);
+
+        // Code below assumes that the slots are consecutive.
+        assert_eq!(slot1_base, slot0_base + slot0_len);
+        assert_eq!(scratch_base, slot1_base + slot1_len);
+
+        let offset_from_end = c::boot_magic_sz() + c::boot_max_align() * 2;
+
+        // println!("Areas: {:#?}", areadesc.get_c());
+
+        // Install the boot trailer signature, so that the code will start an upgrade.
+        // TODO: This must be a multiple of flash alignment, add support for an image that is smaller,
+        // and just gets padded.
+
+        // Create original and upgrade images
+        let slot0 = SlotInfo {
+            base_off: slot0_base as usize,
+            trailer_off: slot1_base - offset_from_end,
+        };
+
+        let slot1 = SlotInfo {
+            base_off: slot1_base as usize,
+            trailer_off: scratch_base - offset_from_end,
+        };
+
+        // Set an alignment, and position the magic value.
+        c::set_sim_flash_align(align);
+
+        let mut failed = false;
+
+        // Creates a badly signed image in slot1 to check that it is not
+        // upgraded to
+        let mut bad_flash = flash.clone();
+        let bad_slot1_image = Images {
+            slot0: &slot0,
+            slot1: &slot1,
+            primary: install_image(&mut bad_flash, slot0_base, 32784, false),
+            upgrade: install_image(&mut bad_flash, slot1_base, 41928, true),
+        };
+
+        failed |= run_signfail_upgrade(&bad_flash, &areadesc, &bad_slot1_image);
+
+        let images = Images {
+            slot0: &slot0,
+            slot1: &slot1,
+            primary: install_image(&mut flash, slot0_base, 32784, false),
+            upgrade: install_image(&mut flash, slot1_base, 41928, false),
+        };
+
+        failed |= run_norevert_newimage(&flash, &areadesc, &images);
+
+        mark_upgrade(&mut flash, &images.slot1);
+
+        // upgrades without fails, counts number of flash operations
+        let total_count = match run_basic_upgrade(&flash, &areadesc, &images) {
+            Ok(v)  => v,
+            Err(_) => {
+                self.failures += 1;
+                return;
+            },
+        };
+
+        failed |= run_basic_revert(&flash, &areadesc, &images);
+        failed |= run_revert_with_fails(&flash, &areadesc, &images, total_count);
+        failed |= run_perm_with_fails(&flash, &areadesc, &images, total_count);
+        failed |= run_perm_with_random_fails(&flash, &areadesc, &images,
+                                             total_count, 5);
+        failed |= run_norevert(&flash, &areadesc, &images);
+
+        //show_flash(&flash);
+
+        if failed {
+            self.failures += 1;
+        } else {
+            self.passes += 1;
+        }
+    }
+}
+
+/// A simple upgrade without forced failures.
+///
+/// Returns the number of flash operations which can later be used to
+/// inject failures at chosen steps.
+fn run_basic_upgrade(flash: &SimFlash, areadesc: &AreaDesc, images: &Images)
+                     -> Result<i32, ()> {
+    let (fl, total_count) = try_upgrade(&flash, &areadesc, &images, None);
+    info!("Total flash operation count={}", total_count);
+
+    if !verify_image(&fl, images.slot0.base_off, &images.upgrade) {
+        warn!("Image mismatch after first boot");
+        Err(())
+    } else {
+        Ok(total_count)
+    }
+}
+
+#[cfg(feature = "overwrite-only")]
+#[allow(unused_variables)]
+fn run_basic_revert(flash: &SimFlash, areadesc: &AreaDesc, images: &Images) -> bool {
+    false
+}
+
+#[cfg(not(feature = "overwrite-only"))]
+fn run_basic_revert(flash: &SimFlash, areadesc: &AreaDesc, images: &Images) -> bool {
+    let mut fails = 0;
+
+    // FIXME: this test would also pass if no swap is ever performed???
+    if Caps::SwapUpgrade.present() {
+        for count in 2 .. 5 {
+            info!("Try revert: {}", count);
+            let fl = try_revert(&flash, &areadesc, count);
+            if !verify_image(&fl, images.slot0.base_off, &images.primary) {
+                error!("Revert failure on count {}", count);
+                fails += 1;
+            }
+        }
+    }
+
+    fails > 0
+}
+
+fn run_perm_with_fails(flash: &SimFlash, areadesc: &AreaDesc, images: &Images,
+                       total_flash_ops: i32) -> bool {
+    let mut fails = 0;
+
+    // Let's try an image halfway through.
+    for i in 1 .. total_flash_ops {
+        info!("Try interruption at {}", i);
+        let (fl, count) = try_upgrade(&flash, &areadesc, &images, Some(i));
+        info!("Second boot, count={}", count);
+        if !verify_image(&fl, images.slot0.base_off, &images.upgrade) {
+            warn!("FAIL at step {} of {}", i, total_flash_ops);
+            fails += 1;
+        }
+
+        if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                           COPY_DONE) {
+            warn!("Mismatched trailer for Slot 0");
+            fails += 1;
+        }
+
+        if !verify_trailer(&fl, images.slot1.trailer_off, MAGIC_UNSET, UNSET,
+                           UNSET) {
+            warn!("Mismatched trailer for Slot 1");
+            fails += 1;
+        }
+
+        if Caps::SwapUpgrade.present() {
+            if !verify_image(&fl, images.slot1.base_off, &images.primary) {
+                warn!("Slot 1 FAIL at step {} of {}", i, total_flash_ops);
+                fails += 1;
+            }
+        }
+    }
+
+    if fails > 0 {
+        error!("{} out of {} failed {:.2}%", fails, total_flash_ops,
+               fails as f32 * 100.0 / total_flash_ops as f32);
+    }
+
+    fails > 0
+}
+
+fn run_perm_with_random_fails(flash: &SimFlash, areadesc: &AreaDesc,
+                              images: &Images, total_flash_ops: i32,
+                              total_fails: usize) -> bool {
+    let mut fails = 0;
+    let (fl, total_counts) = try_random_fails(&flash, &areadesc, &images,
+                                              total_flash_ops, total_fails);
+    info!("Random interruptions at reset points={:?}", total_counts);
+
+    let slot0_ok = verify_image(&fl, images.slot0.base_off, &images.upgrade);
+    let slot1_ok = if Caps::SwapUpgrade.present() {
+        verify_image(&fl, images.slot1.base_off, &images.primary)
+    } else {
+        true
+    };
+    if !slot0_ok || !slot1_ok {
+        error!("Image mismatch after random interrupts: slot0={} slot1={}",
+               if slot0_ok { "ok" } else { "fail" },
+               if slot1_ok { "ok" } else { "fail" });
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                       COPY_DONE) {
+        error!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot1.trailer_off, MAGIC_UNSET, UNSET,
+                       UNSET) {
+        error!("Mismatched trailer for Slot 1");
+        fails += 1;
+    }
+
+    if fails > 0 {
+        error!("Error testing perm upgrade with {} fails", total_fails);
+    }
+
+    fails > 0
+}
+
+#[cfg(feature = "overwrite-only")]
+#[allow(unused_variables)]
+fn run_revert_with_fails(flash: &SimFlash, areadesc: &AreaDesc, images: &Images,
+                         total_count: i32) -> bool {
+    false
+}
+
+#[cfg(not(feature = "overwrite-only"))]
+fn run_revert_with_fails(flash: &SimFlash, areadesc: &AreaDesc, images: &Images,
+                         total_count: i32) -> bool {
+    let mut fails = 0;
+
+    if Caps::SwapUpgrade.present() {
+        for i in 1 .. (total_count - 1) {
+            info!("Try interruption at {}", i);
+            if try_revert_with_fail_at(&flash, &areadesc, &images, i) {
+                error!("Revert failed at interruption {}", i);
+                fails += 1;
+            }
+        }
+    }
+
+    fails > 0
+}
+
+#[cfg(feature = "overwrite-only")]
+#[allow(unused_variables)]
+fn run_norevert(flash: &SimFlash, areadesc: &AreaDesc, images: &Images) -> bool {
+    false
+}
+
+#[cfg(not(feature = "overwrite-only"))]
+fn run_norevert(flash: &SimFlash, areadesc: &AreaDesc, images: &Images) -> bool {
+    let mut fl = flash.clone();
+    let mut fails = 0;
+
+    info!("Try norevert");
+    c::set_flash_counter(0);
+
+    // First do a normal upgrade...
+    if c::boot_go(&mut fl, &areadesc) != 0 {
+        warn!("Failed first boot");
+        fails += 1;
+    }
+
+    //FIXME: copy_done is written by boot_go, is it ok if no copy
+    //       was ever done?
+
+    if !verify_image(&fl, images.slot0.base_off, &images.upgrade) {
+        warn!("Slot 0 image verification FAIL");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, UNSET,
+                       COPY_DONE) {
+        warn!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot1.trailer_off, MAGIC_UNSET, UNSET,
+                       UNSET) {
+        warn!("Mismatched trailer for Slot 1");
+        fails += 1;
+    }
+
+    // Marks image in slot0 as permanent, no revert should happen...
+    mark_permanent_upgrade(&mut fl, &images.slot0);
+
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                       COPY_DONE) {
+        warn!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+
+    if c::boot_go(&mut fl, &areadesc) != 0 {
+        warn!("Failed second boot");
+        fails += 1;
+    }
+
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                       COPY_DONE) {
+        warn!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+    if !verify_image(&fl, images.slot0.base_off, &images.upgrade) {
+        warn!("Failed image verification");
+        fails += 1;
+    }
+
+    if fails > 0 {
+        error!("Error running upgrade without revert");
+    }
+
+    fails > 0
+}
+
+// Tests a new image written to slot0 that already has magic and image_ok set
+// while there is no image on slot1, so no revert should ever happen...
+fn run_norevert_newimage(flash: &SimFlash, areadesc: &AreaDesc,
+                         images: &Images) -> bool {
+    let mut fl = flash.clone();
+    let mut fails = 0;
+
+    info!("Try non-revert on imgtool generated image");
+    c::set_flash_counter(0);
+
+    mark_upgrade(&mut fl, &images.slot0);
+
+    // This simulates writing an image created by imgtool to Slot 0
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, UNSET, UNSET) {
+        warn!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+
+    // Run the bootloader...
+    if c::boot_go(&mut fl, &areadesc) != 0 {
+        warn!("Failed first boot");
+        fails += 1;
+    }
+
+    // State should not have changed
+    if !verify_image(&fl, images.slot0.base_off, &images.primary) {
+        warn!("Failed image verification");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, UNSET,
+                       UNSET) {
+        warn!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot1.trailer_off, MAGIC_UNSET, UNSET,
+                       UNSET) {
+        warn!("Mismatched trailer for Slot 1");
+        fails += 1;
+    }
+
+    if fails > 0 {
+        error!("Expected a non revert with new image");
+    }
+
+    fails > 0
+}
+
+// Tests a new image written to slot0 that already has magic and image_ok set
+// while there is no image on slot1, so no revert should ever happen...
+fn run_signfail_upgrade(flash: &SimFlash, areadesc: &AreaDesc,
+                        images: &Images) -> bool {
+    let mut fl = flash.clone();
+    let mut fails = 0;
+
+    info!("Try upgrade image with bad signature");
+    c::set_flash_counter(0);
+
+    mark_upgrade(&mut fl, &images.slot0);
+    mark_permanent_upgrade(&mut fl, &images.slot0);
+    mark_upgrade(&mut fl, &images.slot1);
+
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                       UNSET) {
+        warn!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+
+    // Run the bootloader...
+    if c::boot_go(&mut fl, &areadesc) != 0 {
+        warn!("Failed first boot");
+        fails += 1;
+    }
+
+    // State should not have changed
+    if !verify_image(&fl, images.slot0.base_off, &images.primary) {
+        warn!("Failed image verification");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                       UNSET) {
+        warn!("Mismatched trailer for Slot 0");
+        fails += 1;
+    }
+
+    if fails > 0 {
+        error!("Expected an upgrade failure when image has bad signature");
+    }
+
+    fails > 0
+}
+
+/// Test a boot, optionally stopping after 'n' flash options.  Returns a count
+/// of the number of flash operations done total.
+fn try_upgrade(flash: &SimFlash, areadesc: &AreaDesc, images: &Images,
+               stop: Option<i32>) -> (SimFlash, i32) {
+    // Clone the flash to have a new copy.
+    let mut fl = flash.clone();
+
+    mark_permanent_upgrade(&mut fl, &images.slot1);
+
+    c::set_flash_counter(stop.unwrap_or(0));
+    let (first_interrupted, count) = match c::boot_go(&mut fl, &areadesc) {
+        -0x13579 => (true, stop.unwrap()),
+        0 => (false, -c::get_flash_counter()),
+        x => panic!("Unknown return: {}", x),
+    };
+    c::set_flash_counter(0);
+
+    if first_interrupted {
+        // fl.dump();
+        match c::boot_go(&mut fl, &areadesc) {
+            -0x13579 => panic!("Shouldn't stop again"),
+            0 => (),
+            x => panic!("Unknown return: {}", x),
+        }
+    }
+
+    (fl, count - c::get_flash_counter())
+}
+
+#[cfg(not(feature = "overwrite-only"))]
+fn try_revert(flash: &SimFlash, areadesc: &AreaDesc, count: usize) -> SimFlash {
+    let mut fl = flash.clone();
+    c::set_flash_counter(0);
+
+    // fl.write_file("image0.bin").unwrap();
+    for i in 0 .. count {
+        info!("Running boot pass {}", i + 1);
+        assert_eq!(c::boot_go(&mut fl, &areadesc), 0);
+    }
+    fl
+}
+
+#[cfg(not(feature = "overwrite-only"))]
+fn try_revert_with_fail_at(flash: &SimFlash, areadesc: &AreaDesc, images: &Images,
+                           stop: i32) -> bool {
+    let mut fl = flash.clone();
+    let mut x: i32;
+    let mut fails = 0;
+
+    c::set_flash_counter(stop);
+    x = c::boot_go(&mut fl, &areadesc);
+    if x != -0x13579 {
+        warn!("Should have stopped at interruption point");
+        fails += 1;
+    }
+
+    if !verify_trailer(&fl, images.slot0.trailer_off, None, None, UNSET) {
+        warn!("copy_done should be unset");
+        fails += 1;
+    }
+
+    c::set_flash_counter(0);
+    x = c::boot_go(&mut fl, &areadesc);
+    if x != 0 {
+        warn!("Should have finished upgrade");
+        fails += 1;
+    }
+
+    if !verify_image(&fl, images.slot0.base_off, &images.upgrade) {
+        warn!("Image in slot 0 before revert is invalid at stop={}", stop);
+        fails += 1;
+    }
+    if !verify_image(&fl, images.slot1.base_off, &images.primary) {
+        warn!("Image in slot 1 before revert is invalid at stop={}", stop);
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, UNSET,
+                       COPY_DONE) {
+        warn!("Mismatched trailer for Slot 0 before revert");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot1.trailer_off, MAGIC_UNSET, UNSET,
+                       UNSET) {
+        warn!("Mismatched trailer for Slot 1 before revert");
+        fails += 1;
+    }
+
+    // Do Revert
+    c::set_flash_counter(0);
+    x = c::boot_go(&mut fl, &areadesc);
+    if x != 0 {
+        warn!("Should have finished a revert");
+        fails += 1;
+    }
+
+    if !verify_image(&fl, images.slot0.base_off, &images.primary) {
+        warn!("Image in slot 0 after revert is invalid at stop={}", stop);
+        fails += 1;
+    }
+    if !verify_image(&fl, images.slot1.base_off, &images.upgrade) {
+        warn!("Image in slot 1 after revert is invalid at stop={}", stop);
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot0.trailer_off, MAGIC_VALID, IMAGE_OK,
+                       COPY_DONE) {
+        warn!("Mismatched trailer for Slot 1 after revert");
+        fails += 1;
+    }
+    if !verify_trailer(&fl, images.slot1.trailer_off, MAGIC_UNSET, UNSET,
+                       UNSET) {
+        warn!("Mismatched trailer for Slot 1 after revert");
+        fails += 1;
+    }
+
+    fails > 0
+}
+
+fn try_random_fails(flash: &SimFlash, areadesc: &AreaDesc, images: &Images,
+                    total_ops: i32,  count: usize) -> (SimFlash, Vec<i32>) {
+    let mut fl = flash.clone();
+
+    mark_permanent_upgrade(&mut fl, &images.slot1);
+
+    let mut rng = rand::thread_rng();
+    let mut resets = vec![0i32; count];
+    let mut remaining_ops = total_ops;
+    for i in 0 .. count {
+        let ops = Range::new(1, remaining_ops / 2);
+        let reset_counter = ops.ind_sample(&mut rng);
+        c::set_flash_counter(reset_counter);
+        match c::boot_go(&mut fl, &areadesc) {
+            0 | -0x13579 => (),
+            x => panic!("Unknown return: {}", x),
+        }
+        remaining_ops -= reset_counter;
+        resets[i] = reset_counter;
+    }
+
+    c::set_flash_counter(0);
+    match c::boot_go(&mut fl, &areadesc) {
+        -0x13579 => panic!("Should not be have been interrupted!"),
+        0 => (),
+        x => panic!("Unknown return: {}", x),
+    }
+
+    (fl, resets)
+}
+
+/// Show the flash layout.
+#[allow(dead_code)]
+fn show_flash(flash: &Flash) {
+    println!("---- Flash configuration ----");
+    for sector in flash.sector_iter() {
+        println!("    {:3}: 0x{:08x}, 0x{:08x}",
+                 sector.num, sector.base, sector.size);
+    }
+    println!("");
+}
+
+/// Install a "program" into the given image.  This fakes the image header, or at least all of the
+/// fields used by the given code.  Returns a copy of the image that was written.
+fn install_image(flash: &mut Flash, offset: usize, len: usize,
+                 bad_sig: bool) -> Vec<u8> {
+    let offset0 = offset;
+
+    let mut tlv = make_tlv();
+
+    // Generate a boot header.  Note that the size doesn't include the header.
+    let header = ImageHeader {
+        magic: 0x96f3b83d,
+        tlv_size: tlv.get_size(),
+        _pad1: 0,
+        hdr_size: 32,
+        key_id: 0,
+        _pad2: 0,
+        img_size: len as u32,
+        flags: tlv.get_flags(),
+        ver: ImageVersion {
+            major: (offset / (128 * 1024)) as u8,
+            minor: 0,
+            revision: 1,
+            build_num: offset as u32,
+        },
+        _pad3: 0,
+    };
+
+    let b_header = header.as_raw();
+    tlv.add_bytes(&b_header);
+    /*
+    let b_header = unsafe { slice::from_raw_parts(&header as *const _ as *const u8,
+                                                  mem::size_of::<ImageHeader>()) };
+                                                  */
+    assert_eq!(b_header.len(), 32);
+    flash.write(offset, &b_header).unwrap();
+    let offset = offset + b_header.len();
+
+    // The core of the image itself is just pseudorandom data.
+    let mut buf = vec![0; len];
+    splat(&mut buf, offset);
+    tlv.add_bytes(&buf);
+
+    // Get and append the TLV itself.
+    if bad_sig {
+        let good_sig = &mut tlv.make_tlv();
+        buf.append(&mut vec![0; good_sig.len()]);
+    } else {
+        buf.append(&mut tlv.make_tlv());
+    }
+
+    // Pad the block to a flash alignment (8 bytes).
+    while buf.len() % 8 != 0 {
+        buf.push(0xFF);
+    }
+
+    flash.write(offset, &buf).unwrap();
+    let offset = offset + buf.len();
+
+    // Copy out the image so that we can verify that the image was installed correctly later.
+    let mut copy = vec![0u8; offset - offset0];
+    flash.read(offset0, &mut copy).unwrap();
+
+    copy
+}
+
+// The TLV in use depends on what kind of signature we are verifying.
+#[cfg(feature = "sig-rsa")]
+fn make_tlv() -> TlvGen {
+    TlvGen::new_rsa_pss()
+}
+
+#[cfg(not(feature = "sig-rsa"))]
+fn make_tlv() -> TlvGen {
+    TlvGen::new_hash_only()
+}
+
+/// Verify that given image is present in the flash at the given offset.
+fn verify_image(flash: &Flash, offset: usize, buf: &[u8]) -> bool {
+    let mut copy = vec![0u8; buf.len()];
+    flash.read(offset, &mut copy).unwrap();
+
+    if buf != &copy[..] {
+        for i in 0 .. buf.len() {
+            if buf[i] != copy[i] {
+                info!("First failure at {:#x}", offset + i);
+                break;
+            }
+        }
+        false
+    } else {
+        true
+    }
+}
+
+#[cfg(feature = "overwrite-only")]
+#[allow(unused_variables)]
+// overwrite-only doesn't employ trailer management
+fn verify_trailer(flash: &Flash, offset: usize,
+                  magic: Option<&[u8]>, image_ok: Option<u8>,
+                  copy_done: Option<u8>) -> bool {
+    true
+}
+
+#[cfg(not(feature = "overwrite-only"))]
+fn verify_trailer(flash: &Flash, offset: usize,
+                  magic: Option<&[u8]>, image_ok: Option<u8>,
+                  copy_done: Option<u8>) -> bool {
+    let mut copy = vec![0u8; c::boot_magic_sz() + c::boot_max_align() * 2];
+    let mut failed = false;
+
+    flash.read(offset, &mut copy).unwrap();
+
+    failed |= match magic {
+        Some(v) => {
+            if &copy[16..] != v  {
+                warn!("\"magic\" mismatch at {:#x}", offset);
+                true
+            } else {
+                false
+            }
+        },
+        None => false,
+    };
+
+    failed |= match image_ok {
+        Some(v) => {
+            if copy[8] != v {
+                warn!("\"image_ok\" mismatch at {:#x}", offset);
+                true
+            } else {
+                false
+            }
+        },
+        None => false,
+    };
+
+    failed |= match copy_done {
+        Some(v) => {
+            if copy[0] != v {
+                warn!("\"copy_done\" mismatch at {:#x}", offset);
+                true
+            } else {
+                false
+            }
+        },
+        None => false,
+    };
+
+    !failed
+}
+
+/// The image header
+#[repr(C)]
+pub struct ImageHeader {
+    magic: u32,
+    tlv_size: u16,
+    key_id: u8,
+    _pad1: u8,
+    hdr_size: u16,
+    _pad2: u16,
+    img_size: u32,
+    flags: u32,
+    ver: ImageVersion,
+    _pad3: u32,
+}
+
+impl AsRaw for ImageHeader {}
+
+#[repr(C)]
+pub struct ImageVersion {
+    major: u8,
+    minor: u8,
+    revision: u16,
+    build_num: u32,
+}
+
+struct SlotInfo {
+    base_off: usize,
+    trailer_off: usize,
+}
+
+struct Images<'a> {
+    slot0: &'a SlotInfo,
+    slot1: &'a SlotInfo,
+    primary: Vec<u8>,
+    upgrade: Vec<u8>,
+}
+
+const MAGIC_VALID: Option<&[u8]> = Some(&[0x77, 0xc2, 0x95, 0xf3,
+                                          0x60, 0xd2, 0xef, 0x7f,
+                                          0x35, 0x52, 0x50, 0x0f,
+                                          0x2c, 0xb6, 0x79, 0x80]);
+const MAGIC_UNSET: Option<&[u8]> = Some(&[0xff; 16]);
+
+const COPY_DONE: Option<u8> = Some(1);
+const IMAGE_OK: Option<u8> = Some(1);
+const UNSET: Option<u8> = Some(0xff);
+
+/// Write out the magic so that the loader tries doing an upgrade.
+fn mark_upgrade(flash: &mut Flash, slot: &SlotInfo) {
+    let offset = slot.trailer_off + c::boot_max_align() * 2;
+    flash.write(offset, MAGIC_VALID.unwrap()).unwrap();
+}
+
+/// Writes the image_ok flag which, guess what, tells the bootloader
+/// the this image is ok (not a test, and no revert is to be performed).
+fn mark_permanent_upgrade(flash: &mut Flash, slot: &SlotInfo) {
+    let ok = [1u8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
+    let align = c::get_sim_flash_align() as usize;
+    let off = slot.trailer_off + c::boot_max_align();
+    flash.write(off, &ok[..align]).unwrap();
+}
+
+// Drop some pseudo-random gibberish onto the data.
+fn splat(data: &mut [u8], seed: usize) {
+    let seed_block = [0x135782ea, 0x92184728, data.len() as u32, seed as u32];
+    let mut rng: XorShiftRng = SeedableRng::from_seed(seed_block);
+    rng.fill_bytes(data);
+}
+
+/// Return a read-only view into the raw bytes of this object
+trait AsRaw : Sized {
+    fn as_raw<'a>(&'a self) -> &'a [u8] {
+        unsafe { slice::from_raw_parts(self as *const _ as *const u8,
+                                       mem::size_of::<Self>()) }
+    }
+}
+
+fn show_sizes() {
+    // This isn't panic safe.
+    let old_align = c::get_sim_flash_align();
+    for min in &[1, 2, 4, 8] {
+        c::set_sim_flash_align(*min);
+        let msize = c::boot_trailer_sz();
+        println!("{:2}: {} (0x{:x})", min, msize, msize);
+    }
+    c::set_sim_flash_align(old_align);
+}
