diff --git a/app/platform/common.c b/app/platform/common.c index d6a213ed..78f4ad76 100644 --- a/app/platform/common.c +++ b/app/platform/common.c @@ -13,15 +13,22 @@ void cmn_platform_init(void) // **************************************************************************** // Internal flash support functions +#if defined(__ESP8266__) // This symbol must be exported by the linker command file and must reflect the // TOTAL size of flash used by the eLua image (not only the code and constants, // but also .data and whatever else ends up in the eLua image). FS will start // at the next usable (aligned to a flash sector boundary) address after // flash_used_size. - -// extern char flash_used_size[]; extern char _flash_used_end[]; +#elif defined(__ESP32__) +/* This symbol must be exported by the linker command file and contain the + * size of all the sections packed into the irom0_flash.bin file, in order + * for us to find the end of used flash. + */ +extern char _irom0_bin_min_sz[]; +#endif + // Helper function: find the flash sector in which an address resides // Return the sector number, as well as the start and end address of the sector static uint32_t flashh_find_sector( uint32_t address, uint32_t *pstart, uint32_t *pend ) @@ -69,6 +76,7 @@ uint32_t platform_flash_get_num_sectors(void) uint32_t platform_flash_get_first_free_block_address( uint32_t *psect ) { +#if defined(__ESP8266__) // Round the total used flash size to the closest flash block address uint32_t start, end, sect; NODE_DBG("_flash_used_end:%08x\n", (uint32_t)_flash_used_end); @@ -83,6 +91,17 @@ uint32_t platform_flash_get_first_free_block_address( uint32_t *psect ) *psect = sect; return start; } +#elif defined(__ESP32__) + uint32_t flash_offs = IROM0_START_FLASH_ADDR + (uint32_t)_irom0_bin_min_sz; + uint32_t sect = + (flash_offs + INTERNAL_FLASH_SECTOR_SIZE-1)/INTERNAL_FLASH_SECTOR_SIZE; + ++sect; /* compensate for various headers not counted in _irom0_bin_min_sz */ + + if (psect) + *psect = sect; + + return sect * INTERNAL_FLASH_SECTOR_SIZE; +#endif } uint32_t platform_flash_write( const void *from, uint32_t toaddr, uint32_t size ) diff --git a/app/platform/cpu_esp32.h b/app/platform/cpu_esp32.h index 15da143e..3307a351 100644 --- a/app/platform/cpu_esp32.h +++ b/app/platform/cpu_esp32.h @@ -55,8 +55,11 @@ #define INTERNAL_FLASH_SIZE ( (SYS_PARAM_SEC_START) * INTERNAL_FLASH_SECTOR_SIZE ) -// TODO: double-check flash mapped address -#define INTERNAL_FLASH_MAPPED_ADDRESS 0x40084000 +/* Note: technically irom0 starts at +0x10, but that's not a page boundary! */ +#define IROM0_START_MAPPED_ADDR 0x40080000 +#define IROM0_START_FLASH_ADDR 0x40000 +// TODO: might need to revamp all this once cache windows fully understood +#define INTERNAL_FLASH_MAPPED_ADDRESS IROM0_START_MAPPED_ADDR #if defined(FLASH_SAFE_API) #define flash_write flash_safe_write diff --git a/app/platform/platform.c b/app/platform/platform.c index 670ad850..1bb5fd4d 100755 --- a/app/platform/platform.c +++ b/app/platform/platform.c @@ -853,7 +853,7 @@ int platform_flash_erase_sector( uint32_t sector_id ) uint32_t platform_flash_mapped2phys (uint32_t mapped_addr) { -#ifdef __ESP8266__ +#if defined(__ESP8266__) uint32_t cache_ctrl = READ_PERI_REG(CACHE_FLASH_CTRL_REG); if (!(cache_ctrl & CACHE_FLASH_ACTIVE)) return -1; @@ -861,8 +861,10 @@ uint32_t platform_flash_mapped2phys (uint32_t mapped_addr) bool b1 = (cache_ctrl & CACHE_FLASH_MAPPED1) ? 1 : 0; uint32_t meg = (b1 << 1) | b0; return mapped_addr - INTERNAL_FLASH_MAPPED_ADDRESS + meg * 0x100000; +#elif defined(__ESP32__) + // TODO: need to handle drom0 addresses too? + return mapped_addr - IROM0_START_MAPPED_ADDR + IROM0_START_FLASH_ADDR; #else - // FIXME - return mapped_addr - INTERNAL_FLASH_MAPPED_ADDRESS; +# error "unknown board" #endif } diff --git a/ld/nodemcu32.ld b/ld/nodemcu32.ld index b74a61d9..8dd2ce39 100644 --- a/ld/nodemcu32.ld +++ b/ld/nodemcu32.ld @@ -278,7 +278,19 @@ SECTIONS LONG(0) LONG(0) /* Null-terminate the array */ _irom0_text_end = ABSOLUTE(.); - _flash_used_end = ABSOLUTE(.); + + /* Due to the way the gen_appbin.py script packs the bundle that goes into + * flash, we don't have a convenient _flash_used_end symbol on the ESP32. + * Instead we sum up the three sections we know goes into the + * irom0_flash.bin, so we can use that as a starting point to scan for + * the next free page. We could presumably be even more specific and + * account for the block headers and trailing checksum. Maybe later. + */ + _irom0_bin_min_sz = ABSOLUTE( + _irom0_text_end - _irom0_text_start + + _text_end - _text_start + + _data_end - _data_start); + } >irom0_0_seg :irom0_0_phdr .lit4 : ALIGN(4)