diff --git a/Makefile b/Makefile index 6bf1218..70afe3a 100644 --- a/Makefile +++ b/Makefile @@ -40,15 +40,24 @@ endif ifeq ($(RBOOT_RTC_ENABLED),1) CFLAGS += -DBOOT_RTC_ENABLED endif +ifeq ($(RBOOT_CONFIG_CUSTOM),1) + CFLAGS += -DBOOT_CONFIG_CUSTOM +endif ifeq ($(RBOOT_CONFIG_CHKSUM),1) CFLAGS += -DBOOT_CONFIG_CHKSUM endif +ifeq ($(RBOOT_CONFIG_DEFAULTS),1) + CFLAGS += -DBOOT_CONFIG_DEFAULTS +endif ifeq ($(RBOOT_GPIO_ENABLED),1) CFLAGS += -DBOOT_GPIO_ENABLED endif ifneq ($(RBOOT_GPIO_NUMBER),) CFLAGS += -DBOOT_GPIO_NUM=$(RBOOT_GPIO_NUMBER) endif +ifeq ($(RBOOT_FALLBACK_ENABLED),1) + CFLAGS += -DBOOT_FALLBACK_ENABLED +endif ifeq ($(RBOOT_IROM_CHKSUM),1) CFLAGS += -DBOOT_IROM_CHKSUM endif diff --git a/rboot.c b/rboot.c index 0e95db5..87d7e1d 100644 --- a/rboot.c +++ b/rboot.c @@ -364,9 +364,13 @@ uint32 NOINLINE find_image(void) { ets_memset(romconf, 0x00, sizeof(rboot_config)); romconf->magic = BOOT_CONFIG_MAGIC; romconf->version = BOOT_CONFIG_VERSION; +#ifndef BOOT_CONFIG_DEFAULTS romconf->count = 2; romconf->roms[0] = SECTOR_SIZE * (BOOT_CONFIG_SECTOR + 1); romconf->roms[1] = (flashsize / 2) + (SECTOR_SIZE * (BOOT_CONFIG_SECTOR + 1)); +#else + set_defaults(romconf); +#endif #ifdef BOOT_CONFIG_CHKSUM romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum); #endif @@ -417,9 +421,18 @@ uint32 NOINLINE find_image(void) { // check valid rom number // gpio/temp boots will have already validated this if (romconf->current_rom >= romconf->count) { - // if invalid rom selected try rom 0 - ets_printf("Invalid rom selected, defaulting to 0.\r\n"); - romToBoot = 0; + // if invalid rom selected try rom 0 or fallback if enabled +#ifdef BOOT_FALLBACK_ENABLED + if (romconf->mode & MODE_FALLBACK) { + ets_printf("Invalid rom selected, defaulting to fallback.\r\n"); + romToBoot = romconf->fallback_rom; + } else { +#endif + ets_printf("Invalid rom selected, defaulting to 0.\r\n"); + romToBoot = 0; +#ifdef BOOT_FALLBACK_ENABLED + } +#endif romconf->current_rom = 0; updateConfig = TRUE; } @@ -452,13 +465,36 @@ uint32 NOINLINE find_image(void) { // for normal mode try each previous rom // until we find a good one or run out updateConfig = TRUE; - romToBoot--; - if (romToBoot < 0) romToBoot = romconf->count - 1; - if (romToBoot == romconf->current_rom) { - // tried them all and all are bad! - ets_printf("No good rom available.\r\n"); - return 0; +#ifdef BOOT_FALLBACK_ENABLED + if (romconf->mode & MODE_FALLBACK) { + if (romToBoot == romconf->fallback_rom) { + // tried them all incl. fallback and all are bad! + ets_printf("No good rom available.\r\n"); + return 0; + } + romToBoot--; + if (romToBoot < 0) romToBoot = romconf->count - 1; + if (romToBoot == romconf->fallback_rom) { + // skip fallback rom in sequence (try as last resort only) + romToBoot--; + if (romToBoot < 0) romToBoot = romconf->count - 1; + } + if (romToBoot == romconf->current_rom) { + // tried them all and all are bad! -> now try fallback rom + romToBoot = romconf->fallback_rom; + } + } else { +#endif + romToBoot--; + if (romToBoot < 0) romToBoot = romconf->count - 1; + if (romToBoot == romconf->current_rom) { + // tried them all and all are bad! + ets_printf("No good rom available.\r\n"); + return 0; + } +#ifdef BOOT_FALLBACK_ENABLED } +#endif runAddr = check_image(romconf->roms[romToBoot]); } diff --git a/rboot.h b/rboot.h index 3981c37..a4a1fec 100644 --- a/rboot.h +++ b/rboot.h @@ -34,6 +34,9 @@ extern "C" { // when BOOT_GPIO_ENABLED is enabled //#define BOOT_GPIO_NUM 16 +// uncomment to enable FALLBACK booting +//#define BOOT_FALLBACK_ENABLED + // uncomment to include .irom0.text section in the checksum // roms must be built with esptool2 using -iromchksum option //#define BOOT_IROM_CHKSUM @@ -63,6 +66,7 @@ extern "C" { #define MODE_GPIO_ROM 0x01 #define MODE_TEMP_ROM 0x02 #define MODE_GPIO_ERASES_SDKCONFIG 0x04 +#define MODE_FALLBACK 0x08 #define RBOOT_RTC_MAGIC 0x2334ae68 #define RBOOT_RTC_READ 1 @@ -95,8 +99,12 @@ typedef struct { uint8 current_rom; ///< Currently selected ROM (will be used for next standard boot) uint8 gpio_rom; ///< ROM to use for GPIO boot (hardware switch) with mode set to MODE_GPIO_ROM uint8 count; ///< Quantity of ROMs available to boot - uint8 unused[2]; ///< Padding (not used) + uint8 fallback_rom; ///< ROM to use for fallback with mode set to MODE_FALLBACK + uint8 unused[1]; ///< Padding (not used) uint32 roms[MAX_ROMS]; ///< Flash addresses of each ROM +#ifdef BOOT_CONFIG_CUSTOM + rboot_custom_config custom[MAX_ROMS]; +#endif #ifdef BOOT_CONFIG_CHKSUM uint8 chksum; ///< Checksum of this configuration structure (if BOOT_CONFIG_CHKSUM defined) #endif