diff --git a/firmware/target/arm/imx233/app.lds b/firmware/target/arm/imx233/app.lds index b378f9ea16..335aa4fcc3 100644 --- a/firmware/target/arm/imx233/app.lds +++ b/firmware/target/arm/imx233/app.lds @@ -39,7 +39,7 @@ SECTIONS { _dramcopystart = .; } > DRAM - + .text : { *(.text*) @@ -47,6 +47,8 @@ SECTIONS *(.rodata*) } > DRAM + _dramtextend = .; + .itext : { _iramstart = .; // always 0 @@ -77,12 +79,17 @@ SECTIONS _initcopy = LOADADDR(.init); + /* crt0 needs a temporary stack which does not overlap with init and itext + * and is in physical memory: put it *after* init and itext. A small one suffices */ + crt0_tmpstack_phys = _dramcopyend + 0x200 - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR; + .dramcopyend (NOLOAD) : { _dramcopyend = .; } > DRAM - .stack (NOLOAD) : + /* the stack overlaps the init and itext region, to reclaim space */ + .stack _dramtextend (NOLOAD) : { *(.stack) stackbegin = .; @@ -90,9 +97,6 @@ SECTIONS stackend = .; } > DRAM - /* physical address of the stack */ - stackend_phys = stackend - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR; - /* treat .bss and .ncbss as a single section */ .bss (NOLOAD) : { diff --git a/firmware/target/arm/imx233/boot.lds b/firmware/target/arm/imx233/boot.lds index 68472d129c..ca455b47ca 100644 --- a/firmware/target/arm/imx233/boot.lds +++ b/firmware/target/arm/imx233/boot.lds @@ -74,7 +74,7 @@ SECTIONS } > DRAM /* physical address of the stack */ - stackend_phys = stackend - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR; + crt0_tmpstack_phys = stackend - CACHED_DRAM_ADDR + UNCACHED_DRAM_ADDR; /* treat .bss and .ncbss as a single section */ .bss (NOLOAD) : diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S index 0a71da5d08..5e1720c7c9 100644 --- a/firmware/target/arm/imx233/crt0.S +++ b/firmware/target/arm/imx233/crt0.S @@ -56,9 +56,12 @@ start: bic r0, r1 mcr p15, 0, r0, c1, c0, 0 - /* To call the C code we need a stack, since the stack is in virtual memory - * use the stack's physical address */ - ldr sp, =stackend_phys + /* To call the C code we need a stack, since the loader's stack might be + * in virtual memory, we need a physical address for the stack. Furthermore, + * we cannot use the main firmware stack yet because it overlaps with the + * init code which will be moved later. We rely on the linker to provide + * a safe, temporary stack */ + ldr sp, =crt0_tmpstack_phys /* Enable MMU */ bl memory_init