I am working on a patch designed to update the partition tables of an encrypted ESP32 device using a USB connection for the update process. During testing, I've encountered a persistent issue where the device enters a boot loop after the patch is applied. This is preventing the successful completion of the update and rendering the device temporarily unusable. I'm seeking guidance on how to diagnose and resolve this boot loop problem to ensure the partition table update can be applied correctly and the device can boot normally afterwards. Please find the code below:
extern const unsigned char partition_table_bin_start[] asm("_binary_partition_table_bin_start");
extern const unsigned char partition_table_bin_end[] asm("_binary_partition_table_bin_end");
static const char *PARTITION_TABLE_UPDATE_TAG = "PartitionTableUpdate";
#define PARTITION_TABLE_SECTOR_SIZE 0x1000
#define EXPECTED_PARTITION_TABLE_SIZE (partition_table_bin_end - partition_table_bin_start)
void PartitionTablePerformUpdate(void)
{
ESP_LOGI(PARTITION_TABLE_UPDATE_TAG, "Updating partition table");
unsigned char* pBuffer = (unsigned char*)heap_caps_calloc(EXPECTED_PARTITION_TABLE_SIZE, sizeof(unsigned char), MALLOC_CAP_8BIT);
assert(pBuffer);
esp_err_t flashOperationStatus = ESP_OK;
do
{
if ((flashOperationStatus = esp_flash_erase_region(esp_flash_default_chip, CONFIG_PARTITION_TABLE_OFFSET, PARTITION_TABLE_SECTOR_SIZE)) != ESP_OK)
{
ESP_LOGE(PARTITION_TABLE_UPDATE_TAG, "esp_flash_erase_region failed with code %d", flashOperationStatus);
}
else if ((flashOperationStatus = esp_flash_write_encrypted(esp_flash_default_chip, CONFIG_PARTITION_TABLE_OFFSET, partition_table_bin_start, EXPECTED_PARTITION_TABLE_SIZE)) != ESP_OK)
{
ESP_LOGE(PARTITION_TABLE_UPDATE_TAG, "esp_flash_write_encrypted failed with code %d", flashOperationStatus);
}
else if ((flashOperationStatus = esp_flash_read_encrypted(esp_flash_default_chip, CONFIG_PARTITION_TABLE_OFFSET, pBuffer, EXPECTED_PARTITION_TABLE_SIZE)) != ESP_OK)
{
ESP_LOGE(PARTITION_TABLE_UPDATE_TAG, "esp_flash_read_encrypted failed with code %d", flashOperationStatus);
}
} while (memcmp(pBuffer, partition_table_bin_start, EXPECTED_PARTITION_TABLE_SIZE) != 0);
heap_caps_free(pBuffer);
ESP_LOGI(PARTITION_TABLE_UPDATE_TAG, "Partition table successfully updated");
ESP_LOGW(PARTITION_TABLE_UPDATE_TAG, "If you have not done so already, power cycle the device once to apply the new partition table");
std::this_thread::sleep_for(std::chrono::seconds(5));
ESP_LOGI(PARTITION_TABLE_UPDATE_TAG, "After a power cycle, proceed with the USB firmware update");
std::this_thread::sleep_for(std::chrono::seconds(5));
}
Please find the partial boot loop output below:
SPIWP:0xee
mode:DIO, clock div:1
load:0x3ffe6270,len:0x32e4
load:0x4004c000,len:0xc34
load:0x40050000,len:0x4f58
entry 0x4004c200
I (39) boot: ESP-IDF v5.0.7 2nd stage bootloader
I (39) boot: compile time 12:36:41
D (39) bootloader_flash: non-XMC chip detected by SFDP Read (00), skip.
D (42) bootloader_flash: mmu set block paddr=0x00000000 (was 0xffffffff)
I (48) boot: chip revision: v1.0
D (51) boot.esp32s2: magic e9
D (54) boot.esp32s2: segments 03
D (57) boot.esp32s2: spi_mode 02
D (60) boot.esp32s2: spi_speed 0f
D (63) boot.esp32s2: spi_size 02
I (66) boot.esp32s2: SPI Speed : 80MHz
I (70) boot.esp32s2: SPI Mode : DIO
I (74) boot.esp32s2: SPI Flash Size : 4MB
D (77) boot: Enabling RTCWDT(9000 ms)
I (81) boot: Enabling RNG early entropy source...
D (85) bootloader_flash: rodata starts from paddr=0x0000e000, size=0xc00, will be mapped to vaddr=0x3f000000
V (95) bootloader_flash: after mapping, starting from paddr=0x00000000 and vaddr=0x3f000000, 0x10000 bytes are mapped
D (105) boot: mapped partition table 0xe000 at 0x3f00e000
D (110) flash_parts: partition table verified, 7 entries
I (115) boot: Partition Table:
I (118) boot: ## Label Usage Type ST Offset Length
D (124) boot: load partition table entry 0x3f00e000
D (129) boot: type=1 subtype=2
I (132) boot: 0 nvs WiFi data 01 02 0000f000 00004000
D (138) boot: load partition table entry 0x3f00e020
D (143) boot: type=1 subtype=0
I (146) boot: 1 otadata OTA data 01 00 00013000 00002000
D (152) boot: load partition table entry 0x3f00e040
D (157) boot: type=1 subtype=1
I (160) boot: 2 phy_init RF data 01 01 00015000 00001000
D (166) boot: load partition table entry 0x3f00e060
D (171) boot: type=0 subtype=10
I (174) boot: 3 ota_0 OTA app 00 10 00020000 00170000
D (180) boot: load partition table entry 0x3f00e080
D (185) boot: type=0 subtype=11
I (188) boot: 4 ota_1 OTA app 00 11 00190000 00170000
D (194) boot: load partition table entry 0x3f00e0a0
D (199) boot: type=1 subtype=4
I (202) boot: 5 nvs_key NVS keys 01 04 00300000 00001000
I (208) boot: End of partition table
D (212) boot: OTA data offset 0x13000
D (215) bootloader_flash: rodata starts from paddr=0x00013000, size=0x2000, will be mapped to vaddr=0x3f000000
V (225) bootloader_flash: after mapping, starting from paddr=0x00010000 and vaddr=0x3f000000, 0x10000 bytes are mapped
D (235) boot: otadata[0]: sequence values 0x00000001
D (240) boot: otadata[1]: sequence values 0xffffffff
D (245) boot_comm: Only otadata[0] is valid
D (248) boot: Active otadata[0]
D (251) boot: Mapping seq 0 -> OTA slot 0
D (255) boot: Trying partition index 0 offs 0x20000 size 0x170000
D (261) esp_image: reading image header @ 0x20000
D (265) bootloader_flash: mmu set block paddr=0x00020000 (was 0xffffffff)
D (272) esp_image: image header: 0xe9 0x06 0x02 0x02 400230a4
V (277) esp_image: loading segment header 0 at offset 0x20018
V (283) esp_image: segment data length 0x6145c data starts 0x20020
V (289) esp_image: segment 0 map_segment 1 segment_data_offs 0x20020 load_addr 0x3f000020
I (297) esp_image: segment 0: paddr=00020020 vaddr=3f000020 size=6145ch (398428) map
D (304) esp_image: free data page_count 0x00000037
D (309) bootloader_flash: rodata starts from paddr=0x00020020, size=0x6145c, will be mapped to vaddr=0x3f000000
V (318) bootloader_flash: after mapping, starting from paddr=0x00020000 and vaddr=0x3f000000, 0x70000 bytes are mapped
V (415) esp_image: loading segment header 1 at offset 0x8147c
D (415) bootloader_flash: mmu set block paddr=0x00080000 (was 0xffffffff)
V (416) esp_image: segment data length 0x317c data starts 0x81484
V (422) esp_image: segment 1 map_segment 0 segment_data_offs 0x81484 load_addr 0x3ffc5a20
I (430) esp_image: segment 1: paddr=00081484 vaddr=3ffc5a20 size=0317ch ( 12668) load
D (437) esp_image: free data page_count 0x00000037
D (442) bootloader_flash: rodata starts from paddr=0x00081484, size=0x317c, will be mapped to vaddr=0x3f000000
V (451) bootloader_flash: after mapping, starting from paddr=0x00080000 and vaddr=0x3f000000, 0x10000 bytes are mapped
V (465) esp_image: loading segment header 2 at offset 0x84600
D (467) bootloader_flash: mmu set block paddr=0x00080000 (was 0xffffffff)
V (474) esp_image: segment data length 0xba10 data starts 0x84608
V (480) esp_image: segment 2 map_segment 0 segment_data_offs 0x84608 load_addr 0x40022000
0x40022000: _WindowOverflow4 at /Users/mukukakapembwa/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/xtensa_vectors.S:1747
I (488) esp_image: segment 2: paddr=00084608 vaddr=40022000 size=0ba10h ( 47632) load
D (495) esp_image: free data page_count 0x00000037
D (500) bootloader_flash: rodata starts from paddr=0x00084608, size=0xba10, will be mapped to vaddr=0x3f000000
V (509) bootloader_flash: after mapping, starting from paddr=0x00080000 and vaddr=0x3f000000, 0x20000 bytes are mapped
V (533) esp_image: loading segment header 3 at offset 0x90018
D (533) bootloader_flash: mmu set block paddr=0x00090000 (was 0xffffffff)
V (534) esp_image: segment data length 0xe6d4c data starts 0x90020
V (540) esp_image: segment 3 map_segment 1 segment_data_offs 0x90020 load_addr 0x40080020
0x40080020: _stext at ??:?
I (548) esp_image: segment 3: paddr=00090020 vaddr=40080020 size=e6d4ch (945484) map
D (555) esp_image: free data page_count 0x00000037
D (560) bootloader_flash: rodata starts from paddr=0x00090020, size=0xe6d4c, will be mapped to vaddr=0x3f000000
V (570) bootloader_flash: after mapping, starting from paddr=0x00090000 and vaddr=0x3f000000, 0xf0000 bytes are mapped
V (785) esp_image: loading segment header 4 at offset 0x176d6c
D (785) bootloader_flash: mmu set block paddr=0x00170000 (was 0xffffffff)
V (785) esp_image: segment data length 0x8010 data starts 0x176d74
V (791) esp_image: segment 4 map_segment 0 segment_data_offs 0x176d74 load_addr 0x4002da10
0x4002da10: spi_ll_infifo_full_clr at /Users/mukukakapembwa/esp/esp-idf/components/hal/esp32s2/include/hal/spi_ll.h:265
(inlined by) spi_slave_hal_prepare_data at /Users/mukukakapembwa/esp/esp-idf/components/hal/spi_slave_hal_iram.c:45
I (799) esp_image: segment 4: paddr=00176d74 vaddr=4002da10 size=08010h ( 32784) load
D (807) esp_image: free data page_count 0x00000037
D (811) bootloader_flash: rodata starts from paddr=0x00176d74, size=0x8010, will be mapped to vaddr=0x3f000000
V (821) bootloader_flash: after mapping, starting from paddr=0x00170000 and vaddr=0x3f000000, 0x10000 bytes are mapped
V (840) esp_image: loading segment header 5 at offset 0x17ed84
D (840) bootloader_flash: mmu set block paddr=0x00170000 (was 0xffffffff)
V (844) esp_image: segment data length 0x1244 data starts 0x17ed8c
V (849) esp_image: segment 5 map_segment 0 segment_data_offs 0x17ed8c load_addr 0x0
I (857) esp_image: segment 5: paddr=0017ed8c vaddr=00000000 size=01244h ( 4676)
D (864) esp_image: free data page_count 0x00000037
D (869) bootloader_flash: rodata starts from paddr=0x0017ed8c, size=0x1244, will be mapped to vaddr=0x3f000000
V (878) bootloader_flash: after mapping, starting from paddr=0x00170000 and vaddr=0x3f000000, 0x10000 bytes are mapped
V (890) esp_image: image start 0x00020000 end of last section 0x0017ffd0
D (895) bootloader_flash: mmu set block paddr=0x00170000 (was 0xffffffff)
D (902) boot: Calculated hash: 961acd69e1a08be2d48f2fad1e5fa25a787e057f1217861328f4395e7332a4e6
I (920) boot: Loaded app from partition at offset 0x20000
I (920) boot: Checking flash encryption...
D (920) efuse: In EFUSE_BLK0__DATA2_REG is used 3 bits starting with 18 bit
D (926) efuse: In EFUSE_BLK0__DATA0_REG is used 1 bits starting with 4 bit
V (932) flash_encrypt: CRYPT_CNT 1, write protection 0
I (937) flash_encrypt: flash encryption is enabled (1 plaintext flashes left)
I (944) boot: Disabling RNG early entropy source...
D (949) boot: Mapping segment 0 as DROM
D (952) boot: Mapping segment 3 as IROM
D (956) boot: calling set_cache_and_start_app
D (960) boot: configure drom and irom and start
V (964) boot: rodata starts from paddr=0x00020020, vaddr=0x3f000020, size=0x6145c
V (971) boot: after mapping rodata, starting from paddr=0x00020000 and vaddr=0x3f000000, 0x70000 bytes are mapped
V (981) boot: text starts from paddr=0x00090020, vaddr=0x40080020, size=0xe6d4c
0x40080020: _stext at ??:?
V (988) boot: after mapping text, starting from paddr=0x00090000 and vaddr=0x40080000, 0xf0000 bytes are mapped
D (998) boot: start: 0x400230a4
0x400230a4: call_start_cpu0 at /Users/mukukakapembwa/esp/esp-idf/components/esp_system/port/cpu_start.c:285
W (1021) flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)
Compile DATE Apr 14 2025 and TIME 12:36:41
abort() was called at PC 0x400259b1 on core 0
0x400259b1: esp_flash_erase_region at /Users/mukukakapembwa/esp/esp-idf/components/spi_flash/esp_flash_api.c:547 (discriminator 5)
Backtrace: 0x400236ae:0x3ffd24c0 0x40029fe5:0x3ffd24e0 0x40030425:0x3ffd2500 0x400259b1:0x3ffd2570 0x4008a0e4:0x3ffd25c0 0x4009b031:0x3ffd25f0 0x40166698:0x3ffd3070
0x400236ae: panic_abort at /Users/mukukakapembwa/esp/esp-idf/components/esp_system/panic.c:425
0x40029fe5: esp_system_abort at /Users/mukukakapembwa/esp/esp-idf/components/esp_system/esp_system.c:153
0x40030425: abort at /Users/mukukakapembwa/esp/esp-idf/components/newlib/abort.c:38
0x400259b1: esp_flash_erase_region at /Users/mukukakapembwa/esp/esp-idf/components/spi_flash/esp_flash_api.c:547 (discriminator 5)
0x4008a0e4: PartitionTablePerformUpdate() at /Users/mukukakapembwa/GC_Projects/ESP32-wifi-driver/src/wifi-module/main/main.cpp:204
0x4009b031: app_main at /Users/mukukakapembwa/GC_Projects/ESP32-wifi-driver/src/wifi-module/main/main.cpp:234
0x40166698: main_task at /Users/mukukakapembwa/esp/esp-idf/components/freertos/app_startup.c:208
ELF file SHA256: 8e6541ea25e6bd48
Rebooting...
ESP-ROM:esp32s2-rc4-20191025
Build:Oct 25 2019
rst:0x3 (RTC_SW_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
Saved PC:0x40023293
0x40023293: esp_restart_noos_dig at /Users/mukukakapembwa/esp/esp-idf/components/esp_system/esp_system.c:64 (discriminator 1)
I would really appreciate any guidance in resolving the issue.
Thank you for your input. I was able to access the regions by allowing writing to dangerous flash regions. In menuconfig:
(Top) -> Component config -> SPI Flash driver -> Writing to dangerous flash regions (Allowed)