IMX7D - can't start M4 elf file from U-boot, works from ULINK debugger

Hi,
I wrote a simple demo app for sending short message every second over UART B from Cortex M4 core. I’m using Keil MDK 5 and ULink Pro debugger. Everything works great if I stop Linux from booting and enter debug session from Keil uVision.

Now I’m trying to start M4 app from U-boot, but nothing happens:

    Colibri iMX7 # tftp m4.elf
    Using FEC0 device
    TFTP from server 192.168.1.22; our IP address is 192.168.1.253
    Filename 'm4.elf'.
    Load address: 0x80800000
    Loading: ##################################################  31.4 KiB
    	 3.1 MiB/s
    done
    Bytes transferred = 32144 (7d90 hex)
    Colibri iMX7 # dcache flush
    Colibri iMX7 # bootaux ${loadaddr}
    ## Starting auxiliary core at 0x1FFF8241 ...

U-boot is still alive, but UART_B is not transmitting data. If i repeat the process without rebooting board, I get the message “Auxiliary core is already up”.

I made some changes to uboot enviroment variables:

arch=arm
baudrate=115200
board=colibri_imx7
board_name=colibri_imx7
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf
boot_file=zImage
boot_net_usb_start=usb start
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_targets=mmc0 mmc1 usb0 dhcp 
bootcmd=setenv fdtfile ${soc}-colibri-emmc-${fdt_board}.dtb && run distro_bootcmd;
bootcmd_dhcp=if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;
bootcmd_mmc0=setenv devnum 0; run mmc_boot
bootcmd_mmc1=setenv devnum 1; run mmc_boot
bootcmd_usb0=setenv devnum 0; run usb_boot
bootdelay=15
bootm_size=0x10000000
console=ttymxc0
cpu=armv7
defargs=clk_ignore_unused
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
emmcargs=ip=off root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
emmcboot=run setup; setenv bootargs ${defargs} ${emmcargs} ${setupargs} ${vidargs}; echo Booting from internal eMMC chip...; run m4boot && load mmc 0:1 ${fdt_addr_r} ${soc}-colibri-emmc-${fdt_board}.dtb && load mmc 0:1 ${kernel_addr_r} ${boot_file} && run fdt_fixup && bootz ${kernel_addr_r} - ${fdt_addr_r}
eth1addr=00:14:2d:71:3b:40
ethact=FEC0
ethaddr=00:14:2d:61:3b:40
ethprime=FEC
fdt_addr_r=0x82000000
fdt_board=eval-v3
fdt_fixup=fdt addr ${fdt_addr_r} && fdt rm /soc/aips-bus@30800000/spba-bus@30800000/serial@30890000
fdtcontroladdr=bff94490
initrd_high=0xffffffff
ip_dyn=yes
ipaddr=192.168.1.253
kernel_addr_r=0x81000000
kernel_file=zImage
loadaddr=0x80800000
m4boot=;
mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi
netmask=255.255.255.0
nfsargs=ip=:::::eth0: root=/dev/nfs
nfsboot=run setup; setenv bootargs ${defargs} ${nfsargs} ${setupargs} ${vidargs}; echo Booting from NFS...;dhcp ${kernel_addr_r} && tftp ${fdt_addr_r} ${soc}-colibri-emmc-${fdt_board}.dtb && run fdt_fixup && bootz ${kernel_addr_r} - ${fdt_addr_r}
pxefile_addr_r=0x87100000
ramdisk_addr_r=0x82100000
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x87000000
sdargs=root=/dev/mmcblk1p2 ro rootwait
sdboot=run setup; setenv bootargs ${defargs} ${sdargs} ${setupargs} ${vidargs}; echo Booting from MMC/SD card...; run m4boot && load mmc 1:1 ${kernel_addr_r} ${kernel_file} && load mmc 1:1 ${fdt_addr_r} ${soc}-colibri-emmc-${fdt_board}.dtb && run fdt_fixup && bootz ${kernel_addr_r} - ${fdt_addr_r}
serial#=06372160
serverip=192.168.1.22
setethupdate=if env exists ethaddr; then; else setenv ethaddr 00:14:2d:00:00:00; fi; tftpboot ${loadaddr} ${board}/flash_eth.img && source ${loadaddr}
setsdupdate=mmc rescan && setenv interface mmc && fatload ${interface} 1:1 ${loadaddr} ${board}/flash_blk.img && source ${loadaddr}
setup=setenv setupargs console=tty1 console=${console},${baudrate}n8 ${memargs} consoleblank=0
setupdate=run setsdupdate || run setusbupdate || run setethupdate
setusbupdate=usb start && setenv interface usb && fatload ${interface} 0:1 ${loadaddr} ${board}/flash_blk.img && source ${loadaddr}
soc=imx7d
splashpos=m,m
updlevel=2
usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
variant=-emmc
vendor=toradex
vidargs=video=mxsfb:640x480M-16@60
videomode=video=ctfb:x:640,y:480,depth:18,pclk:39722,le:48,ri:16,up:33,lo:10,hs:96,vs:2,sync:0,vmode:0

Environment size: 4400/8188 bytes

link text

