diff --git a/components/bootloader/src/main/bootloader_config.h b/components/bootloader/src/main/bootloader_config.h index 6b37899ac..f7379b2e4 100644 --- a/components/bootloader/src/main/bootloader_config.h +++ b/components/bootloader/src/main/bootloader_config.h @@ -22,16 +22,9 @@ extern "C" #endif #include "esp_flash_data_types.h" +#include "soc/soc.h" #define SPI_SEC_SIZE 0x1000 -#define IROM_LOW 0x400D0000 -#define IROM_HIGH 0x40400000 -#define DROM_LOW 0x3F400000 -#define DROM_HIGH 0x3F800000 -#define RTC_IRAM_LOW 0x400C0000 -#define RTC_IRAM_HIGH 0x400C2000 -#define RTC_DATA_LOW 0x50000000 -#define RTC_DATA_HIGH 0x50002000 #define SPI_ERROR_LOG "spi flash error" diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index aa30ad4c7..9a439e58f 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "esp_attr.h" #include "esp_log.h" @@ -312,11 +313,15 @@ void bootloader_main() memcpy(&sa, ota_select_map, sizeof(esp_ota_select_entry_t)); memcpy(&sb, (uint8_t *)ota_select_map + SPI_SEC_SIZE, sizeof(esp_ota_select_entry_t)); bootloader_munmap(ota_select_map); + ESP_LOGD(TAG, "OTA sequence values A 0x%08x B 0x%08x", sa.ota_seq, sb.ota_seq); if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) { + ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF"); // init status flash if (bs.factory.offset != 0) { // if have factory bin,boot factory bin + ESP_LOGD(TAG, "Defaulting to factory image"); load_part_pos = bs.factory; } else { + ESP_LOGD(TAG, "No factory image, defaulting to OTA 0"); load_part_pos = bs.ota[0]; sa.ota_seq = 0x01; sa.crc = ota_select_crc(&sa); @@ -341,10 +346,13 @@ void bootloader_main() //TODO:write data in ota info } else { if(ota_select_valid(&sa) && ota_select_valid(&sb)) { - load_part_pos = bs.ota[(((sa.ota_seq > sb.ota_seq)?sa.ota_seq:sb.ota_seq) - 1)%bs.app_count]; + ESP_LOGD(TAG, "Both OTA sequence valid, using OTA slot %d", MAX(sa.ota_seq, sb.ota_seq)-1); + load_part_pos = bs.ota[(MAX(sa.ota_seq, sb.ota_seq) - 1)%bs.app_count]; } else if(ota_select_valid(&sa)) { + ESP_LOGD(TAG, "Only OTA sequence A is valid, using OTA slot %d", sa.ota_seq - 1); load_part_pos = bs.ota[(sa.ota_seq - 1) % bs.app_count]; } else if(ota_select_valid(&sb)) { + ESP_LOGD(TAG, "Only OTA sequence B is valid, using OTA slot %d", sa.ota_seq - 1); load_part_pos = bs.ota[(sb.ota_seq - 1) % bs.app_count]; } else if (bs.factory.offset != 0) { ESP_LOGE(TAG, "ota data partition invalid, falling back to factory"); @@ -475,7 +483,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition) // TODO: actually check md5 } - if (address >= DROM_LOW && address < DROM_HIGH) { + if (address >= SOC_DROM_LOW && address < SOC_DROM_HIGH) { ESP_LOGD(TAG, "found drom segment, map from %08x to %08x", data_offs, segment_header.load_addr); drom_addr = data_offs; @@ -485,7 +493,7 @@ static void unpack_load_app(const esp_partition_pos_t* partition) map = true; } - if (address >= IROM_LOW && address < IROM_HIGH) { + if (address >= SOC_IROM_LOW && address < SOC_IROM_HIGH) { ESP_LOGD(TAG, "found irom segment, map from %08x to %08x", data_offs, segment_header.load_addr); irom_addr = data_offs; @@ -495,12 +503,12 @@ static void unpack_load_app(const esp_partition_pos_t* partition) map = true; } - if (!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) { + if (!load_rtc_memory && address >= SOC_RTC_IRAM_LOW && address < SOC_RTC_IRAM_HIGH) { ESP_LOGD(TAG, "Skipping RTC code segment at %08x\n", data_offs); load = false; } - if (!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) { + if (!load_rtc_memory && address >= SOC_RTC_DATA_LOW && address < SOC_RTC_DATA_HIGH) { ESP_LOGD(TAG, "Skipping RTC data segment at %08x\n", data_offs); load = false; } diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 942ffd4bf..e6c5f899c 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -108,16 +108,6 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *p *p_length = 0; } - if (src_addr % SPI_FLASH_MMU_PAGE_SIZE != 0) { - /* Image must start on a 64KB boundary - - (This is not a technical limitation, only the flash mapped regions need to be 64KB aligned. But the most - consistent way to do this is to have all the offsets internal to the image correctly 64KB aligned, and then - start the image on a 64KB boundary also.) - */ - return ESP_ERR_INVALID_ARG; - } - err = esp_image_load_header(src_addr, log_errors, &image_header); if (err != ESP_OK) { return err; @@ -133,6 +123,21 @@ esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *p return err; } + uint32_t load_addr = segment_header.load_addr; + bool map_segment = (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH) + || (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH); + + + /* Check that flash cache mapped segment aligns correctly from flash it's mapped address, + relative to the 64KB page mapping size. + */ + ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%x load_addr 0x%x", + i, map_segment, segment_data_offs, load_addr); + if (map_segment && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) { + ESP_LOGE(TAG, "Segment %d has load address 0x%08x, conflict with segment data at 0x%08x", + i, load_addr, segment_data_offs); + } + for (int i = 0; i < segment_header.data_len; i += sizeof(buf)) { err = bootloader_flash_read(segment_data_offs + i, buf, sizeof(buf), true); if (err != ESP_OK) { diff --git a/components/bootloader_support/test/component.mk b/components/bootloader_support/test/component.mk new file mode 100644 index 000000000..8c6eb513e --- /dev/null +++ b/components/bootloader_support/test/component.mk @@ -0,0 +1,4 @@ +# +#Component Makefile +# +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive diff --git a/components/bootloader_support/test/test_verify_image.c b/components/bootloader_support/test/test_verify_image.c new file mode 100644 index 000000000..0c6d1ac5b --- /dev/null +++ b/components/bootloader_support/test/test_verify_image.c @@ -0,0 +1,37 @@ +/* + * Tests for bootloader_support esp_image_basic_verify() + */ + +#include +#include +#include "rom/ets_sys.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +#include "freertos/xtensa_api.h" +#include "unity.h" + +#include "esp_partition.h" +#include "esp_ota_ops.h" +#include "esp_image_format.h" + +TEST_CASE("Verify bootloader image in flash", "[bootloader_support]") +{ + uint32_t image_len = 0; + TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_basic_verify(0x1000, true, &image_len)); + TEST_ASSERT_NOT_EQUAL(0, image_len); +} + +TEST_CASE("Verify unit test app image", "[bootloader_support]") +{ + uint32_t image_len = 0; + const esp_partition_t *running = esp_ota_get_running_partition(); + TEST_ASSERT_NOT_EQUAL(NULL, running); + + TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_basic_verify(running->address, true, &image_len)); + TEST_ASSERT_NOT_EQUAL(0, image_len); + TEST_ASSERT_TRUE(image_len <= running->size); +} + diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index fe6acee2a..b42a77690 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -149,6 +149,16 @@ #define TICKS_PER_US_ROM 26 // CPU is 80MHz //}} +/* Overall memory map */ +#define SOC_IROM_LOW 0x400D0000 +#define SOC_IROM_HIGH 0x40400000 +#define SOC_DROM_LOW 0x3F400000 +#define SOC_DROM_HIGH 0x3F800000 +#define SOC_RTC_IRAM_LOW 0x400C0000 +#define SOC_RTC_IRAM_HIGH 0x400C2000 +#define SOC_RTC_DATA_LOW 0x50000000 +#define SOC_RTC_DATA_HIGH 0x50002000 + #define DR_REG_DPORT_BASE 0x3ff00000 #define DR_REG_RSA_BASE 0x3ff02000 #define DR_REG_SHA_BASE 0x3ff03000