.elf loader for M4 core. How to load an ".elf file"?

I found a loader for “.bin” files in oreder to load a bin file in to M4 TCM memory /OCRAM.

But how to load a .elf in to it?
How to load an “.elf” file instead?

Hi

m4fwloader is for binary file. Provided your elf is “single sectioner” (contiguous memory area for text and variable initializers sections), you may convert it from elf to bin with objdump.

1 Like

Thanks edward for your kind reply.
The issue is that indeed, it is not a single section. THe code is larger than 32KB (TCMem) and I must used OCRAM thanks to the code parameter

 __attribute__ ((section (".ocram_text")));

This is why I need to load an .elf file. But I didn’t find yet a proper loader.

Hi @Edge,

Moving all the code to OCRAM could again make your binary m4fwloader friendly.

You should make sure that GCC optimizes away unused code functions. It is not done by default. -ffunction-sections compiler switch makes function placed each to new section, then --gc-sections linker switch allows removing unused sections.

For ELF you should either stick to U-Boot’s bootaux command (the way suggested in Toradex Knowledge Base here) or try Linux remoteproc driver.
Remoteproc seems being not listed in KB. Perhaps this thread may help you. Seach on NXP iMX forums may help as well.

Hi @Edge,

Sorry for the delay.

I created an overlay for you to use the remote proc driver from NXP (imx_rproc.c) with our downstream kernel.
This driver is not enabled by default in our downstream kernel, so in order to use that, the easiest way is to bitbake a new image and add a custom layer with the modified kernel config file.

Please, follow these two guides on how to set up your Yocto environment and also how to customize it with a custom meta-layer:

To make things easier, you can use this custom meta layer that I created here with the necessary kernel config to enable the remote proc: Download - Toradex File Sharing Platform

With the custom image with the imx-rproc enabled, you can add the following overlay to your image:

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx7d-clock.h>

/ {
	compatible = "toradex,colibri-imx7d",
		     "toradex,colibri-imx7d-emmc",
		     "toradex,colibri-imx7s";
};

&{/} {
	imx7d-cm4 {
		compatible = "fsl,imx7d-cm4";
        syscon = <&src>;
		clocks =  <&clks IMX7D_ARM_M4_ROOT_CLK>;
		mbox-names = "tx", "rx", "rxdb", "txdb";
		mboxes = <&mu 0 1
			  &mu 1 1
			  &mu 3 1
			  &mu 2 1>;
		memory-region = <&m4_reserved>;
        status = "okay";
	};
};

Or you can download it here: Download - Toradex File Sharing Platform (I already compiled it, so you can simply copy it to your /boot/overlays folder and enable it. More information here: Device Tree Overlays (Linux) | Toradex Developer Center)

After that, you can reboot your module and the imx-rproc should be ready:

# dmesg | grep rproc
remoteproc remoteproc0: imx-rproc is available

Copy your .elf file to /lib/firmware and then run the following commands:

# cat /sys/class/remoteproc/remoteproc0/state
offline
# echo hello_world.elf > /sys/class/remoteproc/remoteproc0/firmware
# echo start > /sys/class/remoteproc/remoteproc0/state
[ 7818.651262] remoteproc remoteproc0: powering up imx-rproc
[ 7818.659563] remoteproc remoteproc0: Booting fw image hello_world.elf, size 156628
[ 7818.667654] remoteproc remoteproc0: no dtb rsrc-table
[ 7818.672786] imx-rproc imx7d-cm4: No resource table in elf
[ 7818.728362] remoteproc remoteproc0: remote processor imx-rproc is now up

Now you can control the m4 with the “state” file (starting, stopping…) and point the firmware inside /lib/firmware with the /sys/class/remoteproc/remoteproc0/firmware file.

Please, let me know if all the steps are clear and if you need any help with that.

Also, if you would like to use rpmsg with the remote proc, more modifications will be needed, as pointed out by @Edward in this thread: iMX7D 5.4.x kernel. Launching M4 FW using remoteproc - #23 by Edward

