diff --git a/bootloaders/eboot/Makefile b/bootloaders/eboot/Makefile index 7f035dd1e7..4b2886563a 100644 --- a/bootloaders/eboot/Makefile +++ b/bootloaders/eboot/Makefile @@ -21,7 +21,7 @@ OBJDUMP := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-objdump INC += -I../../tools/sdk/include -I../../tools/sdk/uzlib/src -CFLAGS += -std=gnu99 +CFLAGS += -std=gnu99 -DEBOOT_ENABLE_FLASH_STORAGE CFLAGS += -Os -fcommon -g -Wall -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals -ffunction-sections -fdata-sections -free -fipa-pta diff --git a/bootloaders/eboot/README.md b/bootloaders/eboot/README.md new file mode 100755 index 0000000000..f02fefd7c2 --- /dev/null +++ b/bootloaders/eboot/README.md @@ -0,0 +1,47 @@ +eboot Bootloader +================ + + +A simple bootloader which can copy an OTA update to main application address in flash and load the application code to IRAM. + +# Contents +- [Startup sequence](#startup-sequence) + + +### Startup sequence ### + +On startup the ESP ROM will [load and start the firmware image](#load-and-start) from flash location 0x0 - eboot. + +##### eboot will ##### +1. print a version string from the current firmware image +2. [attempt to read a command](#read-eboot-command) + 1. execute command (if found) + 2. on completion of the command, mark it complete +3. [load and start the application](#load-and-start) + + + +### Read eboot command ### + +Historically eboot commands were stored in RTC RAM. In an effort to survive a power-outage mid-update (which will claer the RTC RAM) there is now provision for storing the commands in Flash. If no valid command is found in the flash storage (or flash storage is disabled) eboot will try RTC RAM. + +Commands are considered valid if the checksum is correct. + +```C +typedef struct eboot_command { + uint32_t magic; + enum action_t action; + uint32_t args[29]; + uint32_t crc32; +} eboot_command_t; +``` + + +### Load and start ### + +The firmware images are expected to have ELF headers indicating what location each section should be loaded into - which is relevant for the RAM locations. + +Both the ESP bootloader and eboot will work through the image sections copying the contents of the appropriate ones into their address. + +Finally execution jumps to the entry-point specified in the image header. + diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index 6e188d806e..dfae5c6ec0 100644 --- a/bootloaders/eboot/eboot.c +++ b/bootloaders/eboot/eboot.c @@ -39,15 +39,69 @@ int print_version(const uint32_t flash_addr) return 0; } +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) +int print_flags(const uint32_t flash_addr) +{ + const char* __attribute__ ((aligned (4))) fmtt = "#%08x\n\0\0"; + uint32_t ver, i; + uint32_t fmt[2]; + eboot_flash_command_t cmd; + fmt[0] = ((uint32_t*) fmtt)[0]; + fmt[1] = ((uint32_t*) fmtt)[1]; + ver = commandAddress(); + ets_putc('<'); + ets_printf((const char*) fmt, ver); + ets_putc('\n'); + for (i = 0; i < EBOOT_COMMAND_MAX_COUNT; i++) { + ets_putc('0' + i); + ets_putc(':'); + readBootCommand(i, &cmd); + ets_printf((const char*) fmt, cmd.flags); + } + ets_putc('D'); + ets_putc('o'); + ets_putc('n'); + ets_putc('e'); + ets_putc('!'); + ets_putc('\n'); + return 0; +} +#else +#define print_flags(X) {} +#endif + +int find_app_start(const uint32_t flash_addr) +{ + image_header_t image_header; + uint32_t pos = flash_addr; + uint8_t count = 0; + + do { + pos += APP_START_OFFSET; + if (SPIRead(pos, &image_header, sizeof(image_header))) { + return 0; + } + count += 1; + } while ((image_header.magic != 0xe9) && (count < 4)); + return pos; +} + int load_app_from_flash_raw(const uint32_t flash_addr) { image_header_t image_header; - uint32_t pos = flash_addr + APP_START_OFFSET; + uint32_t pos = find_app_start(flash_addr); + const char* __attribute__ ((aligned (4))) fmtt = "l:%08x\n\0"; + uint32_t ver, i; + uint32_t fmt[2]; + fmt[0] = ((uint32_t*) fmtt)[0]; + fmt[1] = ((uint32_t*) fmtt)[1]; - if (SPIRead(pos, &image_header, sizeof(image_header))) { + ets_printf((const char*) fmt, pos); + if (SPIRead(pos, &image_header, sizeof(image_header))) { return 1; } pos += sizeof(image_header); + ets_printf((const char*) fmt, pos); for (uint32_t section_index = 0; @@ -62,6 +116,15 @@ int load_app_from_flash_raw(const uint32_t flash_addr) const uint32_t address = section_header.address; +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('f'); + ets_printf((const char*) fmt, pos); + ets_putc('t'); + ets_printf((const char*) fmt, address); + ets_putc('s'); + ets_printf((const char*) fmt, section_header.size); +#endif + bool load = false; if (address < 0x40000000) { @@ -83,8 +146,18 @@ int load_app_from_flash_raw(const uint32_t flash_addr) continue; } +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('l'); + ets_putc('o'); +#endif + if (SPIRead(pos, (void*)address, section_header.size)) return 3; +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('a'); + ets_putc('d'); + ets_putc('\n'); +#endif pos += section_header.size; } @@ -123,6 +196,20 @@ int copy_raw(const uint32_t src_addr, const uint32_t size, const bool verify) { + const char* __attribute__ ((aligned (4))) fmtt = ":%08x\n\0\0"; + uint32_t fmt[2]; + fmt[0] = ((uint32_t*) fmtt)[0]; + fmt[1] = ((uint32_t*) fmtt)[1]; + +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('S'); + ets_printf((const char*) fmt, src_addr); + ets_putc('D'); + ets_printf((const char*) fmt, dst_addr); + ets_putc('B'); + ets_printf((const char*) fmt, size); +#endif + // require regions to be aligned if ((src_addr & 0xfff) != 0 || (dst_addr & 0xfff) != 0) { @@ -223,6 +310,7 @@ int main() struct eboot_command cmd; print_version(0); + print_flags(0); if (eboot_command_read(&cmd) == 0) { // valid command was passed via RTC_MEM @@ -264,6 +352,7 @@ int main() ets_printf((const char *)&cp); #endif if (res == 0) { + eboot_command_clear(); cmd.action = ACTION_LOAD_APP; cmd.args[0] = cmd.args[1]; } diff --git a/bootloaders/eboot/eboot_command.c b/bootloaders/eboot/eboot_command.c index 54d4895c94..a30591153e 100644 --- a/bootloaders/eboot/eboot_command.c +++ b/bootloaders/eboot/eboot_command.c @@ -1,4 +1,5 @@ #include "eboot_command.h" +#include "flash.h" uint32_t crc_update(uint32_t crc, const uint8_t *data, size_t length) { @@ -28,7 +29,155 @@ uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd) offsetof(struct eboot_command, crc32)); } -int eboot_command_read(struct eboot_command* cmd) +#if defined (EBOOT_ENABLE_FLASH_STORAGE) + +uint32_t eboot_read_flash_index(eboot_index_t *eboot_index) +{ + if (SPIRead(0 + APP_START_OFFSET + sizeof(image_header_t) + sizeof(section_header_t), &eboot_index, sizeof(eboot_index))) { + return 0; + } + + if (eboot_index->magic != EBOOT_INDEX_MAGIC_V1) { + return 0; + } + + return 1; +} + +eboot_flash_command_t *commandAddress(void) { + eboot_index_t eboot_index; + const uint32_t addr = 0 + APP_START_OFFSET + sizeof(image_header_t) + sizeof(section_header_t); + if (SPIRead(addr, (uint32_t *)&eboot_index, sizeof(eboot_index))) { + return NULL; + } + if (eboot_index.magic != EBOOT_INDEX_MAGIC_V1) { + return NULL; + } else { + return eboot_index.commands; + } +} + +bool readBootCommand(int cmd, eboot_flash_command_t *dst) { + eboot_flash_command_t *cmds = commandAddress(); + if (cmd >= EBOOT_COMMAND_MAX_COUNT) { + return 0; + } +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('r'); + ets_putc('b'); + ets_putc('0' + cmd); + ets_putc('\n'); +#endif + uint32_t uint = (uint32_t) cmds; + uint32_t addr = (uint32_t)cmds - 0x40200000; + addr += cmd * sizeof(*dst); + if (SPIRead(addr, (uint32_t *)dst, sizeof(*dst))) { + return 0; + } +} + +bool writeBootCommand(int cmd, eboot_flash_command_t *dst) { + eboot_flash_command_t *cmds = commandAddress(); + if (cmd >= EBOOT_COMMAND_MAX_COUNT) { + return 0; + } +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('w'); + ets_putc('b'); + ets_putc('0' + cmd); + ets_putc('\n'); +#endif + uint32_t uint = (uint32_t) cmds; + uint32_t addr = (uint32_t)cmds - 0x40200000; + addr += cmd * sizeof(*dst); + if (SPIWrite(addr, (uint32_t *)dst, sizeof(*dst))) { + return 0; + } +} + +uint32_t eboot_command_read_from_flash(struct eboot_command *cmd) +{ + + eboot_flash_command_t flash_command; + uint32_t i, *src, *dst = (uint32_t *)cmd; + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + // ets_printf("Reading command from flash: %p\n", cmd); + + for (i = 0; i < EBOOT_COMMAND_MAX_COUNT; i++) { + // ets_printf("Read bootCommand %d, flags: %x\n", i, flash_command.flags); + readBootCommand(i, &flash_command); + // ets_printf("Read bootCommand %d, flags: %x\n", i, flash_command.flags); + if (((flash_command.flags & EBOOT_CMD_FLAG_SLOT_FREE) == 0) && + ((flash_command.flags & EBOOT_CMD_FLAG_PENDING) == EBOOT_CMD_FLAG_PENDING)) { + // Not free (meaning there's some data) and pending (so it's yet to be completed) +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('r'); + ets_putc('c'); + ets_putc('0' + i); + ets_putc('\n'); +#endif + src = (uint32_t *)&flash_command.cmd; + for (uint32_t j = 0; j < dw_count; ++j) { + dst[j] = src[j]; + } + // ets_printf("Returning bootCommand %d, flags: %x\n", i, flash_command.flags); + return 1; + } + } + return 0; +} + +uint32_t eboot_command_write_to_flash(struct eboot_command *cmd) +{ + eboot_flash_command_t flash_command; + uint32_t i, *dst, *src = (uint32_t *)cmd; + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + + for (i = 0; i < EBOOT_COMMAND_MAX_COUNT; i++) { + readBootCommand(i, &flash_command); + if (((flash_command.flags & EBOOT_CMD_FLAG_SLOT_FREE) == EBOOT_CMD_FLAG_SLOT_FREE) && + ((flash_command.flags & EBOOT_CMD_FLAG_PENDING) == EBOOT_CMD_FLAG_PENDING)) { +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('w'); + ets_putc('c'); + ets_putc('0' + i); + ets_putc('\n'); +#endif + dst = (uint32_t *)&flash_command.cmd; + for (uint32_t j = 0; j < dw_count; ++j) { + dst[j] = src[j]; + } + flash_command.flags &= ~EBOOT_CMD_FLAG_SLOT_FREE; + writeBootCommand(i, &flash_command); + return 1; + } + } + return 0; +} + +uint32_t eboot_command_clear_flash(void) +{ + eboot_flash_command_t flash_command; + uint32_t i; + + for (i = 0; i < EBOOT_COMMAND_MAX_COUNT; i++) { + readBootCommand(i, &flash_command); + if (((flash_command.flags & EBOOT_CMD_FLAG_SLOT_FREE) == 0) && + ((flash_command.flags & EBOOT_CMD_FLAG_PENDING) == EBOOT_CMD_FLAG_PENDING)) { + flash_command.flags &= ~EBOOT_CMD_FLAG_PENDING; + // ets_printf("Clearing bootCommand %d, flags: %x\n", i, flash_command.flags); + ets_wdt_disable(); + writeBootCommand(i, &flash_command); + ets_wdt_enable(); + return 1; + } + } + return 0; +} + +#endif // EBOOT_ENABLE_FLASH_STORAGE + +int eboot_command_read_from_rtc(struct eboot_command *cmd) { const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); uint32_t* dst = (uint32_t *) cmd; @@ -36,12 +185,71 @@ int eboot_command_read(struct eboot_command* cmd) dst[i] = RTC_MEM[i]; } + return 0; +} + +int eboot_command_write_to_rtc(struct eboot_command *cmd) +{ + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + const uint32_t* src = (const uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + RTC_MEM[i] = src[i]; + } +} + +void eboot_command_clear_rtc(void) +{ + RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0; + RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0; +} + +int eboot_command_read(struct eboot_command* cmd) +{ + uint32_t have_command = 0; + uint32_t count = 0; +#if defined (EBOOT_ENABLE_FLASH_STORAGE) +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('F'); + ets_putc(':'); +#endif + have_command = eboot_command_read_from_flash(cmd); +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('0' + have_command); + ets_putc('\n'); +#endif // EBOOT_ENABLE_SERIAL_DEBUG +#endif // EBOOT_ENABLE_FLASH_STORAGE + if (have_command == 0) { +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('R'); + ets_putc('-'); +#endif + eboot_command_read_from_rtc(cmd); + count = cmd->args[28]; + cmd->args[28] = 0; +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('0' + count); + ets_putc('\n'); +#endif + } + uint32_t crc32 = eboot_command_calculate_crc32(cmd); if ((cmd->magic & EBOOT_MAGIC_MASK) != EBOOT_MAGIC || cmd->crc32 != crc32) { return 1; } + if (count >= 3) { +#if defined (EBOOT_ENABLE_SERIAL_DEBUG) + ets_putc('R'); + ets_putc('>'); + ets_putc('!'); + ets_putc('\n'); +#endif + return 1; + } + + cmd->args[28] = count + 1; + eboot_command_write_to_rtc(cmd); return 0; } @@ -49,17 +257,20 @@ void eboot_command_write(struct eboot_command* cmd) { cmd->magic = EBOOT_MAGIC; cmd->crc32 = eboot_command_calculate_crc32(cmd); - - const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); - const uint32_t* src = (const uint32_t *) cmd; - for (uint32_t i = 0; i < dw_count; ++i) { - RTC_MEM[i] = src[i]; - } +#if defined (EBOOT_ENABLE_FLASH_STORAGE) + eboot_command_write_to_flash(cmd); +#endif // EBOOT_ENABLE_FLASH_STORAGE + eboot_command_write_to_rtc(cmd); } void eboot_command_clear() { - RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0; - RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0; + uint32_t cleared = 0; +#if defined (EBOOT_ENABLE_FLASH_STORAGE) + cleared = eboot_command_clear_flash(); +#endif // EBOOT_ENABLE_FLASH_STORAGE + if (cleared > 0) { + eboot_command_clear_rtc(); + } } diff --git a/bootloaders/eboot/eboot_command.h b/bootloaders/eboot/eboot_command.h index ba9c889a2c..ae11736bee 100644 --- a/bootloaders/eboot/eboot_command.h +++ b/bootloaders/eboot/eboot_command.h @@ -22,13 +22,45 @@ enum action_t { #define EBOOT_MAGIC 0xeb001000 #define EBOOT_MAGIC_MASK 0xfffff000 -struct eboot_command { +typedef struct eboot_command { uint32_t magic; enum action_t action; uint32_t args[29]; uint32_t crc32; -}; +} eboot_command_t; + + +#if defined (EBOOT_ENABLE_FLASH_STORAGE) +// Magic for version 1 corresponds to AR01 +#define EBOOT_INDEX_MAGIC_V1 0x31305241 +#define EBOOT_COMMAND_MAX_COUNT 32 + + +#define FLASH_SECTOR_SIZE 0x1000 + + +/* A command is ready to be actioned if it is both + * Not free (SLOT_FREE == 0) AND + * pending (PENDING == 1) +*/ + +// Is the slot available for new command data (1 == Yes; 0 == It's been used, so No) +#define EBOOT_CMD_FLAG_SLOT_FREE (1 << 0) +// Has the command been actioned (1 == No, needs to be actioned; 0 == It's been completed) +#define EBOOT_CMD_FLAG_PENDING (1 << 1) + +typedef struct eboot_flash_command { + uint32_t flags; + eboot_command_t cmd; +} eboot_flash_command_t; + +typedef struct eboot_index { + uint32_t version; + uint32_t magic; + eboot_flash_command_t *commands; +} eboot_index_t; +#endif // EBOOT_ENABLE_FLASH_STORAGE int eboot_command_read(struct eboot_command* cmd); void eboot_command_write(struct eboot_command* cmd); diff --git a/bootloaders/eboot/flash.h b/bootloaders/eboot/flash.h index 38c528869a..b6613e393d 100644 --- a/bootloaders/eboot/flash.h +++ b/bootloaders/eboot/flash.h @@ -15,6 +15,8 @@ */ #include <spi_flash_geometry.h> +#define APP_START_OFFSET 0x1000 + int SPIEraseBlock(uint32_t block); int SPIEraseSector(uint32_t sector); int SPIRead(uint32_t addr, void *dest, size_t size); diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 51bdfe8e12..6eab4e8a2a 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -603,14 +603,15 @@ uint32_t EspClass::getSketchSize() { return result; } -extern "C" uint32_t _FS_start; +extern "C" uint32_t _SKETCH_AREA_end; uint32_t EspClass::getFreeSketchSpace() { uint32_t usedSize = getSketchSize(); // round one sector up uint32_t freeSpaceStart = (usedSize + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); - uint32_t freeSpaceEnd = (uint32_t)&_FS_start - 0x40200000; + uint32_t freeSpaceEnd = (uint32_t)&_SKETCH_AREA_end - 0x40200000; + #ifdef DEBUG_SERIAL DEBUG_SERIAL.printf("usedSize=%u freeSpaceStart=%u freeSpaceEnd=%u\r\n", usedSize, freeSpaceStart, freeSpaceEnd); diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index d9d468765a..3f9dacdb9b 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -25,6 +25,8 @@ extern "C" { extern "C" uint32_t _FS_start; extern "C" uint32_t _FS_end; +extern "C" uint32_t _SKETCH_AREA_end; + UpdaterClass::UpdaterClass() { @@ -117,8 +119,11 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { if (command == U_FLASH) { //address of the end of the space available for sketch and update - uintptr_t updateEndAddress = (uintptr_t)&_FS_start - 0x40200000; + uintptr_t updateEndAddress = (uintptr_t) &_SKETCH_AREA_end - 0x40200000; + //size of the update rounded to a sector + size_t roundedSize = (size + FLASH_SECTOR_SIZE - 1) & (~(FLASH_SECTOR_SIZE - 1)); + //address where we will start writing the update updateStartAddress = (updateEndAddress > roundedSize)? (updateEndAddress - roundedSize) : 0; #ifdef DEBUG_UPDATER diff --git a/cores/esp8266/core_esp8266_eboot_command.cpp b/cores/esp8266/core_esp8266_eboot_command.cpp index 2ddc65933e..ab9d8336f3 100644 --- a/cores/esp8266/core_esp8266_eboot_command.cpp +++ b/cores/esp8266/core_esp8266_eboot_command.cpp @@ -22,8 +22,14 @@ #include <stddef.h> #include <stdbool.h> #include "coredecls.h" +#include <stdint.h> #include "eboot_command.h" - +#include "flash_utils.h" +#include "c_types.h" +#include "ets_sys.h" +#include "os_type.h" +#include "osapi.h" +#include "spi_flash.h" extern "C" { @@ -32,7 +38,158 @@ static uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd) return crc32((const uint8_t*) cmd, offsetof(struct eboot_command, crc32)); } -int eboot_command_read(struct eboot_command* cmd) +#if defined (EBOOT_ENABLE_FLASH_STORAGE) + +uint32_t eboot_get_flash_block_size(void) { + return 2 * 4 * 1024; +} + +uint32_t eboot_read_flash_index(eboot_index_t *eboot_index) +{ + if (spi_flash_read(0 + APP_START_OFFSET + sizeof(image_header_t) + sizeof(section_header_t), (uint32_t *) &eboot_index, sizeof(eboot_index)) != 0) { + return 0; + } + + if (eboot_index->magic != EBOOT_INDEX_MAGIC_V1) { + return 0; + } + + return 1; +} + +eboot_flash_command_t *commandAddress(void) { + eboot_index_t eboot_index; + const uint32_t addr = 0 + APP_START_OFFSET + sizeof(image_header_t) + sizeof(section_header_t); + ets_printf("commandAddress: %p\n", (void *) addr); + if (spi_flash_read(addr, (uint32_t *)&eboot_index, sizeof(eboot_index)) != 0) { + ets_printf("failed to read SPI\n"); + return NULL; + } + if (eboot_index.magic != EBOOT_INDEX_MAGIC_V1) { + ets_printf("failed to find MAGIC value (had %x)\n", eboot_index.magic); + return NULL; + } else { + return eboot_index.commands; + } +} + +bool readBootCommand(int cmd, eboot_flash_command_t *dst) { + eboot_flash_command_t *cmds = commandAddress(); + if (cmds == 0) { + return 0; + } + ets_printf("Reading command %d from flash: %p\n", cmd, (void *) cmds); + if (cmd >= EBOOT_COMMAND_MAX_COUNT) { + return 0; + } + uint32_t addr = (uint32_t) cmds - 0x40200000; + addr += cmd * sizeof(*dst); + ets_printf("Reading command %d from flash @ %p\n", cmd, (void *) addr); + if (spi_flash_read(addr, (uint32_t *)dst, sizeof(*dst))) { + return 0; + } + return 1; +} + +bool writeBootCommand(int cmd, eboot_flash_command_t *dst) { + eboot_flash_command_t *cmds = commandAddress(); + ets_printf("!Writing command %d to flash: %p\n", cmd, (void *) cmds); + if (cmd >= EBOOT_COMMAND_MAX_COUNT) { + return 0; + } + uint32_t addr = (uint32_t)cmds - 0x40200000; + addr += cmd * sizeof(*dst); + ets_printf("Writing command %d to flash @ %p\n", cmd, (void *) addr); + if (spi_flash_write(addr, (uint32_t *)dst, sizeof(*dst))) { + return 0; + } + return 1; +} + +bool eraseBootCommandBlock(void) { + eboot_flash_command_t *cmds = commandAddress(); + uint32_t addr = (uint32_t)cmds - 0x40200000; + ets_printf("Erasing command block at %p\n", (void *) addr); + if (spi_flash_erase_sector(addr / FLASH_SECTOR_SIZE)) { + return 0; + } + return 1; +} + +uint32_t eboot_command_read_from_flash(eboot_flash_command_t *cmd) +{ + eboot_index_t eboot_index; + eboot_flash_command_t *flash_command; + uint32_t i; + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + + if (!eboot_read_flash_index(&eboot_index)) { + return 0; + } else { + flash_command = eboot_index.commands; + for (i = 0; i < EBOOT_COMMAND_MAX_COUNT; i++) { + if (((flash_command->flags & EBOOT_CMD_FLAG_SLOT_FREE) == 0) && + ((flash_command->flags & EBOOT_CMD_FLAG_PENDING) == EBOOT_CMD_FLAG_PENDING)) { + // This is a valid command waiting to be actioned, or should be. The CRC check will determine if it's actually valid + uint32_t* dst = (uint32_t *) cmd; + uint32_t* src = (uint32_t *) &(flash_command->cmd); + for (uint32_t i = 0; i < dw_count; ++i) { + dst[i] = src[i]; + } + return 1; + } + } + } + return 0; +} + +uint32_t eboot_command_write_to_flash(struct eboot_command *cmd) +{ + eboot_flash_command_t flash_command; + uint32_t i, *dst, *src = (uint32_t *)cmd; + int32_t target_command_slot = -1; + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + ets_printf("Writing command to flash: %p\n", (void *) cmd); + + for (i = 0; i < EBOOT_COMMAND_MAX_COUNT; i++) { + ets_printf("Read bootCommand %d, flags: %x\n", i, flash_command.flags); + if (readBootCommand(i, &flash_command) == 0) { + ets_printf("Reading bootCommand %d failed!\n", i); + } else { + ets_printf("Read bootCommand %d, flags: %x\n", i, flash_command.flags); + if (((flash_command.flags & EBOOT_CMD_FLAG_SLOT_FREE) == EBOOT_CMD_FLAG_SLOT_FREE) && + ((flash_command.flags & EBOOT_CMD_FLAG_PENDING) == EBOOT_CMD_FLAG_PENDING) && + (flash_command.cmd.magic == 0xffffffff) + ) { + target_command_slot = i; + break; + } + } + } + if (target_command_slot == -1) { + // We didn't find a free slot. Assume this is due to the slots being all used, + // so erase the storage page + if (eraseBootCommandBlock() != 1) { + return 0; + } + // Block is now clear, so we can use the first slot + target_command_slot = 0; + // And reinitialise our block to a blank one. + readBootCommand(target_command_slot, &flash_command); + } + dst = (uint32_t *)&flash_command.cmd; + for (uint32_t j = 0; j < dw_count; ++j) { + dst[j] = src[j]; + } + flash_command.flags &= ~EBOOT_CMD_FLAG_SLOT_FREE; + ets_printf("Writing command %d to flash: %p\n", target_command_slot, (void *) cmd); + writeBootCommand(target_command_slot, &flash_command); + return 1; +} + +#endif // EBOOT_ENABLE_FLASH_STORAGE + +int eboot_command_read_from_rtc(struct eboot_command *cmd) { const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); uint32_t* dst = (uint32_t *) cmd; @@ -40,8 +197,36 @@ int eboot_command_read(struct eboot_command* cmd) dst[i] = RTC_MEM[i]; } + return 0; +} + +void eboot_command_write_to_rtc(struct eboot_command *cmd) +{ + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + const uint32_t* src = (const uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + RTC_MEM[i] = src[i]; + } +} + +void eboot_command_clear_rtc(void) +{ + RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0; + RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0; +} + +int eboot_command_read(struct eboot_command* cmd) +{ + uint32_t have_command = 0; +#if defined (EBOOT_ENABLE_FLASH_STORAGE) + // have_command = eboot_command_read_from_flash(cmd); +#endif // EBOOT_ENABLE_FLASH_STORAGE + if (have_command == 0) { + eboot_command_read_from_rtc(cmd); + } + uint32_t crc32 = eboot_command_calculate_crc32(cmd); - if ((cmd->magic & EBOOT_MAGIC_MASK) != EBOOT_MAGIC || + if ((cmd->magic & EBOOT_MAGIC_MASK) != EBOOT_MAGIC || cmd->crc32 != crc32) { return 1; } @@ -51,20 +236,23 @@ int eboot_command_read(struct eboot_command* cmd) void eboot_command_write(struct eboot_command* cmd) { + uint32_t saved = 0; cmd->magic = EBOOT_MAGIC; cmd->crc32 = eboot_command_calculate_crc32(cmd); - - const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); - const uint32_t* src = (const uint32_t *) cmd; - for (uint32_t i = 0; i < dw_count; ++i) { - RTC_MEM[i] = src[i]; + ets_printf("Writing command: %p\n", (void *) cmd); +#if defined (EBOOT_ENABLE_FLASH_STORAGE) + saved = eboot_command_write_to_flash(cmd); +#endif // EBOOT_ENABLE_FLASH_STORAGE + if (saved == 0) { + eboot_command_write_to_rtc(cmd); } } void eboot_command_clear() { - RTC_MEM[offsetof(struct eboot_command, magic) / sizeof(uint32_t)] = 0; - RTC_MEM[offsetof(struct eboot_command, crc32) / sizeof(uint32_t)] = 0; +#if defined (EBOOT_ENABLE_FLASH_STORAGE) +#endif // EBOOT_ENABLE_FLASH_STORAGE + eboot_command_clear_rtc(); } }; diff --git a/cores/esp8266/eboot_command.h b/cores/esp8266/eboot_command.h index 3d854afba3..0d30ab8f3b 100644 --- a/cores/esp8266/eboot_command.h +++ b/cores/esp8266/eboot_command.h @@ -17,13 +17,45 @@ enum action_t { #define EBOOT_MAGIC 0xeb001000 #define EBOOT_MAGIC_MASK 0xfffff000 -struct eboot_command { +typedef struct eboot_command { uint32_t magic; enum action_t action; uint32_t args[29]; uint32_t crc32; -}; +} eboot_command_t; + + +#if defined (EBOOT_ENABLE_FLASH_STORAGE) +// Magic for version 1 corresponds to AR01 +#define EBOOT_INDEX_MAGIC_V1 0x31305241 +#define EBOOT_COMMAND_MAX_COUNT 32 + + +#define FLASH_SECTOR_SIZE 0x1000 + + +/* A command is ready to be actioned if it is both + * Not free (SLOT_FREE == 0) AND + * pending (PENDING == 1) +*/ + +// Is the slot available for new command data (1 == Yes; 0 == It's been used, so No) +#define EBOOT_CMD_FLAG_SLOT_FREE (1 << 0) +// Has the command been actioned (1 == No, needs to be actioned; 0 == It's been completed) +#define EBOOT_CMD_FLAG_PENDING (1 << 1) + +typedef struct eboot_flash_command { + uint32_t flags; + eboot_command_t cmd; +} eboot_flash_command_t; + +typedef struct eboot_index { + uint32_t version; + uint32_t magic; + eboot_flash_command_t *commands; +} eboot_index_t; +#endif // EBOOT_ENABLE_FLASH_STORAGE int eboot_command_read(struct eboot_command* cmd); void eboot_command_write(struct eboot_command* cmd); diff --git a/libraries/ESP8266SdFat b/libraries/ESP8266SdFat index 0a46e4ebb2..af4ed0c5ec 160000 --- a/libraries/ESP8266SdFat +++ b/libraries/ESP8266SdFat @@ -1 +1 @@ -Subproject commit 0a46e4ebb2de585c5a64f981dbc2b2223a438984 +Subproject commit af4ed0c5ec3084cb3883df51ec2052791ca2bff2 diff --git a/platform.txt b/platform.txt index 17af47d77f..1839c05919 100644 --- a/platform.txt +++ b/platform.txt @@ -83,7 +83,7 @@ compiler.elf2hex.flags= compiler.size.cmd=xtensa-lx106-elf-size # This can be overriden in boards.txt -build.extra_flags=-DESP8266 +build.extra_flags=-DESP8266 -DEBOOT_ENABLE_FLASH_STORAGE # These can be overridden in platform.local.txt compiler.c.extra_flags= diff --git a/tools/boards.txt.py b/tools/boards.txt.py index 2fa6f5c97a..ab29e86e66 100755 --- a/tools/boards.txt.py +++ b/tools/boards.txt.py @@ -1310,6 +1310,7 @@ def flash_map (flashsize_kb, fs_kb = 0): eeprom_size_kb = 4 rfcal_size_kb = 4 sdkwifi_size_kb = 12 + ota_commands_size_kb = 8 fs_end = (flashsize_kb - sdkwifi_size_kb - rfcal_size_kb - eeprom_size_kb) * 1024 # For legacy reasons (#6531), the EEPROM sector needs to be at the old @@ -1318,7 +1319,7 @@ def flash_map (flashsize_kb, fs_kb = 0): rfcal_addr = (flashsize_kb - sdkwifi_size_kb - rfcal_size_kb) * 1024 if flashsize_kb <= 1024: - max_upload_size = (flashsize_kb - (fs_kb + eeprom_size_kb + rfcal_size_kb + sdkwifi_size_kb)) * 1024 - reserved + max_upload_size = (flashsize_kb - (fs_kb + eeprom_size_kb + rfcal_size_kb + sdkwifi_size_kb + ota_commands_size_kb)) * 1024 - reserved fs_start = fs_end - fs_kb * 1024 else: max_upload_size = 1024 * 1024 - reserved @@ -1331,8 +1332,9 @@ def flash_map (flashsize_kb, fs_kb = 0): # Adjust FS_end to be a multiple of the block size fs_end = fs_blocksize * (int)((fs_end - fs_start)/fs_blocksize) + fs_start; + ota_commands_addr = fs_start - (ota_commands_size_kb * 1024) - max_ota_size = min(max_upload_size, fs_start / 2) # =(max_upload_size+empty_size)/2 + max_ota_size = min(max_upload_size, ota_commands_addr / 2) # =(max_upload_size+empty_size)/2 strsize = str(int(flashsize_kb / 1024)) + 'M' if (flashsize_kb >= 1024) else str(flashsize_kb) + 'K' strfs = str(int(fs_kb / 1024)) + 'M' if (fs_kb >= 1024) else str(fs_kb) + 'K' strfs_strip = str(int(fs_kb / 1024)) + 'M' if (fs_kb >= 1024) else str(fs_kb) if (fs_kb > 0) else '' @@ -1379,13 +1381,14 @@ def flash_map (flashsize_kb, fs_kb = 0): print("/* Flash Split for %s chips */" % strsize) print("/* sketch @0x%X (~%dKB) (%dB) */" % (spi, (max_upload_size / 1024), max_upload_size)) - empty_size = fs_start - max_upload_size + empty_size = ota_commands_addr - max_upload_size if empty_size > 0: - print("/* empty @0x%X (~%dKB) (%dB) */" % (spi + max_upload_size, empty_size / 1024, empty_size)) - print("/* spiffs @0x%X (~%dKB) (%dB) */" % (spi + fs_start, ((fs_end - fs_start) / 1024), fs_end - fs_start)) - print("/* eeprom @0x%X (%dKB) */" % (spi + rfcal_addr - eeprom_size_kb * 1024, eeprom_size_kb)) - print("/* rfcal @0x%X (%dKB) */" % (spi + rfcal_addr, rfcal_size_kb)) - print("/* wifi @0x%X (%dKB) */" % (spi + rfcal_addr + rfcal_size_kb * 1024, sdkwifi_size_kb)) + print("/* empty @0x%X (~%dKB) (%dB) */" % (spi + max_upload_size, empty_size / 1024, empty_size)) + print("/* otacmds @0x%X (%dKB) */" % (spi + ota_commands_addr, ota_commands_size_kb)) + print("/* spiffs @0x%X (~%dKB) (%dB) */" % (spi + fs_start, ((fs_end - fs_start) / 1024), fs_end - fs_start)) + print("/* eeprom @0x%X (%dKB) */" % (spi + rfcal_addr - eeprom_size_kb * 1024, eeprom_size_kb)) + print("/* rfcal @0x%X (%dKB) */" % (spi + rfcal_addr, rfcal_size_kb)) + print("/* wifi @0x%X (%dKB) */" % (spi + rfcal_addr + rfcal_size_kb * 1024, sdkwifi_size_kb)) print("") print("MEMORY") print("{") @@ -1396,10 +1399,17 @@ def flash_map (flashsize_kb, fs_kb = 0): print(" irom0_0_seg : org = 0x40201010, len = 0x%x" % max_upload_size) print("}") print("") + # print("PROVIDE ( _FS_start = 0x%08X );" % (0x40200000 + fs_start)) + # print("PROVIDE ( _FS_end = 0x%08X );" % (0x40200000 + fs_end)) + # print("PROVIDE ( _FS_page = 0x%X );" % page) + # print("PROVIDE ( _FS_block = 0x%X );" % fs_blocksize) + print("PROVIDE ( _FS_start = 0x%08X );" % (0x40200000 + fs_start)) print("PROVIDE ( _FS_end = 0x%08X );" % (0x40200000 + fs_end)) print("PROVIDE ( _FS_page = 0x%X );" % page) print("PROVIDE ( _FS_block = 0x%X );" % fs_blocksize) + print("PROVIDE ( _BOOTLOADER_DATA = 0x%08X );" % (0x40200000 + ota_commands_addr)) + print("PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA );") print("PROVIDE ( _EEPROM_start = 0x%08x );" % (0x40200000 + eeprom_start)) # Re-add deprecated symbols pointing to the same address as the new standard ones print("/* The following symbols are DEPRECATED and will be REMOVED in a future release */") @@ -1410,6 +1420,8 @@ def flash_map (flashsize_kb, fs_kb = 0): print("") print('INCLUDE "local.eagle.app.v6.common.ld"') + + if ldgen: sys.stdout.close() sys.stdout = realstdout diff --git a/tools/esptool b/tools/esptool index 4fa0bd7b0d..9ad444a6e0 160000 --- a/tools/esptool +++ b/tools/esptool @@ -1 +1 @@ -Subproject commit 4fa0bd7b0d1f69f5ff22b043adc07c5e562a8931 +Subproject commit 9ad444a6e06e58833d5e6044c1d5f3eb3dd56023 diff --git a/tools/sdk/ld/eagle.app.v6.common.ld.h b/tools/sdk/ld/eagle.app.v6.common.ld.h index c51de98408..6de7b51a7b 100644 --- a/tools/sdk/ld/eagle.app.v6.common.ld.h +++ b/tools/sdk/ld/eagle.app.v6.common.ld.h @@ -148,6 +148,8 @@ SECTIONS { _irom0_text_start = ABSOLUTE(.); *(.ver_number) + LONG(0x31305241) + LONG(_BOOTLOADER_DATA) *.c.o(.literal*, .text*) *.cpp.o(EXCLUDE_FILE (umm_malloc.cpp.o) .literal*, EXCLUDE_FILE (umm_malloc.cpp.o) .text*) *.cc.o(.literal*, .text*) diff --git a/tools/sdk/ld/eagle.flash.16m14m.ld b/tools/sdk/ld/eagle.flash.16m14m.ld index 13c1243fef..e25a23409b 100644 --- a/tools/sdk/ld/eagle.flash.16m14m.ld +++ b/tools/sdk/ld/eagle.flash.16m14m.ld @@ -1,10 +1,11 @@ /* Flash Split for 16M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~1028KB) (1052688B) */ -/* spiffs @0x40400000 (~14312KB) (14655488B) */ -/* eeprom @0x411FB000 (4KB) */ -/* rfcal @0x411FC000 (4KB) */ -/* wifi @0x411FD000 (12KB) */ +/* empty @0x402FEFF0 (~1020KB) (1044496B) */ +/* otacmds @0x403FE000 (8KB) */ +/* spiffs @0x40400000 (~14312KB) (14655488B) */ +/* eeprom @0x411FB000 (4KB) */ +/* rfcal @0x411FC000 (4KB) */ +/* wifi @0x411FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x40400000 ); PROVIDE ( _FS_end = 0x411FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x403FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x411fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40400000 ); diff --git a/tools/sdk/ld/eagle.flash.16m15m.ld b/tools/sdk/ld/eagle.flash.16m15m.ld index ad689f0e9f..3a545a0ea4 100644 --- a/tools/sdk/ld/eagle.flash.16m15m.ld +++ b/tools/sdk/ld/eagle.flash.16m15m.ld @@ -1,10 +1,10 @@ /* Flash Split for 16M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~4KB) (4112B) */ -/* spiffs @0x40300000 (~15336KB) (15704064B) */ -/* eeprom @0x411FB000 (4KB) */ -/* rfcal @0x411FC000 (4KB) */ -/* wifi @0x411FD000 (12KB) */ +/* otacmds @0x402FE000 (8KB) */ +/* spiffs @0x40300000 (~15336KB) (15704064B) */ +/* eeprom @0x411FB000 (4KB) */ +/* rfcal @0x411FC000 (4KB) */ +/* wifi @0x411FD000 (12KB) */ MEMORY { @@ -17,6 +17,8 @@ PROVIDE ( _FS_start = 0x40300000 ); PROVIDE ( _FS_end = 0x411FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x402FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x411fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40300000 ); diff --git a/tools/sdk/ld/eagle.flash.2m.ld b/tools/sdk/ld/eagle.flash.2m.ld index 125f20278b..5909c71b1c 100644 --- a/tools/sdk/ld/eagle.flash.2m.ld +++ b/tools/sdk/ld/eagle.flash.2m.ld @@ -1,10 +1,11 @@ /* Flash Split for 2M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~1008KB) (1032208B) */ -/* spiffs @0x403FB000 (~0KB) (0B) */ -/* eeprom @0x403FB000 (4KB) */ -/* rfcal @0x403FC000 (4KB) */ -/* wifi @0x403FD000 (12KB) */ +/* empty @0x402FEFF0 (~1020KB) (1044496B) */ +/* otacmds @0x403FE000 (8KB) */ +/* spiffs @0x403FB000 (~0KB) (0B) */ +/* eeprom @0x403FB000 (4KB) */ +/* rfcal @0x403FC000 (4KB) */ +/* wifi @0x403FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x403FB000 ); PROVIDE ( _FS_end = 0x403FB000 ); PROVIDE ( _FS_page = 0x0 ); PROVIDE ( _FS_block = 0x0 ); +PROVIDE ( _BOOTLOADER_DATA = 0x403FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x403fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x403FB000 ); diff --git a/tools/sdk/ld/eagle.flash.2m128.ld b/tools/sdk/ld/eagle.flash.2m128.ld index e15a7896f1..ea74fcc75d 100644 --- a/tools/sdk/ld/eagle.flash.2m128.ld +++ b/tools/sdk/ld/eagle.flash.2m128.ld @@ -1,10 +1,11 @@ /* Flash Split for 2M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~900KB) (921616B) */ -/* spiffs @0x403E0000 (~108KB) (110592B) */ -/* eeprom @0x403FB000 (4KB) */ -/* rfcal @0x403FC000 (4KB) */ -/* wifi @0x403FD000 (12KB) */ +/* empty @0x402FEFF0 (~892KB) (913424B) */ +/* otacmds @0x403DE000 (8KB) */ +/* spiffs @0x403E0000 (~108KB) (110592B) */ +/* eeprom @0x403FB000 (4KB) */ +/* rfcal @0x403FC000 (4KB) */ +/* wifi @0x403FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x403E0000 ); PROVIDE ( _FS_end = 0x403FB000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x1000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x403DE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x403fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x403E0000 ); diff --git a/tools/sdk/ld/eagle.flash.2m1m.ld b/tools/sdk/ld/eagle.flash.2m1m.ld index 1190e54d74..c368ba257b 100644 --- a/tools/sdk/ld/eagle.flash.2m1m.ld +++ b/tools/sdk/ld/eagle.flash.2m1m.ld @@ -1,10 +1,10 @@ /* Flash Split for 2M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~4KB) (4112B) */ -/* spiffs @0x40300000 (~1000KB) (1024000B) */ -/* eeprom @0x403FB000 (4KB) */ -/* rfcal @0x403FC000 (4KB) */ -/* wifi @0x403FD000 (12KB) */ +/* otacmds @0x402FE000 (8KB) */ +/* spiffs @0x40300000 (~1000KB) (1024000B) */ +/* eeprom @0x403FB000 (4KB) */ +/* rfcal @0x403FC000 (4KB) */ +/* wifi @0x403FD000 (12KB) */ MEMORY { @@ -17,6 +17,8 @@ PROVIDE ( _FS_start = 0x40300000 ); PROVIDE ( _FS_end = 0x403FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x402FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x403fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40300000 ); diff --git a/tools/sdk/ld/eagle.flash.2m256.ld b/tools/sdk/ld/eagle.flash.2m256.ld index 51259864e7..edc30ad3ee 100644 --- a/tools/sdk/ld/eagle.flash.2m256.ld +++ b/tools/sdk/ld/eagle.flash.2m256.ld @@ -1,10 +1,11 @@ /* Flash Split for 2M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~772KB) (790544B) */ -/* spiffs @0x403C0000 (~236KB) (241664B) */ -/* eeprom @0x403FB000 (4KB) */ -/* rfcal @0x403FC000 (4KB) */ -/* wifi @0x403FD000 (12KB) */ +/* empty @0x402FEFF0 (~764KB) (782352B) */ +/* otacmds @0x403BE000 (8KB) */ +/* spiffs @0x403C0000 (~236KB) (241664B) */ +/* eeprom @0x403FB000 (4KB) */ +/* rfcal @0x403FC000 (4KB) */ +/* wifi @0x403FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x403C0000 ); PROVIDE ( _FS_end = 0x403FB000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x1000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x403BE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x403fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x403C0000 ); diff --git a/tools/sdk/ld/eagle.flash.2m512.ld b/tools/sdk/ld/eagle.flash.2m512.ld index 1c495fca01..136f16dde8 100644 --- a/tools/sdk/ld/eagle.flash.2m512.ld +++ b/tools/sdk/ld/eagle.flash.2m512.ld @@ -1,10 +1,11 @@ /* Flash Split for 2M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~516KB) (528400B) */ -/* spiffs @0x40380000 (~488KB) (499712B) */ -/* eeprom @0x403FB000 (4KB) */ -/* rfcal @0x403FC000 (4KB) */ -/* wifi @0x403FD000 (12KB) */ +/* empty @0x402FEFF0 (~508KB) (520208B) */ +/* otacmds @0x4037E000 (8KB) */ +/* spiffs @0x40380000 (~488KB) (499712B) */ +/* eeprom @0x403FB000 (4KB) */ +/* rfcal @0x403FC000 (4KB) */ +/* wifi @0x403FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x40380000 ); PROVIDE ( _FS_end = 0x403FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x4037E000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x403fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40380000 ); diff --git a/tools/sdk/ld/eagle.flash.4m.ld b/tools/sdk/ld/eagle.flash.4m.ld index 36e71f64a2..2a7033baa0 100644 --- a/tools/sdk/ld/eagle.flash.4m.ld +++ b/tools/sdk/ld/eagle.flash.4m.ld @@ -1,10 +1,11 @@ /* Flash Split for 4M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~3056KB) (3129360B) */ -/* spiffs @0x405FB000 (~0KB) (0B) */ -/* eeprom @0x405FB000 (4KB) */ -/* rfcal @0x405FC000 (4KB) */ -/* wifi @0x405FD000 (12KB) */ +/* empty @0x402FEFF0 (~3068KB) (3141648B) */ +/* otacmds @0x405FE000 (8KB) */ +/* spiffs @0x405FB000 (~0KB) (0B) */ +/* eeprom @0x405FB000 (4KB) */ +/* rfcal @0x405FC000 (4KB) */ +/* wifi @0x405FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x405FB000 ); PROVIDE ( _FS_end = 0x405FB000 ); PROVIDE ( _FS_page = 0x0 ); PROVIDE ( _FS_block = 0x0 ); +PROVIDE ( _BOOTLOADER_DATA = 0x405FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x405fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x405FB000 ); diff --git a/tools/sdk/ld/eagle.flash.4m1m.ld b/tools/sdk/ld/eagle.flash.4m1m.ld index 5b0c692e70..a54abf3f0f 100644 --- a/tools/sdk/ld/eagle.flash.4m1m.ld +++ b/tools/sdk/ld/eagle.flash.4m1m.ld @@ -1,10 +1,11 @@ /* Flash Split for 4M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~2052KB) (2101264B) */ -/* spiffs @0x40500000 (~1000KB) (1024000B) */ -/* eeprom @0x405FB000 (4KB) */ -/* rfcal @0x405FC000 (4KB) */ -/* wifi @0x405FD000 (12KB) */ +/* empty @0x402FEFF0 (~2044KB) (2093072B) */ +/* otacmds @0x404FE000 (8KB) */ +/* spiffs @0x40500000 (~1000KB) (1024000B) */ +/* eeprom @0x405FB000 (4KB) */ +/* rfcal @0x405FC000 (4KB) */ +/* wifi @0x405FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x40500000 ); PROVIDE ( _FS_end = 0x405FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x404FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x405fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40500000 ); diff --git a/tools/sdk/ld/eagle.flash.4m2m.ld b/tools/sdk/ld/eagle.flash.4m2m.ld index 554237fb97..33f1d35056 100644 --- a/tools/sdk/ld/eagle.flash.4m2m.ld +++ b/tools/sdk/ld/eagle.flash.4m2m.ld @@ -1,10 +1,11 @@ /* Flash Split for 4M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~1028KB) (1052688B) */ -/* spiffs @0x40400000 (~2024KB) (2072576B) */ -/* eeprom @0x405FB000 (4KB) */ -/* rfcal @0x405FC000 (4KB) */ -/* wifi @0x405FD000 (12KB) */ +/* empty @0x402FEFF0 (~1020KB) (1044496B) */ +/* otacmds @0x403FE000 (8KB) */ +/* spiffs @0x40400000 (~2024KB) (2072576B) */ +/* eeprom @0x405FB000 (4KB) */ +/* rfcal @0x405FC000 (4KB) */ +/* wifi @0x405FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x40400000 ); PROVIDE ( _FS_end = 0x405FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x403FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x405fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40400000 ); diff --git a/tools/sdk/ld/eagle.flash.4m3m.ld b/tools/sdk/ld/eagle.flash.4m3m.ld index 47cf1f93e6..e4bd88dc3e 100644 --- a/tools/sdk/ld/eagle.flash.4m3m.ld +++ b/tools/sdk/ld/eagle.flash.4m3m.ld @@ -1,10 +1,10 @@ /* Flash Split for 4M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~4KB) (4112B) */ -/* spiffs @0x40300000 (~3048KB) (3121152B) */ -/* eeprom @0x405FB000 (4KB) */ -/* rfcal @0x405FC000 (4KB) */ -/* wifi @0x405FD000 (12KB) */ +/* otacmds @0x402FE000 (8KB) */ +/* spiffs @0x40300000 (~3048KB) (3121152B) */ +/* eeprom @0x405FB000 (4KB) */ +/* rfcal @0x405FC000 (4KB) */ +/* wifi @0x405FD000 (12KB) */ MEMORY { @@ -17,6 +17,8 @@ PROVIDE ( _FS_start = 0x40300000 ); PROVIDE ( _FS_end = 0x405FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x402FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x405fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40300000 ); diff --git a/tools/sdk/ld/eagle.flash.8m6m.ld b/tools/sdk/ld/eagle.flash.8m6m.ld index f3febe2085..37203a6e44 100644 --- a/tools/sdk/ld/eagle.flash.8m6m.ld +++ b/tools/sdk/ld/eagle.flash.8m6m.ld @@ -1,10 +1,11 @@ /* Flash Split for 8M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~1028KB) (1052688B) */ -/* spiffs @0x40400000 (~6120KB) (6266880B) */ -/* eeprom @0x409FB000 (4KB) */ -/* rfcal @0x409FC000 (4KB) */ -/* wifi @0x409FD000 (12KB) */ +/* empty @0x402FEFF0 (~1020KB) (1044496B) */ +/* otacmds @0x403FE000 (8KB) */ +/* spiffs @0x40400000 (~6120KB) (6266880B) */ +/* eeprom @0x409FB000 (4KB) */ +/* rfcal @0x409FC000 (4KB) */ +/* wifi @0x409FD000 (12KB) */ MEMORY { @@ -17,6 +18,8 @@ PROVIDE ( _FS_start = 0x40400000 ); PROVIDE ( _FS_end = 0x409FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x403FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x409fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40400000 ); diff --git a/tools/sdk/ld/eagle.flash.8m7m.ld b/tools/sdk/ld/eagle.flash.8m7m.ld index ee4de71084..af0d43ccb9 100644 --- a/tools/sdk/ld/eagle.flash.8m7m.ld +++ b/tools/sdk/ld/eagle.flash.8m7m.ld @@ -1,10 +1,10 @@ /* Flash Split for 8M chips */ /* sketch @0x40200000 (~1019KB) (1044464B) */ -/* empty @0x402FEFF0 (~4KB) (4112B) */ -/* spiffs @0x40300000 (~7144KB) (7315456B) */ -/* eeprom @0x409FB000 (4KB) */ -/* rfcal @0x409FC000 (4KB) */ -/* wifi @0x409FD000 (12KB) */ +/* otacmds @0x402FE000 (8KB) */ +/* spiffs @0x40300000 (~7144KB) (7315456B) */ +/* eeprom @0x409FB000 (4KB) */ +/* rfcal @0x409FC000 (4KB) */ +/* wifi @0x409FD000 (12KB) */ MEMORY { @@ -17,6 +17,8 @@ PROVIDE ( _FS_start = 0x40300000 ); PROVIDE ( _FS_end = 0x409FA000 ); PROVIDE ( _FS_page = 0x100 ); PROVIDE ( _FS_block = 0x2000 ); +PROVIDE ( _BOOTLOADER_DATA = 0x402FE000 ); +PROVIDE ( _SKETCH_AREA_end = _BOOTLOADER_DATA ); PROVIDE ( _EEPROM_start = 0x409fb000 ); /* The following symbols are DEPRECATED and will be REMOVED in a future release */ PROVIDE ( _SPIFFS_start = 0x40300000 );