M4 Cortex firmware stops working after Mender integration on Apalis iMX8QM

Hardware & Software Setup

  • Board: Toradex Apalis iMX8QM V1.1
  • BSP Version: toradex-bsp-6.7.0 (trying to integrate with toradex-bsp-6.2.0 for Mender)
  • Mender Setup: Using meta-mender-community/meta-mender-toradex
  • Kernel: Linux 5.15.148-6.7.0-devel

Problem Description

I have a Cortex-M4 firmware that handles CAN communication. It works perfectly without Mender, but stops functioning properly after Mender OTA integration.

What Works:

:white_check_mark: M4 firmware loads from rootfs via U-Boot
:white_check_mark: M4 starts successfully (bootaux complete)
:white_check_mark: M4 sends initialization messages (“hello world”)
:white_check_mark: RPMSG channel established (/dev/ttyRPMSG30 exists)
:white_check_mark: Mender OTA updates work correctly

What Doesn’t Work:

:cross_mark: M4 appears to stop after sending initial messages
:cross_mark: No further RPMSG communication
:cross_mark: CAN functionality doesn’t work

Key Observations

1. Memory Reservation Issue:

[    0.000000] OF: fdt: Reserved memory: failed to reserve memory for node 'm4@88000000': base 0x0000000088000000, size 128 MiB

2. Device Tree has the reservation:

$ cat /sys/firmware/devicetree/base/reserved-memory/m4@88000000/reg | hexdump -C
00000000  00 00 00 00 88 00 00 00  00 00 00 00 08 00 00 00

(Correctly shows: base=0x88000000, size=128MB)

3. Boot logs show M4 working initially:

[    3.875948] imx_rpmsg_tty virtio3.rpmsg-virtual-tty-channel.-1.30: new channel: 0x400 -> 0x1e!
[    3.886594] rpmsg_tty_cb68 65 6c 6c 6f 20 77 6f 72 6c 64 21    hello world!

Then silence - no further messages.

My Configuration

U-Boot Environment (working):

/* Boot M4 */
 #define M4_BOOT_ENV \
-	"m4_0_image=m4_0.bin\0" \
+	"m4_0_image=/home/pixii/Cortex_M4/pixii_lls.bin\0" \
 	"m4_1_image=m4_1.bin\0" \
-	"loadm4image_0=fatload mmc 0:1 ${loadaddr} ${m4_0_image}\0" \
+	"loadm4image_0=ext4load mmc 0:2 ${loadaddr} ${m4_0_image}\0" \
 	"loadm4image_1=fatload mmc 0:1 ${loadaddr} ${m4_1_image}\0" \
 	"m4boot_0=run loadm4image_0; dcache flush; bootaux ${loadaddr} 0\0" \
-	"m4boot_1=run loadm4image_1; dcache flush; bootaux ${loadaddr} 1\0" \
+	"m4boot_1=run loadm4image_1; dcache flush; bootaux ${loadaddr} 1\0"
 
 /* Enable Distro Boot */
 #define BOOT_TARGET_DEVICES(func) \
@@ -39,6 +39,7 @@
 
 /* Initial environment variables */
 #define CONFIG_EXTRA_ENV_SETTINGS \
+	"bootcmd=run m4boot_0; run distro_bootcmd\0" \
 	BOOTENV \
 	M4_BOOT_ENV \
 	MEM_LAYOUT_ENV_SETTINGS \

U-Boot defconfig:

CONFIG_ARM=y
CONFIG_ARCH_IMX8=y
CONFIG_SYS_TEXT_BASE=0x80020000
CONFIG_SYS_MALLOC_LEN=0x2800000
CONFIG_SYS_MALLOC_F_LEN=0x8000
CONFIG_NR_DRAM_BANKS=3
CONFIG_SYS_MEMTEST_START=0x88000000
CONFIG_SYS_MEMTEST_END=0x89000000
CONFIG_ENV_SIZE=0x4000
CONFIG_ENV_OFFSET=0x800000
CONFIG_ENV_OFFSET_REDUND=0x1000000
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8qm-apalis"
CONFIG_BOOTAUX_RESERVED_MEM_BASE=0x88000000
CONFIG_BOOTAUX_RESERVED_MEM_SIZE=0x08000000
CONFIG_TARGET_APALIS_IMX8=y
CONFIG_IMX_SNVS_SEC_SC=y
CONFIG_IMX_BOOTAUX=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_REMAKE_ELF=y
CONFIG_SYS_LOAD_ADDR=0x95400000
# CONFIG_FIT is not set
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_BOOTDELAY=0
CONFIG_ZERO_BOOTDELAY_CHECK=y
CONFIG_SILENT_CONSOLE=y
CONFIG_SILENT_CONSOLE_UPDATE_ON_RELOC=y
CONFIG_SYS_DEVICE_NULLDEV=y
CONFIG_SILENT_CONSOLE_UPDATE_ON_SET=y
CONFIG_SILENT_U_BOOT_ONLY=y
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="test -n ${fdtfile} || setenv fdtfile ${soc}-apalis${variant}-${fdt_board}.dtb"
CONFIG_LOG=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SYS_PROMPT="Apalis iMX8 # "
CONFIG_CMD_CPU=y
# CONFIG_BOOTM_NETBSD is not set
CONFIG_CMD_ASKENV=y
CONFIG_CMD_BMP=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DM=y
CONFIG_CMD_FUSE=y
#CONFIG_CMD_GPIO is not set
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
# CONFIG_CMD_USB is not set
# CONFIG_CMD_USB_MASS_STORAGE is not set
CONFIG_CMD_CACHE=y
CONFIG_CMD_UUID=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SYS_MMC_ENV_PART=0
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_VERSION_VARIABLE=y
CONFIG_IP_DEFRAG=y
# CONFIG_TFTP_BLOCKSIZE is not set
# CONFIG_TFTP_TSIZE is not set
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_ENV=y
CONFIG_CLK_IMX8=y
CONFIG_CPU=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82800000
CONFIG_FASTBOOT_BUF_SIZE=0x08000000
CONFIG_FASTBOOT_FLASH=y
# CONFIG_GPIO_HOG is not set
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_IMX_LPI2C=y
CONFIG_MISC=y
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_FSL_USDHC=y
CONFIG_PHYLIB=y
CONFIG_PHY_ADDR_ENABLE=y
# CONFIG_PHY_MICREL is not set
# CONFIG_PHY_MICREL_KSZ90X1 is not set
# CONFIG_DM_ETH is not set
# CONFIG_FEC_MXC_SHARE_MDIO is not set
# CONFIG_FEC_MXC_MDIO_BASE is not set
# CONFIG_FEC_MXC is not set
# CONFIG_MII is not set
# CONFIG_PHY is not set
CONFIG_CDNS3_USB_PHY=y
# CONFIG_PINCTRL is not set
# CONFIG_PINCTRL_IMX8 is not set
CONFIG_POWER_DOMAIN=y
CONFIG_IMX8_POWER_DOMAIN=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_SERIAL=y
CONFIG_FSL_LPUART=y
CONFIG_DM_THERMAL=y
CONFIG_IMX_SCU_THERMAL=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_CDNS3=y
CONFIG_USB_CDNS3_GADGET=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Toradex"
CONFIG_USB_GADGET_VENDOR_NUM=0x1b67
CONFIG_USB_GADGET_PRODUCT_NUM=0x4000
CONFIG_CI_UDC=y
CONFIG_USB_PORT_AUTO=y
CONFIG_OF_LIBFDT_OVERLAY=y
# CONFIG_EFI_LOADER is not set
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="setenv fdtfile ${mender_dtb_name}"
CONFIG_CMD_BOOTCOUNT=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_ENV=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_DM_PWM=y
CONFIG_VIDEO=y
CONFIG_DM_VIDEO=y
CONFIG_BACKLIGHT_GPIO=y
CONFIG_VIDEO_IMXDPUV1=y
CONFIG_VIDEO_IMX8_LVDS=y
CONFIG_VIDEO_LOGO=y
CONFIG_SPLASH_SCREEN=y
CONFIG_SPLASH_SOURCE=y
CONFIG_SPLASH_SCREEN_ALIGN=y
CONFIG_BMP_16BPP=y
CONFIG_BMP_24BPP=y
CONFIG_BMP_32BPP=y
# CONFIG_CFB_CONSOLE is not set

