Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

makefiles: allow to override suit manifest payloads #16771

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ HEXFILE ?= $(ELFFILE:.elf=.hex)
BINFILE ?= $(ELFFILE:.elf=.bin)
MAPFILE ?= $(ELFFILE:.elf=.map)

ifneq (,$(filter suit, $(USEMODULE)))
ifneq (,$(filter suit,$(USEMODULE)))
include $(RIOTMAKE)/suit.base.inc.mk
endif

Expand All @@ -663,6 +663,11 @@ endif
# It should be included after defining 'BINFILE' for 'riotboot.bin' handling.
include $(RIOTMAKE)/boot/riotboot.mk

# include suit targets
ifneq (,$(filter suit,$(USEMODULE)))
include $(RIOTMAKE)/suit.inc.mk
endif

# Targets to get given file
elffile: $(ELFFILE)
hexfile: $(HEXFILE)
Expand Down
30 changes: 8 additions & 22 deletions examples/suit_update/README.hardware.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ If this optional step is skipped then `SUIT_COAP_SERVER` will be
the link local address of the `bt0` interface and `SUIT_CLIENT` will be
the link local address of the device, with the interface specified. e.g:


SUIT_COAP_SERVER=[fe80::19:86ff:fe00:16ca]
SUIT_CLIENT=[fe80::e4dd:e0ff:fe8f:7365%bt0]

Expand Down Expand Up @@ -306,10 +305,10 @@ see 6 pairs of messages indicating where (filepath) the file was published and
the corresponding coap resource URI

...
published "/home/francisco/workspace/RIOT/examples/suit_update/bin/samr21-xpro/suit_update-riot.suitv3_signed.1557135946.bin"
as "coap://[2001:db8::1]/fw/samr21-xpro/suit_update-riot.suitv3_signed.1557135946.bin"
published "/home/francisco/workspace/RIOT/examples/suit_update/bin/samr21-xpro/suit_update-riot.suitv3_signed.latest.bin"
as "coap://[2001:db8::1]/fw/samr21-xpro/suit_update-riot.suitv3_signed.latest.bin"
published "${RIOTBASE}/examples/suit_update/bin/samr21-xpro/suit_files/riot.suit.1632124156.bin"
as "coap://[2001:db8::1]/fw/suit_update/samr21-xpro/riot.suit.1632124156.bin"
published "${RIOTBASE}/examples/suit_update/bin/samr21-xpro/suit_files/riot.suit.latest.bin"
as "coap://[2001:db8::1]/fw/suit_update/samr21-xpro/riot.suit.latest.bin"
...

### Notify an update to the device
Expand Down Expand Up @@ -497,19 +496,6 @@ When a new manifest url is received on the trigger resource a message is resent
to the coap thread with the manifest's url. The thread will then fetch the
manifest by a block coap request to the specified url.

- **support for v3**

This includes v3 manifest support. When a url is received in the /suit/trigger
coap resource it will trigger a coap blockwise fetch of the manifest. When this
manifest is received it will be parsed. The signature of the manifest will be
verified and then the rest of the manifest content. If the received manifest is valid it
will extract the url for the firmware location from the manifest.

It will then fetch the firmware, write it to the inactive slot and reboot the device.
Digest validation is done once all the firmware is written to flash.
From there the bootloader takes over, verifying the slot riotboot_hdr and boots
from the newest image.

#### Key Generation

To sign the manifest and for the device to verify the manifest a pair of keys
Expand Down Expand Up @@ -574,10 +560,10 @@ The following variables are defined in makefiles/suit.inc.mk:

The following convention is used when naming a manifest

SUIT_MANIFEST ?= $(BINDIR_APP)-riot.suitv3.$(APP_VER).bin
SUIT_MANIFEST_LATEST ?= $(BINDIR_APP)-riot.suitv3.latest.bin
SUIT_MANIFEST_SIGNED ?= $(BINDIR_APP)-riot.suitv3_signed.$(APP_VER).bin
SUIT_MANIFEST_SIGNED_LATEST ?= $(BINDIR_APP)-riot.suitv3_signed.latest.bin
SUIT_MANIFEST ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME)_unsigned.$(APP_VER).bin
SUIT_MANIFEST_LATEST ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME)_unsigned.latest.bin
SUIT_MANIFEST_SIGNED ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME).$(APP_VER).bin
SUIT_MANIFEST_SIGNED_LATEST ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME).latest.bin

The following default values are using for generating the manifest:

Expand Down
38 changes: 18 additions & 20 deletions makefiles/boot/riotboot.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,29 @@ CFLAGS += -I$(BINDIR)/riotbuild

