]> granicus.if.org Git - esp-idf/commitdiff
bootloader/early boot: Error out if >192KB of static DRAM is allocated (temporary...
authorAngus Gratton <angus@espressif.com>
Wed, 12 Jul 2017 02:25:13 +0000 (10:25 +0800)
committerAngus Gratton <gus@projectgus.com>
Wed, 12 Jul 2017 05:06:56 +0000 (13:06 +0800)
Currently the last 128KB of DRAM is reserved for the bootloader & early boot stacks. This means if >192KB of static DRAM
is allocated, the only available heap is this region - which is disabled until the scheduler starts. As a result, you
get either heap corruption on early boot if the static data overlaps startup heap (leading to very weird errors), or
FreeRTOS will fail to start when it can't malloc() anything.

Long term fix is to move the stacks & bootloader data to the very end of RAM, and only reserve that part for early
boot. This is a little fiddly because of also wanting to make sure this memory is not preemptively fragmented when it
gets reintroduced to the heap. This will become more important if/when we have more static allocation options in the
future.

For now, these errors make it clear why the boot has failed.

Ref TW13909

components/bootloader/src/main/bootloader_start.c
components/esp32/cpu_start.c

index fd062a5f91794cf06b26936d7a7ad3da5302eaf2..123f67d8f65c856876b825dbf23653f9ada7b8af 100644 (file)
@@ -520,6 +520,13 @@ static void unpack_load_app(const esp_partition_pos_t* partition)
                bootloader RAM... */
 
             if (end_addr < 0x40000000) {
+                if (end_addr > 0x3FFE0000) {
+                    /* Temporary workaround for an ugly crash, until we allow >192KB of static DRAM */
+                    ESP_LOGE(TAG, "DRAM segment %d (start 0x%08x end 0x%08x) too large for IDF to boot",
+                             segment, start_addr, end_addr);
+                    return;
+                }
+
                 sp = (intptr_t)get_sp();
                 if (end_addr > sp) {
                     ESP_LOGE(TAG, "Segment %d end address %08x overlaps bootloader stack %08x - can't load",
index 858036c6779103ac9bbecf92d4946a0a737e91db..db32c4fdce149237034c4862fa93a4ccf84055c7 100644 (file)
 #define STRINGIFY(s) STRINGIFY2(s)
 #define STRINGIFY2(s) #s
 
-void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
-void start_cpu0_default(void) IRAM_ATTR;
+void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default"))) __attribute__((noreturn));
+void start_cpu0_default(void) IRAM_ATTR __attribute__((noreturn));
 #if !CONFIG_FREERTOS_UNICORE
-static void IRAM_ATTR call_start_cpu1();
-void start_cpu1(void) __attribute__((weak, alias("start_cpu1_default")));
-void start_cpu1_default(void) IRAM_ATTR;
+static void IRAM_ATTR call_start_cpu1() __attribute__((noreturn));
+void start_cpu1(void) __attribute__((weak, alias("start_cpu1_default"))) __attribute__((noreturn));
+void start_cpu1_default(void) IRAM_ATTR __attribute__((noreturn));
 static bool app_cpu_started = false;
 #endif //!CONFIG_FREERTOS_UNICORE
 
@@ -126,6 +126,13 @@ void IRAM_ATTR call_start_cpu0()
         esp_panic_wdt_stop();
     }
 
+    // Temporary workaround for an ugly crash, until we allow > 192KB of static DRAM
+    if ((intptr_t)&_bss_end > 0x3FFE0000) {
+        // Can't use assert() or logging here because there's no .bss
+        ets_printf("ERROR: Static .bss section extends past 0x3FFE0000. IDF cannot boot.\n");
+        abort();
+    }
+
     //Clear BSS. Please do not attempt to do any complex stuff (like early logging) before this.
     memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
 
@@ -287,6 +294,7 @@ void start_cpu0_default(void)
             ESP_TASK_MAIN_PRIO, NULL, 0);
     ESP_LOGI(TAG, "Starting scheduler on PRO CPU.");
     vTaskStartScheduler();
+    abort(); /* Only get to here if not enough free heap to start scheduler */
 }
 
 #if !CONFIG_FREERTOS_UNICORE
@@ -313,6 +321,7 @@ void start_cpu1_default(void)
 
     ESP_EARLY_LOGI(TAG, "Starting scheduler on APP CPU.");
     xPortStartScheduler();
+    abort(); /* Only get to here if FreeRTOS somehow very broken */
 }
 #endif //!CONFIG_FREERTOS_UNICORE