Let me know if you wish to use rpmsg, so we can work out a new device tree and a patch to uboot.

Best Regards,
Hiago.

Hi @Edge,

Did you have time to take a look at this?
If my reply helped you, please mark it as a “Solution” so others can benefit from it as well.

Feel free to ask any questions you might have.

Best Regards,
Hiago.

Good morning @hfranco.tx ,

I attach to this conversation since it is the exact place where I’m stuck at.
I’m trying to use remoteproc to control M4 firmware from A7 user space.
I’ve followed your instruction, but I’m clearly missing something.
I’m working with a colibri-imx7d-1gb-emmc on Iris rev 2.0 carrier board, running dunfell, kernel 5.4.193.
Starting from reference-minimal-image, I’ve created a custom image with the following changes

  1. Apply .cfg to defconfig file to enable remoteproc
  2. use a custom .dts, which enable remoteproc and release control of uartB, to be controlled by M4
  3. patch uboot variable, to load m4 firmware at startup with bootaux taking elf file from rootfs
  4. (use systemd instead of connman to set fixed ip address)

The bootaux part is working, cause i see the M4 running through UARTB, but I’m not able to stop/update/restart it from A7, because remoteproc seems not present at all…

From image, you can see remoteproc kernel config parameters are enabled, but there’s nothing in the folder /sys/class/remoteproc/, and rproc does not appear at all under dmesg.

From this second picture, my custom dtb seems to be correctly loaded

Here’s my meta-layer
meta-debug.zip (142.2 KB)

Thanks in advance for your help!

Paolo

Hi @PaoloMichelotti93,

Sorry for the delay. I will try to reproduce that on my side and get back to you.

Best Regards,
Hiago.

Hi @PaoloMichelotti93,

Here I tried the following overlay:

/dts-v1/;
/plugin/;

#include <dt-bindings/clock/imx7d-clock.h>

/ {
	compatible = "toradex,colibri-imx7d",
		     "toradex,colibri-imx7d-emmc",
		     "toradex,colibri-imx7s";
};

&{/} {
	imx7d-cm4 {
		compatible = "fsl,imx7d-cm4";
		clocks =  <&clks IMX7D_ARM_M4_ROOT_CLK>;
		syscon = <&src>;
		mbox-names = "tx", "rx", "rxdb";
		mboxes = <&mu 0 1
			&mu 1 1
			&mu 3 1>;
		status = "okay";
	};
};

&mu {
	status = "okay";
};

&uart2 {
	status = "disabled";
};

and enabling the configuration for remote proc in my Yocto layer:

CONFIG_LOCALVERSION="-5.7.2-devel"
CONFIG_LOCALVERSION_AUTO=y
CONFIG_REMOTEPROC=y
CONFIG_IMX_REMOTEPROC=m

And it worked out of the box:

