Update trailer format
This implements changes according to MCUB-14, easing the process
of making external apps parse and read/write the trailer.
Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/boot/bootutil/include/bootutil/bootutil.h b/boot/bootutil/include/bootutil/bootutil.h
index c97fc4c..f128d74 100644
--- a/boot/bootutil/include/bootutil/bootutil.h
+++ b/boot/bootutil/include/bootutil/bootutil.h
@@ -40,6 +40,9 @@
#define BOOT_SWAP_TYPE_FAIL 0xff
+#define MAX_FLASH_ALIGN 8
+extern const uint32_t BOOT_MAX_ALIGN;
+
struct image_header;
/**
* A response object provided by the boot loader code; indicates where to jump
@@ -57,6 +60,17 @@
uint32_t br_image_off;
};
+/* This is not actually used by mcuboot's code but can be used by apps
+ * when attempting to read/write a trailer.
+ */
+struct image_trailer {
+ uint8_t copy_done;
+ uint8_t pad1[MAX_FLASH_ALIGN - 1];
+ uint8_t image_ok;
+ uint8_t pad2[MAX_FLASH_ALIGN - 1];
+ uint8_t magic[16];
+};
+
/* you must have pre-allocated all the entries within this structure */
int boot_go(struct boot_rsp *rsp);
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index 902fe77..5c04c2f 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -20,6 +20,7 @@
#include <assert.h>
#include <string.h>
#include <inttypes.h>
+#include <stddef.h>
#include "sysflash/sysflash.h"
#include "hal/hal_bsp.h"
@@ -43,6 +44,7 @@
};
const uint32_t BOOT_MAGIC_SZ = sizeof boot_img_magic;
+const uint32_t BOOT_MAX_ALIGN = MAX_FLASH_ALIGN;
struct boot_swap_table {
/** * For each field, a value of 0 means "any". */
@@ -164,37 +166,25 @@
uint32_t
boot_slots_trailer_sz(uint8_t min_write_sz)
{
- return BOOT_MAGIC_SZ +
- /* state for all sectors */
+ return /* state for all sectors */
BOOT_STATUS_MAX_ENTRIES * BOOT_STATUS_STATE_COUNT * min_write_sz +
- /* copy_done + image_ok */
- min_write_sz * 2;
+ BOOT_MAX_ALIGN * 2 /* copy_done + image_ok */ +
+ BOOT_MAGIC_SZ;
}
static uint32_t
boot_scratch_trailer_sz(uint8_t min_write_sz)
{
- return BOOT_MAGIC_SZ + /* magic */
- BOOT_STATUS_STATE_COUNT * min_write_sz + /* state for one sector */
- min_write_sz; /* image_ok */
+ return BOOT_STATUS_STATE_COUNT * min_write_sz + /* state for one sector */
+ BOOT_MAX_ALIGN + /* image_ok */
+ BOOT_MAGIC_SZ;
}
static uint32_t
boot_magic_off(const struct flash_area *fap)
{
- uint32_t off_from_end;
- uint8_t elem_sz;
-
- elem_sz = flash_area_align(fap);
-
- if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) {
- off_from_end = boot_scratch_trailer_sz(elem_sz);
- } else {
- off_from_end = boot_slots_trailer_sz(elem_sz);
- }
-
- assert(off_from_end <= fap->fa_size);
- return fap->fa_size - off_from_end;
+ assert(offsetof(struct image_trailer, magic) == 16);
+ return fap->fa_size - BOOT_MAGIC_SZ;
}
int
@@ -214,20 +204,34 @@
uint32_t
boot_status_off(const struct flash_area *fap)
{
- return boot_magic_off(fap) + BOOT_MAGIC_SZ;
+ uint32_t off_from_end;
+ uint8_t elem_sz;
+
+ elem_sz = flash_area_align(fap);
+
+ if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) {
+ off_from_end = boot_scratch_trailer_sz(elem_sz);
+ } else {
+ off_from_end = boot_slots_trailer_sz(elem_sz);
+ }
+
+ assert(off_from_end <= fap->fa_size);
+ return fap->fa_size - off_from_end;
}
static uint32_t
boot_copy_done_off(const struct flash_area *fap)
{
assert(fap->fa_id != FLASH_AREA_IMAGE_SCRATCH);
- return fap->fa_size - flash_area_align(fap) * 2;
+ assert(offsetof(struct image_trailer, copy_done) == 0);
+ return fap->fa_size - BOOT_MAGIC_SZ - BOOT_MAX_ALIGN * 2;
}
static uint32_t
boot_image_ok_off(const struct flash_area *fap)
{
- return fap->fa_size - flash_area_align(fap);
+ assert(offsetof(struct image_trailer, image_ok) == 8);
+ return fap->fa_size - BOOT_MAGIC_SZ - BOOT_MAX_ALIGN;
}
int
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 3f0a68d..3530338 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -40,8 +40,6 @@
#define BOOT_TMPBUF_SZ 256
-#define BOOT_MAX_ALIGN 8
-
/*
* Maintain state of copy progress.
*/
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index bd92df0..dc1e88d 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -471,7 +471,7 @@
uint32_t off;
int area_id;
int rc;
- uint8_t buf[8];
+ uint8_t buf[BOOT_MAX_ALIGN];
uint8_t align;
/* NOTE: The first sector copied (that is the last sector on slot) contains
@@ -498,7 +498,7 @@
BOOT_WRITE_SZ(&boot_data));
align = hal_flash_align(fap->fa_device_id);
- memset(buf, 0xFF, 8);
+ memset(buf, 0xFF, BOOT_MAX_ALIGN);
buf[0] = bs->state;
rc = flash_area_write(fap, off, buf, align);
@@ -945,7 +945,7 @@
/* copy current status that is being maintained in scratch */
rc = boot_copy_sector(FLASH_AREA_IMAGE_SCRATCH, FLASH_AREA_IMAGE_0,
scratch_trailer_off,
- img_off + copy_sz + BOOT_MAGIC_SZ,
+ img_off + copy_sz,
BOOT_STATUS_STATE_COUNT * BOOT_WRITE_SZ(&boot_data));
assert(rc == 0);
diff --git a/sim/src/c.rs b/sim/src/c.rs
index 4de9553..a770ca6 100644
--- a/sim/src/c.rs
+++ b/sim/src/c.rs
@@ -33,6 +33,14 @@
unsafe { raw::sim_flash_align = align };
}
+pub fn boot_magic_sz() -> usize {
+ unsafe { raw::BOOT_MAGIC_SZ as usize }
+}
+
+pub fn boot_max_align() -> usize {
+ unsafe { raw::BOOT_MAX_ALIGN as usize }
+}
+
mod raw {
use area::CAreaDesc;
use libc;
@@ -46,5 +54,8 @@
pub static mut sim_flash_align: u8;
pub fn boot_slots_trailer_sz(min_write_sz: u8) -> u32;
+
+ pub static BOOT_MAGIC_SZ: u32;
+ pub static BOOT_MAX_ALIGN: u32;
}
}
diff --git a/sim/src/main.rs b/sim/src/main.rs
index d970ef2..086cc21 100644
--- a/sim/src/main.rs
+++ b/sim/src/main.rs
@@ -220,11 +220,10 @@
// Set an alignment, and position the magic value.
c::set_sim_flash_align(align);
- let trailer_size = c::boot_trailer_sz();
// Mark the upgrade as ready to install. (This looks like it might be a bug in the code,
// however.)
- mark_upgrade(&mut flash, scratch_base - trailer_size as usize);
+ mark_upgrade(&mut flash, scratch_base - c::boot_magic_sz() as usize);
let (fl2, total_count) = try_upgrade(&flash, &areadesc, None);
info!("First boot, count={}", total_count);
@@ -324,7 +323,7 @@
let ok = [1u8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
let (base, _) = areadesc.find(FlashId::ImageScratch);
let align = c::get_sim_flash_align() as usize;
- fl.write(base - align, &ok[..align]).unwrap();
+ fl.write(base - c::boot_magic_sz() - c::boot_max_align(), &ok[..align]).unwrap();
c::set_flash_counter(stop.unwrap_or(0));
let (first_interrupted, cnt1) = match c::boot_go(&mut fl, &areadesc) {
@@ -369,7 +368,8 @@
// Write boot_ok
let ok = [1u8, 0, 0, 0, 0, 0, 0, 0];
let (slot0_base, slot0_len) = areadesc.find(FlashId::Image0);
- fl.write(slot0_base + slot0_len - align, &ok[..align]).unwrap();
+ fl.write(slot0_base + slot0_len - c::boot_magic_sz() - c::boot_max_align(),
+ &ok[..align]).unwrap();
assert_eq!(c::boot_go(&mut fl, &areadesc), 0);
fl
}
@@ -382,7 +382,7 @@
let ok = [1u8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
let (base, _) = areadesc.find(FlashId::ImageScratch);
let align = c::get_sim_flash_align() as usize;
- fl.write(base - align, &ok[..align]).unwrap();
+ fl.write(base - c::boot_magic_sz() - c::boot_max_align(), &ok[..align]).unwrap();
let mut rng = rand::thread_rng();
let mut resets = vec![0i32; count];