MX6 SoloX bare metal startup

Showing results for 
Search instead for 
Did you mean: 

MX6 SoloX bare metal startup

No ratings

MX6 SoloX bare metal startup

According to section 13.5 (Cortex-M4 Boot Requirements) of the i.MX6SX  Reference Manual :

• Cortex-A9 always boots as the primary core.

• Cortex-M4 does not have a boot ROM and at POR is not provided a clock.

• Cortex-A9 ROM is responsible for the following:

• Loading and authenticating A9 bootloader and initiating Cortex-M4
firmware as a unified image.

• Setting up Cortex-M4 initial exception table in TCRAML

• Launching the Cortex-M4 by enabling its clock.

In addition :  M4 obtains minimal initial vector table, containing

a) Initial Stack pointer

b) Reset vector

c) NMI vector

from a fixed location (zero offset) in TCM(L) after A9 enables it’s clock.

So, A9 (bootloader) is responsible for:

    Configuring M4 initial vector table  in TCM(L) ;

    Loading M4 code ;

    Configuring CSU and RDC for TrustZone (if needed)

      and A9/M4 domain separation ;

    Enabling M4 clock.

   Please look at the enclosed projects, which help to understand how to build, load

and run startup codes for both Cortex-A9 and Cortex-M4 cores of i.MX6 SoloX.

  Also note : the i.MX6 SoloX has two cores with different address mapping.

Please refer to Table 2-1 (System memory map) for Cortex-A9 core and

to Table 2-2 (CM4 memory map) for Cortex-M4 of the i.MX6 SoloX

Reference Manual. To run Cortex-M4 it is needed to fill TCM(L), that
is addressed as TCML ALIAS (from zero). The same memory is mapped

to 0x007f8000 of the Cortex-A9 (non-reflected in the Table 2-1).
Note, this area is accessible by the Cortex-A9 after M4 clock is enabled


The following resources may be helpful, when working with i.MX6 SoloX :

“How to configure Real View ICE  and RealView debugger  to work with i.MX6 SoloX”

“Integrating Processor Expert for i.MX and ARM GCC with Eclipse”

“I.MX6SX start M4 from U-Boot with QSPI flash”

"Loading Code on Cortex-M4 from Linux for the i.MX 6SoloX and i.MX 7Dual/7Solo "

Labels (1)

Nice document Yuri. Do you know why the RM states that the 0x007f8000 area is reserved?

It would be awesome if a further document you explain the RDC and CSU in detail.

Alejandro, hi !

  Appears, I also cannot find any official documents

(except examples) about  0x007f8000 address  mapping.



Got it! Thanks Yuri.



Hi Alejandro

attached part of 6SX_Cortex-M4_Development.pptx presentation

which can be found on below link

SoloX starting M4 & stopping A9 & lowest power with just M4 running

p.12 shows 0x007f8000 address  mapping for A9 TCML

MX6SX A9 TCML address.jpg

Best regards


Thanks a lot Igor!

I can't access the pptx presentation, clicking on the link reports "Access to this place or content is restricted. If you think this is a mistake, please contact your administrator or the person who directed you here."

suggest to ask local FAE to give you access to that document.


Hello Yuri,

Many thanks for your useful post.

I want to debug M4 core by using Jlink, first try to access A9 core, use Jlink commands to change some system registers to enable M4 and then open gdb debug session for it. But I've met problem regarding to reset M4 core when start/stop gdb debug session. I could only reset M4 core by accessing SRC_SCR via A9, this is not really convenient I think.

I think another way that using IMX6SX bare metal project to enable M4 core, I've tried to use Jlink download A9 binary image before starting gdb debug session for M4 successfully. Now I want to copy A9 binary image into a bootable SD card, so after pressing reset button I can start debug M4 core at there.

Would please show me how to generate a bootable SD image, I've tried with the bellow command but it doesn't work :

dd if=test_A9.bin of=/dev/sdb bs=513 seek=2

Thanks so much.

Best Regards


  As for " I could only reset M4 core by accessing SRC_SCR via A9 ... ",
this is correct, CM4 is not intended to be loaded / start without CA9.

Regarding bootable SD, please use the following

Linux command

$ dd if=test_A9.bin of=/dev/sdb bs=512 

  Also, the following - hope - helps.

How to build bootable SD image (for i.MX6 SL as example)



Hi Yuri,

Thanks so much for your help.

Best Regards


How do I compile the attached code? I'm getting the error:

arm-none-eabi-gcc -g -Wall -fmessage-length=0 -o test.out *.s *.c -fno-zero-initialized-in-bss -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp -marm -mlittle-endian -T mx6slx.ld -nostartfiles -Wl,-Map,,--cref,-n
main.c:8:19: fatal error: stdio.h: No such file or directory
#include <stdio.h>
compilation terminated.
syscalls.c:1:19: fatal error: errno.h: No such file or directory
#include <errno.h>
compilation terminated.
In file included from uart.c:14:0:
io.h:17:19: fatal error: stdio.h: No such file or directory
#include <stdio.h>
compilation terminated.
make: *** [test.out] Error 1
makefile:13: recipe for target 'test.out' failed

I'm trying to compile it in eclipse.



  general considerations about eclipse configuration may be found at 



Thanks, Yuri Muhin

I already followed that document but does not help with that issue. This is what I have until now.

Since I'm working on Linux I didn't installed the Code Sourcery thing, instead I'm working with the gcc-arm-none-eabi which I installed using:

$ sudo apt-get install gcc-arm-none-eabi

And therefore I had to change the cs-rm and cs-make for rm and make respectively.

And I was able to create an eclipse project with the downloaded code and configure the project to make it work, nevertheless, I had the first error:

main.c:8:19: fatal error: stdio.h: No such file or directory
#include <stdio.h>               
compilation terminated.
make: *** [cortex_A9/main.o] Error 1
cortex_A9/ recipe for target 'cortex_A9/main.o' failed

And I was able to solve it adding "/usr/include" in the include directories at project > properties. But I'm not sure if this is a correct way of solving this error.

After fixing this error I got a new one:

syscalls.c:168:1: error: unknown type name 'caddr_t'  caddr_t _sbrk(int incr)

And for solving that I had to include explicitly the file "/usr/include/x86_64-linux-gnu/sys/types.h"and also I don't know if that is the correct way to solve it.

Now having eliminated those two errors I have the following one:

Building target: imx6-A9.elf
Invoking: Cross ARM C Linker
arm-none-eabi-gcc -mcpu=cortex-a9 -march=armv7-a -marm -mlittle-endian -mfloat-abi=softfp -mfpu=neon -mno-unaligned-access -fno-zero-initialized-in-bss -O0  -g -T "/home/mmalagon/iMX6/MX6SX_hello_MFG/cortex_A9/mx6slx.ld" -nostartfiles -Wl,-Map,"" -o "imx6-A9.elf"  ./cortex_A9/main.o ./cortex_A9/syscalls.o ./cortex_A9/uart.o   
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: cannot find -lg
makefile:42: recipe for target 'imx6-A9.elf' failed
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: cannot find -lc
collect2: error: ld returned 1 exit status
make: *** [imx6-A9.elf] Error 1

Which I haven't been able to resolve.

I don't know if this error is a consequence of the way I solved the two previous errors.

Am I in the right direction? or what other considerations shall be taken into account to compile the code on LINUX?

Thanks for helping.


  Looks like it is needed specify the correct paths for  libraries and include files.




Indeed, I was missing some libraries.

In summary, If you want to develop bare-metal code for the i.MX6SoloX without using CodeSourcery then you need to execute this:

sudo apt-get install gcc-arm-none-eabi libnewlib-arm-none-eabi -y

And then choose "Custom (arm-none-eabi-gcc)" in Project>Settings>C/C++ Build, 'Toolchains' tab.

Use the code samples here:  since they work out of the box and already include eclipse projects for both the A9 and the M4.

YuriMuhin_ng‌ how come the "vectors.s" found in the code is different than the code igorpadykov‌ posted on the i.mx6 solox for dummies thread?

I've also noticed that the file "vectors.s" in the code from this thread does not use the "PLATFORM_INIT" code found in "plat_startup.h"  for dummies  does.

Also, the most important thing here is that the code in this thread (test.bin) works with the MFG tool and the code in does not. Even though I don't want to be loading my code to RAM every time with the MFG tool every time, as the code from this thread does, I would like to know why this code is working with the mfg tool and the code in the other thread is not.

Is there any document that explaining the differences? Because the enclosed projects don't really help much about knowing how to build startup codes and neither does help the fact that these two "vectors" assembly files are so different, I mean, they have some similarities at the end but the beginning of the files are substantially different and there is no way I've found that explains why these differences.


test.bin has not offset 0x400 for dcd, specially for mfg tool,

please check sect.8.7 Program image i.MX6SX Reference Manual

for descriptions IVT, DCD header.

Best regards


  Hope the following helps. 



Hi Yuri, Guys,

I am trying to run the attached example on A9 and have it load the M4.

I think I pulled in all of the code correctly but maybe not.

What happens is that A9 runs fine and when I tell it to load the M4, the M4 disappears, i.e. I can’t connect to it through Ulink Pro D jtag.

I get this error:

Connected to running target NXP - i.MX6 SoloX Sabre SDB
cd "C:\Users\tomasz\Documents\DS-5 Workspace"
Working directory "C:\Users\tomasz\Documents\DS-5 Workspace"
break -d -p "C:\Users\tomasz\Documents\DS-5 Workspace\fireworks_A9x1-FVP_GCC\src\main.c":25
! Breakpoint 1 has been pended
! No compilation unit matching "C:/Users/tomasz/Documents/DS-5 Workspace/fireworks_A9x1-FVP_GCC/src/main.c" was found
condition 1
break-script 1 ""
ignore 1 0
break-stop-on-cores 1
unsilence 1
Breakpoint 1 unsilenced
core 1
Current core is Cortex-M4 (ID 1)
! Unable to stop device Cortex-M4
! Cannot stop target.


Any ideas?


  CM4 can be accessible only after loading and running its code: 
- CM4 Clock should be On;

- CM4 should be enabled and reset (assertion / negation).



Thanks Yuri, 

Looks like a reset after loading the SW should be changed from m4c_non_sclr_rst to m4c_rst. 

At least for my rev. C of the board.

What seems to work is :

-  reset m4 platform (m4p_rst),

- load the binary

- reset m4 *core* only (m4c_rst)

In the code looks like m4c_non_sclr_rst ( non-self clearing SW reset) is being used.

Seems like it should be replaced w/m4c_rst.




Version history
Revision #:
1 of 1
Last update:
‎07-09-2015 11:53 PM
Updated by: