From ec24ea49b19b501cef3cde1e84dd53ed358db7a9 Mon Sep 17 00:00:00 2001 From: Francisco Acosta Date: Thu, 18 Oct 2018 19:09:00 +0200 Subject: [PATCH] riotboot: add support for multislot riotboot looks for valid, available slots and compares its version. The slot with the highest version is booted, otherwise if no valid slot is found it loops on `while(1);` --- bootloaders/riotboot/main.c | 23 ++++++++++++++++++---- makefiles/boot/riotboot.mk | 39 ++++++++++++++++++++++++++++--------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/bootloaders/riotboot/main.c b/bootloaders/riotboot/main.c index ce6914296c..8ee9268c0b 100644 --- a/bootloaders/riotboot/main.c +++ b/bootloaders/riotboot/main.c @@ -27,14 +27,29 @@ void kernel_init(void) { - /* bootloader boots only slot 0 if it is valid */ - unsigned slot = 0; + uint32_t version = 0; + int slot = -1; - if (riotboot_slot_validate(slot) == 0) { + for (unsigned i = 0; i < riotboot_slot_numof; i++) { + const riotboot_hdr_t *riot_hdr = riotboot_slot_get_hdr(i); + if (riotboot_slot_validate(i)) { + /* skip slot if metadata broken */ + continue; + } + if (riot_hdr->start_addr != riotboot_slot_get_image_startaddr(i)) { + continue; + } + if (slot == -1 || riot_hdr->version > version) { + version = riot_hdr->version; + slot = i; + } + } + + if (slot != -1) { riotboot_slot_jump(slot); } - /* serious trouble! */ + /* serious trouble! nothing to boot */ while (1) {} } diff --git a/makefiles/boot/riotboot.mk b/makefiles/boot/riotboot.mk index ab0c6e63fa..ff770e4c63 100644 --- a/makefiles/boot/riotboot.mk +++ b/makefiles/boot/riotboot.mk @@ -1,6 +1,6 @@ ifneq (,$(filter riotboot,$(FEATURES_USED))) -.PHONY: riotboot/flash riotboot/flash-bootloader riotboot/flash-slot0 riotboot/bootloader/% +.PHONY: riotboot/flash riotboot/flash-bootloader riotboot/flash-slot0 riotboot/flash-slot1 riotboot/bootloader/% RIOTBOOT_DIR = $(RIOTBASE)/bootloaders/riotboot RIOTBOOT ?= $(RIOTBOOT_DIR)/bin/$(BOARD)/riotboot.elf @@ -17,30 +17,40 @@ RIOTBOOT_HDR_LEN ?= 0x100 # Export variables for 'riotboot_slot' export SLOT0_LEN +export SLOT1_LEN +export NUM_SLOTS -# By default, slot 0 is found just after RIOTBOOT_LEN. It might -# be overridden to add more offset as needed. +# By default, slot 0 is found just after RIOTBOOT_LEN. Slot 1 after +# slot 0. The values might be overridden to add more or less offset +# if needed. export SLOT0_OFFSET ?= $(RIOTBOOT_LEN) +# export does not work properly with variables using '$(( ))' so evaluate it in a shell +export SLOT1_OFFSET ?= $(shell echo $$(($(SLOT0_OFFSET) + $(SLOT0_LEN)))) # Mandatory APP_VER, set to 0 by default APP_VER ?= 0 # Final target for slot 0 with riot_hdr SLOT0_RIOT_BIN = $(BINDIR_APP)-slot0.riot.bin +SLOT1_RIOT_BIN = $(BINDIR_APP)-slot1.riot.bin +SLOT_RIOT_BINS = $(SLOT0_RIOT_BIN) $(SLOT1_RIOT_BIN) # For slot generation only link is needed $(BINDIR_APP)-%.elf: link $(Q)$(_LINK) -o $@ -# Slot 0 firmware offset, after header -SLOT0_IMAGE_OFFSET := $$(($(RIOTBOOT_LEN) + $(RIOTBOOT_HDR_LEN))) +# Slot 0 and 1 firmware offset, after header +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) # Create binary target with RIOT header -$(SLOT0_RIOT_BIN): %.riot.bin: %.hdr %.bin +$(SLOT_RIOT_BINS): %.riot.bin: %.hdr %.bin @echo "creating $@..." $(Q)cat $^ > $@ @@ -60,9 +70,10 @@ $(HEADER_TOOL): 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) -# Generic target to create a binary file from the image with header -riotboot: $(SLOT0_RIOT_BIN) +# Generic target to create a binary files for both slots +riotboot: $(SLOT_RIOT_BINS) # riotboot bootloader compile target riotboot/flash-bootloader: riotboot/bootloader/flash @@ -108,8 +119,18 @@ riotboot/flash-slot0: ELFFILE=$(SLOT0_RIOT_BIN) riotboot/flash-slot0: $(SLOT0_RIOT_BIN) $(FLASHDEPS) $(FLASHER) $(FFLAGS) -# Targets to generate only slot 0 binary +# Flashing rule for slot 1 +riotboot/flash-slot1: export IMAGE_OFFSET=$(SLOT1_OFFSET) +# Flashing rule for edbg to flash only slot 1 +riotboot/flash-slot1: HEXFILE=$(SLOT1_RIOT_BIN) +# openocd +riotboot/flash-slot1: ELFFILE=$(SLOT1_RIOT_BIN) +riotboot/flash-slot1: $(SLOT1_RIOT_BIN) $(FLASHDEPS) + $(FLASHER) $(FFLAGS) + +# Targets to generate only slots binary riotboot/slot0: $(SLOT0_RIOT_BIN) +riotboot/slot1: $(SLOT1_RIOT_BIN) # Default flashing rule for bootloader + slot 0 riotboot/flash: riotboot/flash-slot0 riotboot/flash-bootloader