local.conf (Mender settings):

# Mender Artifact name
MENDER_ARTIFACT_NAME = "test-v1.0"

# specify bsp version
TORADEX_BSP_VERSION="toradex-bsp-6.2.0"

#MENDER CONFIGURATIONS
INHERIT += "mender-full"
INHERIT += "mender-toradex"
DISTRO_FEATURES:append = " systemd"
VIRTUAL-RUNTIME_init_manager = "systemd"
DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
VIRTUAL-RUNTIME_initscripts = ""



# Comment/remove below to enable GRUB integration instead of U-Boot
MENDER_FEATURES_ENABLE:append = " mender-uboot mender-image mender-image-sd"
MENDER_FEATURES_DISABLE:append = " mender-grub mender-image-uefi"

IMAGE_CLASSES += "image_type_mender_tezi"
IMAGE_FSTYPES:append = " mender_tezi"
IMAGE_FSTYPES:remove = " teziimg"
IMAGE_INSTALL:append = " kernel-image kernel-devicetree"


# Remove files from boot partition that are loaded by Mender
# from the root partitions; this allows the files to be updated OTA
IMAGE_BOOT_FILES:remove:mender-uboot = "zImage ${KERNEL_DEVICETREE} overlays.txt overlays/*;overlays/"

# Settings for apalis-imx8
#
MENDER_IMAGE_BOOTLOADER_BOOTSECTOR_OFFSET:apalis-imx8 = "0"
OFFSET_SPL_PAYLOAD:apalis-imx8 = ""
MENDER_BOOT_PART_SIZE_MB:apalis-imx8 = "32"
MENDER_STORAGE_TOTAL_SIZE_MB:apalis-imx8 = "12288"
KERNEL_DEVICETREE:apalis-imx8 = "freescale/imx8qm-apalis-v1.1-ixora-v1.2.dtb"
MENDER_STORAGE_DEVICE:apalis-imx8 = "/dev/mmcblk0"
MENDER_BOOT_PART = "${MENDER_STORAGE_DEVICE_BASE}1"
MENDER_DATA_PART = "${MENDER_STORAGE_DEVICE_BASE}4"
MENDER_ROOTFS_PART_A = "${MENDER_STORAGE_DEVICE_BASE}2"
MENDER_ROOTFS_PART_B = "${MENDER_STORAGE_DEVICE_BASE}3"

# Append the Mender provided bootargs to tdxargs
# the Toradex boot.scr will overwrite bootargs so we stash the context in tdxargs
MENDER_UBOOT_POST_SETUP_COMMANDS:append = " ; setenv tdxargs \${tdxargs} \${bootargs}; "

# Make sure the Toradex boot script finds the overlays and overlays.txt file in
# the /boot directory of the rootfs partition
MENDER_UBOOT_POST_SETUP_COMMANDS:append = " ; setenv overlays_file /boot/overlays.txt ; setenv overlays_prefix boot/overlays/ "


#meta-mender-validation configuration
MENDER_FEATURES_ENABLE:append = " mender-prepopulate-inactive-partition"
IMAGE_INSTALL:append = " bootloader-validation"

#Mender Update Modules
IMAGE_INSTALL:append = " mender-ipk mender-rootfs-version-check mender-qt"




Questions

  1. Is the “failed to reserve memory” warning expected when M4 is loaded by U-Boot? Or does this indicate Linux might be using M4’s memory?

  2. Does Mender’s partition layout affect M4 memory regions? The M4 works without Mender, suggesting something in Mender’s configuration interferes.

  3. Should I add no-map property to the M4 reserved-memory node? Would this prevent Linux from accessing M4’s memory?

  4. Has anyone successfully integrated M4 firmware with Mender on i.MX8? Any specific configurations needed?

