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