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
This commit is contained in:
Angus Gratton 2017-07-12 10:25:13 +08:00 committed by Angus Gratton
parent 9487797273
commit 2b0f623259
2 changed files with 21 additions and 5 deletions

View 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",

View file

@ -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