From 4a987dacca4760aed96c505a363ffde52405ff91 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 24 Aug 2018 17:56:38 +0530 Subject: [PATCH 1/3] bootloader: keep bootloader_common code to retention region It is possible to utilize some of the routines related to otadata partition validation, after firmware image is downloaded to RAM. Hence these routines should be part of app cpu cache, so that they do not get overwritten by firmware. Signed-off-by: Mahavir Jain --- components/bootloader/subproject/main/esp32.bootloader.ld | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/bootloader/subproject/main/esp32.bootloader.ld b/components/bootloader/subproject/main/esp32.bootloader.ld index 8930d5305..384488125 100644 --- a/components/bootloader/subproject/main/esp32.bootloader.ld +++ b/components/bootloader/subproject/main/esp32.bootloader.ld @@ -36,11 +36,12 @@ SECTIONS { . = ALIGN (16); _stext = .; - _text_start = ABSOLUTE(.); + _loader_text_start = ABSOLUTE(.); *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ *liblog.a:(.literal .text .literal.* .text.*) *libgcc.a:(.literal .text .literal.* .text.*) + *libbootloader_support.a:bootloader_common.o(.literal .text .literal.* .text.*) *libbootloader_support.a:bootloader_flash.o(.literal .text .literal.* .text.*) *libbootloader_support.a:bootloader_random.o(.literal .text .literal.* .text.*) *libbootloader_support.a:bootloader_utility.o(.literal .text .literal.* .text.*) @@ -56,7 +57,7 @@ SECTIONS *(.fini.literal) *(.fini) *(.gnu.version) - _text_end = ABSOLUTE(.); + _loader_text_end = ABSOLUTE(.); _etext = .; } > iram_loader_seg From 62746e414ef890c9f4c04980f1f0cc45458ed251 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 24 Aug 2018 17:58:04 +0530 Subject: [PATCH 2/3] bootloader: add API for erasing flash region Signed-off-by: Mahavir Jain --- .../include_bootloader/bootloader_flash.h | 11 +++++++ .../src/bootloader_common.c | 6 ++-- .../bootloader_support/src/bootloader_flash.c | 29 +++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/components/bootloader_support/include_bootloader/bootloader_flash.h b/components/bootloader_support/include_bootloader/bootloader_flash.h index 763136e03..85a482781 100644 --- a/components/bootloader_support/include_bootloader/bootloader_flash.h +++ b/components/bootloader_support/include_bootloader/bootloader_flash.h @@ -21,6 +21,7 @@ #include "esp_spi_flash.h" #define FLASH_SECTOR_SIZE 0x1000 +#define FLASH_BLOCK_SIZE 0x10000 /* Provide a Flash API for bootloader_support code, that can be used from bootloader or app code. @@ -100,4 +101,14 @@ esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool */ esp_err_t bootloader_flash_erase_sector(size_t sector); +/** + * @brief Erase the Flash range. + * + * @param start_addr start address of flash offset + * @param size sector aligned size to be erased + * + * @return esp_err_t + */ +esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size); + #endif diff --git a/components/bootloader_support/src/bootloader_common.c b/components/bootloader_support/src/bootloader_common.c index a17492601..479407845 100644 --- a/components/bootloader_support/src/bootloader_common.c +++ b/components/bootloader_support/src/bootloader_common.c @@ -106,8 +106,8 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat partitions = bootloader_mmap(ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN); if (!partitions) { - ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN); - return false; + ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_OFFSET, ESP_PARTITION_TABLE_MAX_LEN); + return false; } ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_OFFSET, (intptr_t)partitions); @@ -128,7 +128,7 @@ bool bootloader_common_erase_part_type_data(const char *list_erase, bool ota_dat // partition->label is not null-terminated string. strncpy(label, (char *)&partition->label, sizeof(label) - 1); if (fl_ota_data_erase == true || (bootloader_common_label_search(list_erase, label) == true)) { - err = esp_rom_spiflash_erase_area(partition->pos.offset, partition->pos.size); + err = bootloader_flash_erase_range(partition->pos.offset, partition->pos.size); if (err != ESP_OK) { ret = false; marker = "err"; diff --git a/components/bootloader_support/src/bootloader_flash.c b/components/bootloader_support/src/bootloader_flash.c index a7a6f6e61..735c21327 100644 --- a/components/bootloader_support/src/bootloader_flash.c +++ b/components/bootloader_support/src/bootloader_flash.c @@ -73,6 +73,11 @@ esp_err_t bootloader_flash_erase_sector(size_t sector) return spi_flash_erase_sector(sector); } +esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) +{ + return spi_flash_erase_range(start_addr, size); +} + #else /* Bootloader version, uses ROM functions only */ #include @@ -247,4 +252,28 @@ esp_err_t bootloader_flash_erase_sector(size_t sector) return spi_to_esp_err(esp_rom_spiflash_erase_sector(sector)); } +esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) +{ + if (start_addr % FLASH_SECTOR_SIZE != 0) { + return ESP_ERR_INVALID_ARG; + } + if (size % FLASH_SECTOR_SIZE != 0) { + return ESP_ERR_INVALID_SIZE; + } + size_t start = start_addr / FLASH_SECTOR_SIZE; + size_t end = start + size / FLASH_SECTOR_SIZE; + const size_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; + + esp_rom_spiflash_result_t rc = ESP_ROM_SPIFLASH_RESULT_OK; + for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) { + if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) { + rc = esp_rom_spiflash_erase_block(sector / sectors_per_block); + sector += sectors_per_block; + } else { + rc = esp_rom_spiflash_erase_sector(sector); + ++sector; + } + } + return spi_to_esp_err(rc); +} #endif From 8227db4f5ecadc2f40f61b371e41f0aa5b46ab83 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Mon, 27 Aug 2018 21:54:20 +0530 Subject: [PATCH 3/3] spi_flash: fix erase_range for block erase check Erase in block (64k) as much as possible, before falling back to sector (4k) erase. Signed-off-by: Mahavir Jain --- components/spi_flash/flash_ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index aab0c1210..89f9ef5e1 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -218,7 +218,7 @@ esp_err_t IRAM_ATTR spi_flash_erase_range(uint32_t start_addr, uint32_t size) if (rc == ESP_ROM_SPIFLASH_RESULT_OK) { for (size_t sector = start; sector != end && rc == ESP_ROM_SPIFLASH_RESULT_OK; ) { spi_flash_guard_start(); - if (sector % sectors_per_block == 0 && end - sector > sectors_per_block) { + if (sector % sectors_per_block == 0 && end - sector >= sectors_per_block) { rc = esp_rom_spiflash_erase_block(sector / sectors_per_block); sector += sectors_per_block; COUNTER_ADD_BYTES(erase, sectors_per_block * SPI_FLASH_SEC_SIZE);