I made elf file from axf file with following command:
fromelf --elf --nodebug --output=M4.elf M4.axf

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x1FFF8000 0x00008000  {    ; load region size_region
  ER_IROM1 0x1FFF8000 0x00008000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00008000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

Elf file is available at following link.

What exact U-Boot version are you talking about?

We are actually in the process of getting such functionality upstreamed:

https://patchwork.ozlabs.org/patch/1192953/

Hi,
I’m using preloaded U-boot version U-Boot 2016.11-1.

U-Boot 2016.11-1.0b1+g07edca0bb8 (Jan 01 1970 - 00:00:00 +0000)
arm-torizon-linux-gnueabi-gcc (GCC) 8.3.0
GNU ld (GNU Binutils) 2.32.0.20190204
Colibri iMX7 # 

I found more than two forum threads describing the same approach:

Tft for M4

The bootaux command can also boot binfiles. Note that images older than 2.7b2 support bin firmwares only. This example loads the binary into the Cortex-M4 local TCM (Tightly Coupled Memory)

Should I use bin file?

HI @tp1234

Should I use bin file?

Actually a .elf should work too. Can you try to boot from SD Card or eMMC Flash and check if you still see the issue?

Best regards,
Jaski

I tried booting multiple elf files from SD Card, but nothing has changed.

Colibri iMX7 # fatload mmc 1 ${loadaddr} M4.elf
reading M4.elf
32768 bytes read in 14 ms (2.2 MiB/s)
Colibri iMX7 # dcache flush
Colibri iMX7 # bootaux ${loadaddr}
## Starting auxiliary core at 0x1FFF8241 ...
Colibri iMX7 # 

Maybe my elf files are corrupted or something? Could someone please provide working elf file for IMX7D and Aster board?

Hi @tp1234 ,

I’ve just tested loading M4 binary from the same revision of U-boot (07edca0bb8):

U-Boot 2016.11 (Nov 25 2019 - 14:28:53 +0200)

CPU:   Freescale i.MX7D rev1.3 996 MHz (running at 792 MHz)
CPU:   Extended Commercial temperature grade (-20C to 105C) at 40C
Reset cause: POR
DRAM:  1 GiB
PMIC:  RN5T567 LSIVER=0x01 OTPVER=0x0d
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
Video: 640x480x18
In:    serial
Out:   serial
Err:   serial
Model: Toradex Colibri iMX7 Dual 1GB (eMMC) V1.1A, Serial# 06449092
Net:   FEC0
Hit any key to stop autoboot:  0 
Colibri iMX7 # dhcp; tftpboot ${fdt_addr_r} ${board_name}/hello_world.elf && bootaux ${fdt_addr_r}
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
BOOTP broadcast 4
BOOTP broadcast 5
DHCP client bound to address 192.168.88.252 (3763 ms)
Using FEC0 device
TFTP from server 192.168.88.2; our IP address is 192.168.88.252
Filename 'colibri_imx7/hello_world.elf'.
Load address: 0x82000000
Loading: ##################################################  194.5 KiB
	 7.6 MiB/s
done
Bytes transferred = 199140 (309e4 hex)
## Starting auxiliary core at 0x1FFF80B5 ...

On UART_B:

# picocom -b 115200 /dev/ttyACM0 
picocom v2.2

port is        : /dev/ttyACM0
flowcontrol    : none
baudrate is    : 115200
parity is      : none
databits are   : 8
stopbits are   : 1
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv -E
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

Type [C-a] [C-h] to see available commands

Terminal ready

Hello World!

I’ve attached the same hello_world.elf I was using. Please check if there is still no output
on your side

Thanks

Thanks @igor.tx,
but still no output. Not sure where to look anymore. I’ll double check everything.

Colibri iMX7 # tftpboot ${fdt_addr_r} hello_world.elf && bootaux ${fdt_addr_r}
Using FEC0 device
TFTP from server 192.168.1.22; our IP address is 192.168.1.253
Filename 'hello_world.elf'.
Load address: 0x82000000
Loading: ##################################################  194.5 KiB
	 5.9 MiB/s
done
Bytes transferred = 199140 (309e4 hex)
## Starting auxiliary core at 0x1FFF80B5 ...

Did you try to output something to UART_B under regular Toradex Linux when M4 is not activated?

@tp1234 btw, could you please try to disable dcache before running any commands?

> dcache off && tftpboot ${fdt_addr_r} hello_world.elf && bootaux ${fdt_addr_r}

Thanks

Hi,
I tried but nothing has changed.

Hi,

Output is not working from UART_B. Is it even possible to use UART_B (Cortex-M4 default console) under linux without device tree modifications? I’m running default torizon with docker runtime image.

sudo chmod 666 /dev/ttymxc1
echo HelloWorld > /dev/ttymxc1

UART_A (Linux / U-boot console) is working as expected.

sudo chmod 666 /dev/ttymxc0
echo HelloWorld > /dev/ttymxc0

Hi @tp1234

You are correct in that you can’t get a response out of UART_B the same way as UART_A. But you can still get a response out of UART_B from the device’s Linux console.

Follow the following documentation: https://developer.toradex.com/getting-started/module-3-hardware-peripherals/basic-uart-usage-colibri-evaluation-board-colibri-imx6

Just up to Step 5 is enough to confirm whether UART_B is enabled and working at least on the Torizon Linux Kernel side of things.

Just to be clear I was able to get a response out of UART_B from the Torizon Linux kernel, but I was unable to get a response via the hello_world.elf from u-boot same as you.

I’m still investigating why that is but for the time being can you confirm that UART_B is at least working for you in the Linux Kernel.

Best Regards,
Jeremias

I finally managed to get response from Torizon linux kernel and from elf file given by @igor.tx.

It seems that I made some false assumptions. UART_B is not the same as UART2. I used Aster X20.10 (UART2_TX) pin for Keil UART transmit test. Elf file and torizon kernel are using X20.8 (UARTB_TX) pin.

I’ll investigate futher and post my findings.

Thanks for your Input. We will wait for your result.