Allow passing in `--overwrite-only` flag
Overwrite only requires just magic + image_ok + copy_done. This fixes
issues generating images in overwrite only mode when the firmware image
is too big and overflows the swap status area.
Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/scripts/imgtool.py b/scripts/imgtool.py
index f3bd016..ccac193 100755
--- a/scripts/imgtool.py
+++ b/scripts/imgtool.py
@@ -114,6 +114,8 @@
@click.argument('outfile')
@click.argument('infile')
+@click.option('--overwrite-only', default=False, is_flag=True,
+ help='Use overwrite-only instead of swap upgrades')
@click.option('-M', '--max-sectors', type=int,
help='When padding allow for this amount of sectors (defaults to 128)')
@click.option('--pad', default=False, is_flag=True,
@@ -129,12 +131,13 @@
@click.option('-k', '--key', metavar='filename')
@click.command(help='Create a signed or unsigned image')
def sign(key, align, version, header_size, included_header, slot_size, pad,
- max_sectors, infile, outfile):
+ max_sectors, overwrite_only, infile, outfile):
img = image.Image.load(infile, version=decode_version(version),
header_size=header_size,
included_header=included_header, pad=pad,
align=int(align), slot_size=slot_size,
- max_sectors=max_sectors)
+ max_sectors=max_sectors,
+ overwrite_only=overwrite_only)
key = load_key(key) if key else None
img.sign(key)
diff --git a/scripts/imgtool/image.py b/scripts/imgtool/image.py
index bb7a1f6..ea318f7 100644
--- a/scripts/imgtool/image.py
+++ b/scripts/imgtool/image.py
@@ -85,24 +85,27 @@
return obj
def __init__(self, version=None, header_size=IMAGE_HEADER_SIZE, pad=0,
- align=1, slot_size=0, max_sectors=DEFAULT_MAX_SECTORS):
+ align=1, slot_size=0, max_sectors=DEFAULT_MAX_SECTORS,
+ overwrite_only=False):
self.version = version or versmod.decode_version("0")
self.header_size = header_size or IMAGE_HEADER_SIZE
self.pad = pad
self.align = align
self.slot_size = slot_size
self.max_sectors = max_sectors
+ self.overwrite_only = overwrite_only
def __repr__(self):
return "<Image version={}, header_size={}, base_addr={}, \
- align={}, slot_size={}, max_sectors={}, format={}, \
- payloadlen=0x{:x}>".format(
+ align={}, slot_size={}, max_sectors={}, overwrite_only={}, \
+ format={}, payloadlen=0x{:x}>".format(
self.version,
self.header_size,
self.base_addr if self.base_addr is not None else "N/A",
self.align,
self.slot_size,
self.max_sectors,
+ self.overwrite_only,
self.__class__.__name__,
len(self.payload))
@@ -114,7 +117,8 @@
if any(v != 0 for v in self.payload[0:self.header_size]):
raise Exception("Padding requested, but image does not start with zeros")
if self.slot_size > 0:
- tsize = self._trailer_size(self.align, self.max_sectors)
+ tsize = self._trailer_size(self.align, self.max_sectors,
+ self.overwrite_only)
padding = self.slot_size - (len(self.payload) + tsize)
if padding < 0:
msg = "Image size (0x{:x}) + trailer (0x{:x}) exceeds requested size 0x{:x}".format(
@@ -181,16 +185,20 @@
self.payload = bytearray(self.payload)
self.payload[:len(header)] = header
- def _trailer_size(self, write_size, max_sectors):
+ def _trailer_size(self, write_size, max_sectors, overwrite_only):
# NOTE: should already be checked by the argument parser
- if write_size not in set([1, 2, 4, 8]):
- raise Exception("Invalid alignment: {}".format(write_size))
- m = DEFAULT_MAX_SECTORS if max_sectors is None else max_sectors
- return m * 3 * write_size + 8 * 2 + 16
+ if overwrite_only:
+ return 8 * 2 + 16
+ else:
+ if write_size not in set([1, 2, 4, 8]):
+ raise Exception("Invalid alignment: {}".format(write_size))
+ m = DEFAULT_MAX_SECTORS if max_sectors is None else max_sectors
+ return m * 3 * write_size + 8 * 2 + 16
def pad_to(self, size):
"""Pad the image to the given size, with the given flash alignment."""
- tsize = self._trailer_size(self.align, self.max_sectors)
+ tsize = self._trailer_size(self.align, self.max_sectors,
+ self.overwrite_only)
padding = size - (len(self.payload) + tsize)
pbytes = b'\xff' * padding
pbytes += b'\xff' * (tsize - len(boot_magic))