HEADER_TOOL_DIR = $(RIOTBASE)/dist/tools/riotboot_gen_hdr
HEADER_TOOL ?= $(HEADER_TOOL_DIR)/bin/genhdr
BINDIR_APP = $(BINDIR)/$(APPLICATION)
BINDIR_RIOTBOOT = $(BINDIR)/riotboot_files

$(BINDIR_RIOTBOOT): $(CLEAN)
$(Q)mkdir -p $(BINDIR_RIOTBOOT)

#
export SLOT0_OFFSET SLOT0_LEN SLOT1_OFFSET SLOT1_LEN

# Mandatory APP_VER, set to epoch by default
EPOCH := $(shell date +%s)
EPOCH = $(call memoized,EPOCH,$(shell date +%s))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reasoning behind that change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoiding a shell call if not used

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can split

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine, I was just not familiar with call memoized

APP_VER ?= $(EPOCH)

# Final target for slot 0 with riot_hdr
SLOT0_RIOT_BIN = $(BINDIR_APP)-slot0.$(APP_VER).riot.bin
SLOT1_RIOT_BIN = $(BINDIR_APP)-slot1.$(APP_VER).riot.bin
SLOT0_RIOT_BIN = $(BINDIR_RIOTBOOT)/slot0.$(APP_VER).bin
SLOT1_RIOT_BIN = $(BINDIR_RIOTBOOT)/slot1.$(APP_VER).bin
benpicco marked this conversation as resolved.
Show resolved Hide resolved
SLOT_RIOT_BINS = $(SLOT0_RIOT_BIN) $(SLOT1_RIOT_BIN)

# if RIOTBOOT_SKIP_COMPILE is set to 1, "make riotboot/slot[01](-flash)"
# will not depend on the base elf files, thus skipping the compilation step.
# This results in the equivalent to "make flash-only" for
# "make riotboot/flash-slot[01]".
ifneq (1, $(RIOTBOOT_SKIP_COMPILE))
$(BINDIR_APP)-%.elf: $(BASELIBS) $(ARCHIVES)
fjmolinas marked this conversation as resolved.
Show resolved Hide resolved
$(BINDIR_RIOTBOOT)/%.elf: $(BASELIBS) $(ARCHIVES) $(BINDIR_RIOTBOOT)
$(Q)$(_LINK) -o $@
endif

Expand All @@ -37,19 +40,19 @@ SLOT0_IMAGE_OFFSET := $$(($(SLOT0_OFFSET) + $(RIOTBOOT_HDR_LEN)))
SLOT1_IMAGE_OFFSET := $$(($(SLOT1_OFFSET) + $(RIOTBOOT_HDR_LEN)))

# Link slots ELF *after* riot_hdr and limit the ROM to the slots length
$(BINDIR_APP)-slot0.elf: FW_ROM_LEN=$$((SLOT0_LEN - $(RIOTBOOT_HDR_LEN)))
$(BINDIR_APP)-slot0.elf: ROM_OFFSET=$(SLOT0_IMAGE_OFFSET)
$(BINDIR_APP)-slot1.elf: FW_ROM_LEN=$$((SLOT1_LEN - $(RIOTBOOT_HDR_LEN)))
$(BINDIR_APP)-slot1.elf: ROM_OFFSET=$(SLOT1_IMAGE_OFFSET)
SLOT_RIOT_ELFS = $(BINDIR_APP)-slot0.elf $(BINDIR_APP)-slot1.elf
$(BINDIR_RIOTBOOT)/slot0.elf: FW_ROM_LEN=$$((SLOT0_LEN - $(RIOTBOOT_HDR_LEN)))
$(BINDIR_RIOTBOOT)/slot0.elf: ROM_OFFSET=$(SLOT0_IMAGE_OFFSET)
$(BINDIR_RIOTBOOT)/slot1.elf: FW_ROM_LEN=$$((SLOT1_LEN - $(RIOTBOOT_HDR_LEN)))
$(BINDIR_RIOTBOOT)/slot1.elf: ROM_OFFSET=$(SLOT1_IMAGE_OFFSET)
SLOT_RIOT_ELFS = $(BINDIR_RIOTBOOT)/slot0.elf $(BINDIR_RIOTBOOT)/slot1.elf

# ensure both slot elf files are always linked
# this ensures that both "make test" and "make test-murdock" can rely on them
# being present without having to trigger re-compilation.
BUILD_FILES += $(SLOT_RIOT_ELFS)

# Create binary target with RIOT header
$(SLOT_RIOT_BINS): %.$(APP_VER).riot.bin: %.hdr %.bin
$(SLOT_RIOT_BINS): %.$(APP_VER).bin: %.hdr %.bin
@echo "creating $@..."
$(Q)cat $^ > $@

