diff --git a/esp8266/esp8266_common.ld b/esp8266/esp8266_common.ld
index 1da835681a2798df75609f384ec201f461fb7902..bc983df70030fd89ad9918a2dbc9b94f49b61b56 100644
--- a/esp8266/esp8266_common.ld
+++ b/esp8266/esp8266_common.ld
@@ -19,6 +19,8 @@ EXTERN(_KernelExceptionVector)
 EXTERN(_NMIExceptionVector)
 EXTERN(_UserExceptionVector)
 
+_firmware_size = ORIGIN(irom0_0_seg) + LENGTH(irom0_0_seg) - 0x40200000;
+
 PROVIDE(_memmap_vecbase_reset = 0x40000000);
 
 /* Various memory-map dependent cache attribute settings: */
diff --git a/esp8266/modesp.c b/esp8266/modesp.c
index 432fd5ac31c9852071ba8d29f782dc863d618102..5eaae27d6ab050fce7e61f257389f4b8fa061847 100644
--- a/esp8266/modesp.c
+++ b/esp8266/modesp.c
@@ -159,12 +159,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);
 // we assume there's a yaota8266 bootloader.
 #define IS_OTA_FIRMWARE() ((*(uint32_t*)0x40200000 & 0xff00) == 0x100)
 
+extern byte _firmware_size[];
+
 STATIC mp_obj_t esp_flash_user_start(void) {
-    if (IS_OTA_FIRMWARE()) {
-        return MP_OBJ_NEW_SMALL_INT(0x3c000 + 0x90000);
-    } else {
-        return MP_OBJ_NEW_SMALL_INT(0x90000);
-    }
+    return MP_OBJ_NEW_SMALL_INT((uint32_t)_firmware_size);
 }
 STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_user_start_obj, esp_flash_user_start);