From 1acfa30497e8d8592b6363e64d9d68ff6e6fdb0a Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Wed, 17 May 2017 15:47:33 -0400 Subject: [PATCH 1/2] bootutil_log: send simulator logs to stderr This matches the behavior of Rust's logs. Signed-off-by: Marti Bolivar --- boot/bootutil/include/bootutil/bootutil_log.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/boot/bootutil/include/bootutil/bootutil_log.h b/boot/bootutil/include/bootutil/bootutil_log.h index 5188525f..643fc99b 100644 --- a/boot/bootutil/include/bootutil/bootutil_log.h +++ b/boot/bootutil/include/bootutil/bootutil_log.h @@ -90,7 +90,7 @@ int sim_log_enabled(int level); #define BOOT_LOG_ERR(_fmt, ...) \ do { \ if (sim_log_enabled(BOOT_LOG_LEVEL_ERROR)) { \ - printf("[ERR] " _fmt "\n", ##__VA_ARGS__); \ + fprintf(stderr, "[ERR] " _fmt "\n", ##__VA_ARGS__); \ } \ } while (0) #else @@ -101,7 +101,7 @@ int sim_log_enabled(int level); #define BOOT_LOG_WRN(_fmt, ...) \ do { \ if (sim_log_enabled(BOOT_LOG_LEVEL_WARNING)) { \ - printf("[WRN] " _fmt "\n", ##__VA_ARGS__); \ + fprintf(stderr, "[WRN] " _fmt "\n", ##__VA_ARGS__); \ } \ } while (0) #else @@ -112,7 +112,7 @@ int sim_log_enabled(int level); #define BOOT_LOG_INF(_fmt, ...) \ do { \ if (sim_log_enabled(BOOT_LOG_LEVEL_INFO)) { \ - printf("[INF] " _fmt "\n", ##__VA_ARGS__); \ + fprintf(stderr, "[INF] " _fmt "\n", ##__VA_ARGS__); \ } \ } while (0) #else @@ -123,7 +123,7 @@ int sim_log_enabled(int level); #define BOOT_LOG_DBG(_fmt, ...) \ do { \ if (sim_log_enabled(BOOT_LOG_LEVEL_DEBUG)) { \ - printf("[DBG] " _fmt "\n", ##__VA_ARGS__); \ + fprintf(stderr, "[DBG] " _fmt "\n", ##__VA_ARGS__); \ } \ } while (0) #else From 51d36dd5921ed804814c082b999fe2f60209af23 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Wed, 17 May 2017 17:39:46 -0400 Subject: [PATCH 2/2] sim: add stricter write checking Extend the flash emulation in the simulator to verify that the bootloader explicitly erases flash before writing to it for a second time. Signed-off-by: Marti Bolivar --- sim/src/flash.rs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/sim/src/flash.rs b/sim/src/flash.rs index adbb69a3..125db6c2 100644 --- a/sim/src/flash.rs +++ b/sim/src/flash.rs @@ -36,6 +36,7 @@ fn ewrite>(message: T) -> ErrorKind { #[derive(Clone)] pub struct Flash { data: Vec, + write_safe: Vec, sectors: Vec, // Alignment required for writes. align: usize, @@ -51,6 +52,7 @@ impl Flash { let total = sectors.iter().sum(); Flash { data: vec![0xffu8; total], + write_safe: vec![true; total], sectors: sectors, align: align, } @@ -74,11 +76,21 @@ impl Flash { *x = 0xff; } + for x in &mut self.write_safe[offset .. offset + len] { + *x = true; + } + Ok(()) } - /// Writes are fairly unconstrained, but we restrict to only allowing writes of values that - /// are entirely written as 0xFF. + /// We restrict to only allowing writes of values that are: + /// + /// 1. being written to for the first time + /// 2. being written to after being erased + /// + /// This emulates a flash device which starts out erased, with the + /// added restriction that repeated writes to the same location + /// are disallowed, even if they would be safe to do. pub fn write(&mut self, offset: usize, payload: &[u8]) -> Result<()> { if offset + payload.len() > self.data.len() { panic!("Write outside of device"); @@ -93,13 +105,14 @@ impl Flash { panic!("Write length not multiple of alignment"); } - let mut sub = &mut self.data[offset .. offset + payload.len()]; - for (i, x) in sub.iter().enumerate() { - if *x != 0xFF { - bail!(ewrite(format!("Write to non-FF location at 0x{:x}", offset + i))); + for (i, x) in &mut self.write_safe[offset .. offset + payload.len()].iter_mut().enumerate() { + if !(*x) { + bail!(ewrite(format!("Write to unerased location at 0x{:x}", i))); } + *x = false; } + let mut sub = &mut self.data[offset .. offset + payload.len()]; sub.copy_from_slice(payload); Ok(()) }