root@colibri-imx7-emmc-06674594:~# ls -lh /lib/firmware/
-rw-r--r--    1 root     root        1.1K Mar  9  2018 LICENCE.Marvell
-rw-r--r--    1 root     root        2.1K Mar  9  2018 LICENCE.ralink-firmware.txt
-rw-r--r--    1 root     root        2.1K Mar  9  2018 LICENCE.rtlwifi_firmware.txt
-rw-r--r--    1 root     root        2.6K Mar  9  2018 LICENSE.QualcommAtheros_ath10k
-rw-r--r--    1 root     root        2.5K Mar  9  2018 LICENSE.sdma_firmware
drwxr-xr-x   11 root     root        4.0K Mar  9  2018 ath10k
-rwxr-xr-x    1 root     root      278.7K Apr 26 19:46 hello_world.elf
drwxr-xr-x    3 root     root        4.0K Mar  9  2018 imx
drwxr-xr-x    2 root     root        4.0K Mar  9  2018 libertas
drwxr-xr-x    2 root     root        4.0K Mar  9  2018 mrvl
drwxr-xr-x    2 root     root        4.0K Mar  9  2018 nxp
-rw-r--r--    1 root     root        4.0K Mar  9  2018 regulatory.db
-rw-r--r--    1 root     root        1.2K Mar  9  2018 regulatory.db.p7s
-rw-r--r--    1 root     root        8.0K Mar  9  2018 rt2561.bin
-rw-r--r--    1 root     root        8.0K Mar  9  2018 rt2561s.bin
-rw-r--r--    1 root     root        8.0K Mar  9  2018 rt2661.bin
-rw-r--r--    1 root     root        8.0K Mar  9  2018 rt2860.bin
-rw-r--r--    1 root     root        8.0K Mar  9  2018 rt2870.bin
lrwxrwxrwx    1 root     root          10 Mar  9  2018 rt3070.bin -> rt2870.bin
-rw-r--r--    1 root     root        4.0K Mar  9  2018 rt3071.bin
lrwxrwxrwx    1 root     root          10 Mar  9  2018 rt3090.bin -> rt2860.bin
-rw-r--r--    1 root     root        4.0K Mar  9  2018 rt3290.bin
-rw-r--r--    1 root     root        2.0K Mar  9  2018 rt73.bin
drwxr-xr-x    2 root     root        4.0K Mar  9  2018 rtlwifi
root@colibri-imx7-emmc-06674594:~# cat /sys/class/remoteproc/remoteproc0/state 
offline
root@colibri-imx7-emmc-06674594:~# echo hello_world.elf >  /sys/class/remoteproc/remoteproc0/firmware 
root@colibri-imx7-emmc-06674594:~# echo start > /sys/class/remoteproc/remoteproc[  608.255101] remoteproc remoteproc0: powering up imx-rproc
0/state 
[  608.263631] remoteproc remoteproc0: Booting fw image hello_world.elf, size 285396
[  608.271478] remoteproc remoteproc0: no dtb rsrc-table
[  608.276547] imx-rproc imx7d-cm4: No resource table in elf
[  608.332066] remoteproc remoteproc0: remote processor imx-rproc is now up

here is my custom layer:

 .
├──  conf
│  └──  layer.conf
├──  COPYING.MIT
├──  README
└──  recipes-kernel
   └──  linux
      ├──  device-tree-overlays
      │  └──  colibri-imx7_hmp.dts
      ├──  device-tree-overlays_%.bbappend
      ├──  linux-toradex
      │  └──  hmp.cfg
      └── linux-toradex_%.bbappend
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += "file://hmp.cfg"
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"

SRC_URI += "file://colibri-imx7_hmp.dts"

TEZI_EXTERNAL_KERNEL_DEVICETREE =  "colibri-imx7_hmp.dtbo"
TEZI_EXTERNAL_KERNEL_DEVICETREE_BOOT = "colibri-imx7_hmp.dtbo"

do_collect_overlays_prepend () {
    cp ${WORKDIR}/colibri-imx7_hmp.dts ${S}
}

Hope this helps, let me know if you need anything else.

Best Regards,
Hiago.

Hi @hfranco.tx ,

thanks for your help!
Things seems better, but still not working…
Starting from iris-v2 dtb, hmp overlay seems to be correctly loaded

Message unit (and also rpmsg) seems loaded too
mu

rpmsg

remoteproc is started, but an error appears when probing core m4…

Can you help me again?
Thanks

Regards

Paolo

Hello @PaoloMichelotti93,

Could you please provide us with more details about the commands you ran before the error occurred? Alternatively, did you experience the errors immediately after booting the module with the HMP overlay?

Thanks!

Best regards,
Hiago.

Hi @hfranco.tx ,

sorry, my fault.
The error appears immediately during boot, before running any command.

Thanks
Regards

Hi @PaoloMichelotti93,

Thanks for the information. I can’t see this error on my side, can you please share your overlays.txt file? Just the output of cat /boot/overlays.txt. Only the HMP overlay is enabled?

Best Regards,
Hiago.