From 2b0f623259f8af0797cf2a488b0e54762ca34a08 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 12 Jul 2017 10:25:13 +0800 Subject: [PATCH] bootloader/early boot: Error out if >192KB of static DRAM is allocated (temporary fix) 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 --- .../bootloader/src/main/bootloader_start.c | 7 +++++++ components/esp32/cpu_start.c | 19 ++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/components/bootloader/src/main/bootloader_start.c b/components/bootloader/src/main/bootloader_start.c index fd062a5f91..123f67d8f6 100644 --- a/components/bootloader/src/main/bootloader_start.c +++ b/components/bootloader/src/main/bootloader_start.c @@ -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", diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 858036c677..db32c4fdce 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -68,12 +68,12 @@ #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 -- 2.40.0