Reboot m4 from linux without rebooting linux

To update the m4 firmware we currently use the ubiupdatevol on linux to write a new firmware to /dev/ubi0_2 and afterwards reboot the linux so that the u-boot handles the m4 rebooting

As we had no time yet to optimize the linux startup time this can take some time. I tried to do some optimizations, but it seemed like it could be quite time consuming. So my question would be is there maybe another easier way we could use during development to reload and reboot the m4 firmware? One thing I heard about that could be useful is remoteproc.

So my question would be:

  • Is remoteproc feasible to do this?
  • If remoteproc is feasible, would you have any hints where to start?
  • Are there other options to reload and reboot the firmware?

Dear @andriscewo

It seems that there is a Remoteproc driver for the iMX7 available in newer kernel versions:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/remoteproc/imx_rproc.c?h=v4.14
You would have to backport this driver to the Toradex kernel 4.9 and it could work then.

How to use Remoteproc for loading a new M4 image you can find here:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/remoteproc.txt?h=v4.14

Unfortunately we haven’t done anything with Remoteproc on the iMX7 yet. If you should be successful, it would be nice if you can share your research with us.

Regards,
Stefan

Thanks a lot for the input. I will try my luck and should I be successful I will commit a patch

You are welcome. We will be glad to have feedback from you.

Yea that would be interesting.

For now I use imx m4fwloader app , which does this from user space. ( i’m running non Toradex kernel though, but depending on “things”, you may still be able to use it ).
Remoteproc would be next step.

( The m4fwloader with fixes for iMX7D specifically is here:
GitHub - dry-75/imx-m4fwloader: Tool for loading firmware to M4 core on i.MX6SX and 7D )

Thanks for the input.

Note that our Colibri iMX7 are rather nicely supported by upstream/mainline kernels. Those kernels also have remoteproc drivers for i.MX 7.

Currently, upstream kernels do lack proper suspend support and do not have the ttyRPMSG driver.

I need to read on & study remoteproc, for now I just heard the word here & elsewhere before.

Glancing at that code it seems to do exactly what that small app does, not more, just didn’t see how it expects user to pass the blob to it. ( I hope it’s as easy as with that user app ).

Toradex’s kernel and repo and how it updates it are great. I’m thinking to track Toradex’s Git tree for my other iMX7 based SoM, non Toradex. Because Toradex tracks different sources (besides it’s own in depth work that is …)

The user app violates typical user space/kernel space borders: The app writes directly into hardware registers via /dev/mem… Some kernel might not even allow this (e.g. if CONFIG_DEVMEM is disabled, or CONFIG_STRICT_DEVMEM is enabled).

remoteproc is a kernel framework which allows to load the firmware into memory accessible by the remote processor and starts the remote processor. To load the firmware from user space it uses the firmware loading mechanism (hence the M4 core firmware needs to be placed under /lib/firmware). You then can start/stop the firmware using sysfs, see also Documentation/ABI/testing/sysfs-class-remoteproc and Documentation/remoteproc.txt.

Yea I agree on /dev/mem, and that it may not be available or allowed on the system for security reasons may be, was one of my concerns when I found it. I planned to investigate the kernel driver, which wasn’t in bsp provided for my project. All start, stop, reset if it has is great if it has.

For development and debugging, luckily one can always config the kernel how they want and enable that devmem. And hook up firmware file from non specific location, at any time after system booted. All may be handy when you trying out things an debugging.

I understand direct access to hw registers this way from user space is wrong & ugly, but sometimes it’s just easier to try out things (esp. if you never dived deep or new into understanding Linux kernel/driver code). And the small bad app does things straight out of the App note, so easy & quick(er) relatively :slight_smile:

I wonder if OP has back-ported that driver yet, otherwise I’ll get to it sometime.

Nope, didn’t have time yet as we had some other more important issues, but I think I will look into this the next days as we have another issue that might be related to starting / stoping the m4 firmware

Update: @dry I got it to work. In the answer is the description how (you have to adapt the dts entry if you use tcm memory).

I had some success, but I got stuck somewhere. So maybe first what I did.

I applied these Patch files for the backport. Enabled the imx_rproc kernel module with nconfig. Afterwards I added this section to the dts

/ {
	m4_reserved_sysmem1: cm4@00910000 {
		reg = <0x00910000 0x10000>;
	};

	m4_reserved_sysmem2: cm4@00920000 {
		reg = <0x00920000 0x20000>;
	};

	imx7d-cm4 {
		compatible	= "fsl,imx7d-cm4";
		memory-region	= <&m4_reserved_sysmem1>, <&m4_reserved_sysmem2>;
		syscon		= <&src>;
		clocks		= <&clks IMX7D_ARM_M4_ROOT_CLK>;
	};
};

Would this be correct to use the OCRAM memory (using the default OCRAM linker script)?

I added my firmware to /lib/firmware and updated the name in /sys/class/remoteproc/remoteproc0/firmware.
I tried to start the firmware with echo start > /sys/class/remoteproc/remoteproc0/state and got always a write error until I realized that it tries to start the firmware anyways.

So this is where I got stuck with the following error ( dmesg | grep remote ):

[  247.916687] remoteproc remoteproc0: powering up imx-rproc
[  247.961952] remoteproc remoteproc0: Booting fw image RTOScewo.elf, size 126182
[  247.969239] remoteproc remoteproc0: Failed to find resource table
[  247.975371] remoteproc remoteproc0: Boot failed: -22

Any hints what I could try? I found someone that wanted to send a patch that would allow for loading of files without resource tables ( [RFC] remoteproc: support ELF loading without resource table — Linux Remote Processors ), but never finished it as it seems. I could maybe add a resource table, but wouldn’t know where to start. Other ideas?

Hi @andriscewo
It looks like newer kernel versions simply leave table_ptr unset if no resource table is used. Where does it crash if you do something like this? I’m sure it will crash somewhere:)
Regards,
Stefan

Thanks for the suggestion. With this patch it works now Empty resource table patch

Thanks @andriscewo for your update.

It seems that a similar patch is upstream (somewhere around v4.15 as it seems):
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d4bb86f2c39cdd31338dd0274540596aa9ae82c3

You could also give v4.17 a try, it should have descend Colibri iMX7 1GB support.

The remoteproc works as expected. Issue is there are some problems using it together with rpmsg so we abandoned the experiment for now

Thanks for the feedback.

hey @andriscewo
Where is this → " … In the answer is the description how". Is it all in the comments to Stefan’s answer (including your backport?).

Everything you need to get the remoteproc running is in the comments to the answer from stefan. Should you have a problem with overwriting sections in the elf file take a look at this ( Error in M4 ocram linker file - Technical Support - Toradex Community ). Issue is it doesn’t work well together with the rpmsg. Couldn’t get it to run anymore after I used remoteproc

Ok thanks, I’ll let you know if I get that working in my setup.
Atm I’m using luser space app to load and no issues with rpmsg for me.