Hi,
I am currently developing a firmware on the Cortex-M7 of the i.MX8M Nano (MIMX8MN4CVTIZ) based on an example using RPmsg-lite, remoteproc, FreeRTOS and CMSIS-DSP.
I try to build using the linker file MIMX8MN4xxxxx_cm7_ram.ld provided by the MCUXpresso SDK with the following configuration :
/* Specify the memory areas */
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000240
m_text (RX) : ORIGIN = 0x00000240, LENGTH = 0x0001FDC0
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
m_data2 (RW) : ORIGIN = 0x80000000, LENGTH = 0x01000000
}
Which would apparently start at the ITCM of the system according to the declared memory map :
When I build the text section is quite big (mostly due to CMSIS-DSP) :
Memory region Used Size Region Size %age Used m_interrupts: 576 B 576 B 100.00% m_text: 123704 B 130496 B 94.80% m_data: 61032 B 128 KB 46.56% m_data2: 0 GB 16 MB 0.00%
And when I run it I get this error :
[ 82.135828] imx-rproc imx8mn-cm7: Translation failed: da = 0x1e578 len = 0xee68
[ 82.143174] remoteproc remoteproc0: bad phdr da 0x1e578 mem 0xee68
In the output.map I see the address in error corresponds to __DATA_ROM, the end of the text section :
0x000000000001e578 __etext = . 0x000000000001e578 __DATA_ROM = . .data 0x0000000020000000 0x98 load address 0x000000000001e578 0x0000000020000000 . = ALIGN (0x4) 0x0000000020000000 __DATA_RAM = . 0x0000000020000000 __data_start__ = . *(.data)
My question is regarding the section declaration of the same linker file :
/* The program code and other data goes into internal RAM */
.text :
{
. = ALIGN(4);
*(.text) /* .text sections (code) */
*(.text*) /* .text* sections (code) */
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
*(.glue_7) /* glue arm to thumb code */
*(.glue_7t) /* glue thumb to arm code */
*(.eh_frame)
KEEP (*(.init))
KEEP (*(.fini))
. = ALIGN(4);
} > m_text
...
__etext = .; /* define a global symbol at end of code */
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
.data : AT(__DATA_ROM)
{
. = ALIGN(4);
__DATA_RAM = .;
__data_start__ = .; /* create a global symbol at data start */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
KEEP(*(.jcr*))
. = ALIGN(4);
__data_end__ = .; /* define a global symbol at data end */
} > m_data
Does ".data : AT(__DATA_ROM)" mean that the .data section starts at the end of the .text section ? Why is that and therefore what is the point declaring the start address of m_data in MEMORY {} ?
If I understand correctly this would mean that .data section could overflow the ITCM range, especially when .text is close to its maximum size like my fw. What am I or the linker doing wrong ?
Thanks a lot your help!
Hello,
I build with _cm7_ddr_ram.ld and it cannot boot when loaded from linux with remoteproc :
[ 1302.815264] remoteproc remoteproc0: Booting fw image octopus_fw_m7.elf.elf, size 515580
[ 1302.823689] remoteproc remoteproc0: bad phdr da 0x80000000 mem 0x240
[ 1302.830075] remoteproc remoteproc0: Failed to load program segments: -22
[ 1302.837157] remoteproc remoteproc0: Boot failed: -22
And I have reserve the memory on linux' size :
@ycx
Hello,
I have some doubts regarding memory address of 8000_0000 for CM7
address area. According to chapter 2.1.3 (Cortex-M7 Memory Map) of
i.MX 8M Nano Reference Manual (Rev. 1, 11/2020) :
4000_0000 - BFFF_FFFF is DDR Address of 2048MB
Regards,
Yuri.
Hi Yuri,
Yes and my system only has 512MB DDR which only makes ranges 0x4000_0000 - 0x6000_0000 available (for M7 this range is peripheral: Execute Never). How do I configure the linker script so that I can load M7 firmware in DDR from uboot ?
Thanks a lot.
Yann
My guess is I should use aliased range that is (M7) 0x1000_0000 - 0x1FFD_FFFF according to memory map, which makes (A53) 0x4000_0000 - 0x4FFD_FFFF.
So after moving kernel load address etc and reserving e.g. (A53) 0x4000_0000 - 0x40FF_FFFF, I should put offset 0x1000_0000 in the linker script and, in uboot, load fw at address 0x4000_0000.
Correct ?
Thank you
@ycx
Hello,
Yes, generally Your approach is correct.
Note: aliased range (M7) 0x1000_0000 - 0x1FFD_FFFF corresponds (M7)
0x4000_0000 - BFFF_FFFF, which in its turn maps to A53 0x4000_0000 - BFFF_FFFF.
Regards,
Yuri.
@ycx
Hello,
Generally the linker file lines below are intended for code / data relocation.
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
.data : AT(__DATA_ROM)
{
Please use the linked below file with explanation how to do it.
https://community.nxp.com/t5/Kinetis-Design-Studio-Knowledge/Relocating-Code-and-Data-Using-the-KDS-...
In Your case - perhaps - it would be better to try using DRAM configuration; *_cm7_ddr_ram.ld
Regards,
Yuri.