Expand All @@ -68,8 +71,8 @@ $(HEADER_TOOL): FORCE
%.hdr: $(HEADER_TOOL) %.bin FORCE
$(Q)$(HEADER_TOOL) generate $< $(APP_VER) $$(($(ROM_START_ADDR)+$(OFFSET))) $(RIOTBOOT_HDR_LEN) - > $@

$(BINDIR_APP)-slot0.hdr: OFFSET=$(SLOT0_IMAGE_OFFSET)
$(BINDIR_APP)-slot1.hdr: OFFSET=$(SLOT1_IMAGE_OFFSET)
$(BINDIR_RIOTBOOT)/slot0.hdr: OFFSET=$(SLOT0_IMAGE_OFFSET)
$(BINDIR_RIOTBOOT)/slot1.hdr: OFFSET=$(SLOT1_IMAGE_OFFSET)

# Generic target to create a binary files for both slots
riotboot: $(SLOT_RIOT_BINS)
Expand Down Expand Up @@ -104,12 +107,12 @@ ifneq ($(BOOTLOADER_BIN)/riotboot.bin,$(BINFILE))
endif

# Create combined binary booloader + RIOT firmware with header
RIOTBOOT_COMBINED_BIN = $(BINDIR_APP)-slot0-combined.bin
RIOTBOOT_COMBINED_BIN = $(BINDIR_RIOTBOOT)/slot0-combined.bin
riotboot/combined-slot0: $(RIOTBOOT_COMBINED_BIN)
$(RIOTBOOT_COMBINED_BIN): $(BOOTLOADER_BIN)/riotboot.extended.bin $(SLOT0_RIOT_BIN)
$(Q)cat $^ > $@

RIOTBOOT_EXTENDED_BIN = $(BINDIR_APP)-slot0-extended.bin
RIOTBOOT_EXTENDED_BIN = $(BINDIR_RIOTBOOT)/slot0-extended.bin

# Generate a binary file from slot 0 which covers slot 1 riot_hdr
# in order to invalidate slot 1
Expand Down Expand Up @@ -154,11 +157,6 @@ riotboot/flash: riotboot/flash-slot0 riotboot/flash-bootloader
# It also makes 'flash' and 'flash-only' work without specific command.
FLASHFILE = $(RIOTBOOT_EXTENDED_BIN)

# include suit targets
ifneq (,$(filter suit, $(USEMODULE)))
include $(RIOTMAKE)/suit.inc.mk
endif

else
riotboot:
$(Q)echo "error: riotboot feature not selected! (try FEATURES_REQUIRED += riotboot)"
Expand Down
45 changes: 27 additions & 18 deletions makefiles/suit.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,54 @@
# makefiles/suit.base.inc.mk
#
#
SUIT_COAP_BASEPATH ?= fw/$(BOARD)

# Mandatory APP_VER, set to epoch by default
EPOCH = $(call memoized,EPOCH,$(shell date +%s))
APP_VER ?= $(EPOCH)

SUIT_VENDOR ?= "riot-os.org"
SUIT_SEQNR ?= $(APP_VER)
SUIT_CLASS ?= $(BOARD)

SUIT_COAP_BASEPATH ?= fw/$(APPLICATION)/$(BOARD)
SUIT_COAP_SERVER ?= localhost
SUIT_COAP_ROOT ?= coap://$(SUIT_COAP_SERVER)/$(SUIT_COAP_BASEPATH)
SUIT_COAP_FSROOT ?= $(RIOTBASE)/coaproot

BINDIR_SUIT = $(BINDIR)/suit_files
$(BINDIR_SUIT): $(CLEAN)
$(Q)mkdir -p $(BINDIR_SUIT)

#
SUIT_MANIFEST ?= $(BINDIR_APP)-riot.suit.$(APP_VER).bin
SUIT_MANIFEST_LATEST ?= $(BINDIR_APP)-riot.suit.latest.bin
SUIT_MANIFEST_SIGNED ?= $(BINDIR_APP)-riot.suit_signed.$(APP_VER).bin
SUIT_MANIFEST_SIGNED_LATEST ?= $(BINDIR_APP)-riot.suit_signed.latest.bin
SUIT_MANIFEST_BASENAME ?= riot.suit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getting the application name back in here should fix the overwriting for different applications?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, I added the application name to SUIT_COAP_BASEPATH, that way they can override each other while still keeping simple consistent file names.

SUIT_MANIFEST ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME)_unsigned.$(SUIT_SEQNR).bin
SUIT_MANIFEST_LATEST ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME)_unsigned.latest.bin
SUIT_MANIFEST_SIGNED ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME).$(SUIT_SEQNR).bin
SUIT_MANIFEST_SIGNED_LATEST ?= $(BINDIR_SUIT)/$(SUIT_MANIFEST_BASENAME).latest.bin

SUIT_NOTIFY_VERSION ?= latest
SUIT_NOTIFY_MANIFEST ?= $(APPLICATION)-riot.suit_signed.$(SUIT_NOTIFY_VERSION).bin
SUIT_NOTIFY_MANIFEST ?= $(SUIT_MANIFEST_BASENAME).$(SUIT_NOTIFY_VERSION).bin

# Long manifest names require more buffer space when parsing
export CFLAGS += -DCONFIG_SOCK_URLPATH_MAXLEN=128

SUIT_VENDOR ?= "riot-os.org"
SUIT_SEQNR ?= $(APP_VER)
SUIT_CLASS ?= $(BOARD)
SUIT_MANIFEST_PAYLOADS ?= $(SLOT0_RIOT_BIN) $(SLOT1_RIOT_BIN)
SUIT_MANIFEST_SLOTFILES ?= $(SLOT0_RIOT_BIN):$(SLOT0_OFFSET) \
$(SLOT1_RIOT_BIN):$(SLOT1_OFFSET)

#
$(SUIT_MANIFEST): $(SLOT0_RIOT_BIN) $(SLOT1_RIOT_BIN)
$(SUIT_MANIFEST): $(SUIT_MANIFEST_PAYLOADS) $(BINDIR_SUIT)
$(Q)$(RIOTBASE)/dist/tools/suit/gen_manifest.py \
--urlroot $(SUIT_COAP_ROOT) \
--seqnr $(SUIT_SEQNR) \
--uuid-vendor $(SUIT_VENDOR) \
--uuid-class $(SUIT_CLASS) \
-o [email protected] \
$(SLOT0_RIOT_BIN):$(SLOT0_OFFSET) \
$(SLOT1_RIOT_BIN):$(SLOT1_OFFSET)
$(SUIT_MANIFEST_SLOTFILES)

$(Q)$(SUIT_TOOL) create -f suit -i [email protected] -o $@

$(Q)rm -f [email protected]


$(SUIT_MANIFEST_SIGNED): $(SUIT_MANIFEST) $(SUIT_SEC)
$(Q)$(SUIT_TOOL) sign -k $(SUIT_SEC) -m $(SUIT_MANIFEST) -o $@

Expand All @@ -50,14 +61,12 @@ $(SUIT_MANIFEST_LATEST): $(SUIT_MANIFEST)
$(SUIT_MANIFEST_SIGNED_LATEST): $(SUIT_MANIFEST_SIGNED)
$(Q)ln -f -s $< $@

SUIT_MANIFESTS := $(SUIT_MANIFEST) \
$(SUIT_MANIFEST_LATEST) \
$(SUIT_MANIFEST_SIGNED) \
SUIT_MANIFESTS := $(SUIT_MANIFEST_SIGNED) \
$(SUIT_MANIFEST_SIGNED_LATEST)

suit/manifest: $(SUIT_MANIFESTS)

suit/publish: $(SUIT_MANIFESTS) $(SLOT0_RIOT_BIN) $(SLOT1_RIOT_BIN)
suit/publish: $(SUIT_MANIFESTS) $(SUIT_MANIFEST_PAYLOADS)
$(Q)mkdir -p $(SUIT_COAP_FSROOT)/$(SUIT_COAP_BASEPATH)
$(Q)cp $^ $(SUIT_COAP_FSROOT)/$(SUIT_COAP_BASEPATH)
$(Q)for file in $^; do \
Expand Down
2 changes: 1 addition & 1 deletion tests/riotboot_flashwrite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ number:
Then send via CoAP, for example, with libcoap's coap_client:

$ coap-client -m post coap://[<ip address of node>]/flashwrite \
-f bin/<board>/tests_riotboot_flashwrite-slot1.riot.bin -b 64
-f bin/<board>/riotboot_files/slot1.bin -b 64

Then reboot the node manually, confirming that it booted from slot 1.
2 changes: 1 addition & 1 deletion tests/riotboot_flashwrite/tests-with-config/01-run.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def make_notify(client_url, slot, version):
"POST",
"coap://{}/flashwrite".format(client_url),
"--payload",
"@tests_riotboot_flashwrite-slot{}.{}.riot.bin".format(slot, version),
"@riotboot_files/slot{}.{}.bin".format(slot, version),
"--payload-initial-szx",
"2",
]
Expand Down