What I’ve Tried

  • :white_check_mark: Loading M4 firmware from rootfs using ${mender_uboot_root} (dynamic partition)
  • :white_check_mark: Using dedicated M4 load address (0x88000000) separate from kernel
  • :white_check_mark: Running M4 load in preboot before Mender’s bootcmd
  • :white_check_mark: Verified device tree overlays load correctly (including CAN overlay)
  • :cross_mark: Not yet tried: kernel command line memmap=128M$0x88000000

Additional Information

M4 firmware binary is in rootfs at /home/pixii/Cortex_M4/pixii_lls.bin and loads successfully (74KB file).

Any guidance would be greatly appreciated! Is this a known issue with Toradex + Mender + M4 integration?

References

  • meta-mender-community: meta-mender-toradex-nxp
  • BSP: toradex-bsp-6.7.0
  • Board: apalis-imx8

Hi, I’m the Toradex AI Assistant.

I might make mistakes or occasionally get you wrong. Our support team will step in if needed.


I can help troubleshoot your Cortex-M4 firmware issue with Mender integration on the Apalis iMX8QM. Based on the documentation, this appears to be a memory reservation conflict.

Memory Reservation Analysis

The “failed to reserve memory” warning you’re seeing is significant. For RPMsg to work properly, it’s necessary to allocate the correct RAM buffers in the device tree file (1). Toradex provides device tree overlays for an out-of-the-box experience with HMP, and these overlays are compatible with all Downstream and upstream-based modules starting from BSP and Torizon OS 6 (1).

Device Tree Configuration

The device tree structure comprises nodes that represent different hardware components, and each node contains properties that describe the configuration of the corresponding hardware component (2). For your Apalis iMX8QM, you need to ensure proper memory area allocation.

The two CPU platforms (Cortex-A and Cortex-M) use different memory layouts to access individual subsystems (3). This is critical for your setup since the M4 needs dedicated memory regions that Linux shouldn’t access.

Recommended Solutions

1. Device Tree Overlay Application

Check if you have the appropriate HMP overlay applied. For overlays marked as available, they are pre-compiled (*.dtbo) into Torizon OS and BSP reference images (4). You should verify that the proper overlay is loaded for your Apalis iMX8.

2. Memory Buffer Configuration

The buffer reservation works by defining specific memory addresses in the device tree (4). For your configuration, ensure that:

  • The memory region at 0x88000000 is properly reserved
  • The no-map property is included to prevent Linux from accessing M4’s memory
  • The reservation happens before Linux kernel initialization

3. RPMsg Communication Setup

RPMsg (Remote Processor Messaging) is a communication protocol for inter-processor communication on embedded Linux systems that enables efficient data exchange between processors in a heterogeneous multi-core environment (1). Since your RPMSG channel establishes initially but then stops communicating, this suggests a memory conflict after Linux fully boots.

Getting Started with HMP

The proper approach for HMP setup involves (5):

  1. Set up resource sharing between the cores: Configure your pins and HMP memory areas
  2. Configure your host machine to build firmware binary: Install and configure the MCUXpresso IDE or CLI toolchain
  3. Load binaries into the Cortex-M: Deploy and run your binary to the target hardware

Mender Integration Considerations

Based on the community discussion, there are known challenges with Mender integration on Toradex platforms (6). The issue you’re experiencing could be related to how Mender’s partition layout affects the memory reservation timing during boot.

Next Steps

  1. Verify the HMP overlay is properly applied for your Apalis iMX8QM
  2. Add the no-map property to your M4 reserved-memory node
  3. Consider using kernel command line memmap=128M$0x88000000 as you mentioned
  4. Check if the memory reservation timing conflicts with Mender’s boot sequence

The fact that your M4 works without Mender but fails with it strongly suggests a boot-time memory allocation conflict that needs to be resolved through proper device tree configuration.

Best regards, Toradex AI Assistant.


Did you like my answer? :+1: :-1:

If I answered your question, please tick the “Solution” checkbox.

For follow-up questions to me, please use @ToradexAI in your post.