2222#include "bootloader_memory_utils.h"
2323#include "soc/soc_caps.h"
2424#include "hal/cache_ll.h"
25+ #include "spi_flash_mmap.h"
2526
2627#define ALIGN_UP (num , align ) (((num) + ((align) - 1)) & ~((align) - 1))
2728
@@ -77,7 +78,7 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t
7778static esp_err_t verify_image_header (uint32_t src_addr , const esp_image_header_t * image , bool silent );
7879
7980/* Verify a segment header */
80- static esp_err_t verify_segment_header (int index , const esp_image_segment_header_t * segment , uint32_t segment_data_offs , bool silent );
81+ static esp_err_t verify_segment_header (int index , const esp_image_segment_header_t * segment , uint32_t segment_data_offs , esp_image_metadata_t * metadata , bool silent );
8182
8283/* Log-and-fail macro for use in esp_image_load */
8384#define FAIL_LOAD (...) do { \
@@ -559,7 +560,7 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
559560
560561 ESP_LOGV (TAG , "segment data length 0x%" PRIx32 " data starts 0x%" PRIx32 , data_len , data_addr );
561562
562- CHECK_ERR (verify_segment_header (index , header , data_addr , silent ));
563+ CHECK_ERR (verify_segment_header (index , header , data_addr , metadata , silent ));
563564
564565 if (data_len % 4 != 0 ) {
565566 FAIL_LOAD ("unaligned segment length 0x%" PRIx32 , data_len );
@@ -748,7 +749,7 @@ static esp_err_t process_segment_data(int segment, intptr_t load_addr, uint32_t
748749 return ESP_OK ;
749750}
750751
751- static esp_err_t verify_segment_header (int index , const esp_image_segment_header_t * segment , uint32_t segment_data_offs , bool silent )
752+ static esp_err_t verify_segment_header (int index , const esp_image_segment_header_t * segment , uint32_t segment_data_offs , esp_image_metadata_t * metadata , bool silent )
752753{
753754 if ((segment -> data_len & 3 ) != 0
754755 || segment -> data_len >= SIXTEEN_MB ) {
@@ -761,13 +762,39 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header
761762 uint32_t load_addr = segment -> load_addr ;
762763 bool map_segment = should_map (load_addr );
763764
765+ #if SOC_MMU_PAGE_SIZE_CONFIGURABLE
766+ /* ESP APP descriptor is present in the DROM segment #0 */
767+ if (index == 0 && metadata -> start_addr != ESP_BOOTLOADER_OFFSET ) {
768+ const esp_app_desc_t * app_desc = (const esp_app_desc_t * )bootloader_mmap (segment_data_offs , sizeof (esp_app_desc_t ));
769+ if (!app_desc || app_desc -> magic_word != ESP_APP_DESC_MAGIC_WORD ) {
770+ ESP_LOGE (TAG , "Failed to fetch app description header!" );
771+ return ESP_FAIL ;
772+ }
773+
774+ // Convert from log base 2 number to actual size while handling legacy image case (value 0)
775+ metadata -> mmu_page_size = (app_desc -> mmu_page_size > 0 ) ? (1UL << app_desc -> mmu_page_size ) : SPI_FLASH_MMU_PAGE_SIZE ;
776+ if (metadata -> mmu_page_size != SPI_FLASH_MMU_PAGE_SIZE ) {
777+ ESP_LOGI (TAG , "MMU page size mismatch, configured: 0x%x, found: 0x%" PRIx32 , SPI_FLASH_MMU_PAGE_SIZE , metadata -> mmu_page_size );
778+ }
779+ bootloader_munmap (app_desc );
780+ } else if (index == 0 && metadata -> start_addr == ESP_BOOTLOADER_OFFSET ) {
781+ // Bootloader always uses the default MMU page size
782+ metadata -> mmu_page_size = SPI_FLASH_MMU_PAGE_SIZE ;
783+ }
784+ #else // SOC_MMU_PAGE_SIZE_CONFIGURABLE
785+ metadata -> mmu_page_size = SPI_FLASH_MMU_PAGE_SIZE ;
786+ #endif // !SOC_MMU_PAGE_SIZE_CONFIGURABLE
787+
788+ const int mmu_page_size = metadata -> mmu_page_size ;
789+ ESP_LOGV (TAG , "MMU page size 0x%x" , mmu_page_size );
790+
764791 /* Check that flash cache mapped segment aligns correctly from flash to its mapped address,
765- relative to the 64KB page mapping size.
792+ relative to the MMU page mapping size.
766793 */
767794 ESP_LOGV (TAG , "segment %d map_segment %d segment_data_offs 0x%" PRIx32 " load_addr 0x%" PRIx32 ,
768795 index , map_segment , segment_data_offs , load_addr );
769796 if (map_segment
770- && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE ) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE ))) {
797+ && ((segment_data_offs % mmu_page_size ) != (load_addr % mmu_page_size ))) {
771798 if (!silent ) {
772799 ESP_LOGE (TAG , "Segment %d load address 0x%08" PRIx32 ", doesn't match data 0x%08" PRIx32 ,
773800 index , load_addr , segment_data_offs );
0 commit comments