Enabling M7 Core and Resource Sharing with Linux - Part 3

2024.11.25by debix.io

(Continued: )

@@ -1143,6 +1264,8 @@

priv->rproc = rproc;

priv->dcfg = dcfg;

priv->dev = dev;

+ priv->m_core_ddr_addr = 0;

+ priv->last_load_addr = 0;

if (dcfg->method == IMX_DIRECT_MMIO) {

regmap = syscon_regmap_lookup_by_phandle(np, "syscon");

@@ -1164,6 +1287,10 @@

/* mbox is optional, so not fail here */

}

+ ret = imx_rproc_parse_dt(dev, priv);

+ if (ret)

+ goto err_put_mbox;

+

ret = imx_rproc_addr_init(priv, pdev);

if (ret) {

dev_err(dev, "failed on imx_rproc_addr_init\n");

@@ -1223,6 +1350,14 @@

{

struct rproc *rproc = platform_get_drvdata(pdev);

struct imx_rproc *priv = rproc->priv;

+ if (!IS_ERR(priv->txdb_ch))

+ mbox_free_channel(priv->txdb_ch);

+ if (!IS_ERR(priv->rxdb_ch))

+ mbox_free_channel(priv->rxdb_ch);

+ if (!IS_ERR(priv->tx_ch))

+ mbox_free_channel(priv->tx_ch);

+ if (!IS_ERR(priv->rx_ch))

+ mbox_free_channel(priv->rx_ch);

if (!priv->early_boot)

clk_disable_unprepare(priv->clk);

@@ -1239,7 +1374,7 @@

{ .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },

{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },

{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },

- { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },

+ { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mp },

{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },

{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },

{},

remoteproc_core.c


--- /drivers/remoteproc/remoteproc_core.c

+++ /drivers/remoteproc/remoteproc_core.c

@@ -1114,6 +1114,14 @@

if (!rproc->table_ptr)

return 0;

+ //add by wei

+

+ if ((int)rproc->table_ptr->num < 0) {

+ WARN_ON(rproc->table_ptr->num);

+ rproc->table_ptr->num=0;

+ return 0;

+ }

+

for (i = 0; i < rproc->table_ptr->num; i++) {

int offset = rproc->table_ptr->offset[i];

struct fw_rsc_hdr *hdr = (void *)rproc->table_ptr + offset;

@@ -1373,7 +1381,7 @@

* that any subsequent changes will be applied to the loaded version.

*/

loaded_table = rproc_find_loaded_rsc_table(rproc, fw);

- if (loaded_table) {

+ if (loaded_table && rproc->cached_table) {

memcpy(loaded_table, rproc->cached_table, rproc->table_sz);

rproc->table_ptr = loaded_table;

}

remoteproc_elf_loader.c


--- /drivers/remoteproc/remoteproc_elf_loader.c

+++ /drivers/remoteproc/remoteproc_elf_loader.c

@@ -133,16 +133,16 @@

{

if (!rproc->ops->elf_memcpy)

memcpy(dest, src, count);

-

- rproc->ops->elf_memcpy(rproc, dest, src, count);

+ else

+ rproc->ops->elf_memcpy(rproc, dest, src, count);

}

static void rproc_elf_memset(struct rproc *rproc, void *s, int c, size_t count)

{

if (!rproc->ops->elf_memset)

memset(s, c, count);

-

- rproc->ops->elf_memset(rproc, s, c, count);

+ else

+ rproc->ops->elf_memset(rproc, s, c, count);

}

4. Copy the File

Copy the file hello_world.bin to the Micro SD card in the same partition with the image and device tree.

5. Hardware Connection

Connect UART2 and UART4 to PC, set the baud rate as 115200. Please refer to the figure below:


6. Start the M7 Core

Go to the uboot CLI and run the following command:

  • fatload mmc 1:1 0x48000000 hello_world.bin;cp.b 0x48000000 0x7e0000 20000;  

  • bootaux 0x7e0000  

You can see that UART4S prints hello world on the serial port terminal. This indicates that the M7 core is working properly.

After executing the bootcmd command, if you can enter the system normally, it means that the A53 core and M7 can work simultaneously. 

7. uboot Quick Start

Go to the uboot CLI and run the following command:

  • setenv m7_image hello_world.bin

  • setenv m7_loadaddr 0x7e0000

  • setenv m7_copyaddr 0x96000000

  • setenv m7_loadimage "fatload mmc '${mmcdev}':'${mmcpart}' '${m7_copyaddr}' '${m7_image}'; cp.b '${m7_copyaddr}' '${m7_loadaddr}' 0x20000"

  • setenv run_m7_image "run m7_loadimage; dcache flush; bootaux '${m7_loadaddr}'"  

After you enter the uboot, you can type the run run_m7_image command to directly start the M7 kernel. 


③ Develop the M7 Core Firmware in Debix1.Obtain SDK Source Code

1.Obtain SDK Source Code

https://mcuxpresso.nxp.com/en/download?hash=502a027cddc304d8e16cc44319a90811&uvid=455793&dl=1&js=1&to_vault=true

Download the SDK resource package and copy the SDK package to the Debix board directory:

Create a folder M7_SDK and unzip the SDK package into this folder M7_SDK:

  • mkdir M7_SDK

  • unzip SDK_2_12_0_EVK-MIMX8MP.zip -d M7_SD

2.Install cmake

①Install cmake:

  • sudo apt install cmake

②Replace the dynamic link library, otherwise during later the cmake compilation, it will prompt you that libcurl.so.4 is not found:

  • sudo rm /usr/lib/libcurl.so.4

  • sudo ln -s /usr/lib/libcurl.so.4.7.0 /usr/local/lib/libcurl.so.4

Use ls -l /usr/local/lib/libcurl.so.4 to see if the dynamic link library is installed successfully:

3.Obtain gcc-arm-none-eabi Cross Tool Chain

Enter the directory M7_SDK/, get the tool chain and configure the environment variables:

  • wget https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-aarch64-linux.tar.bz2

  • tar -xvf gcc-arm-none-eabi-9-2019-q4-major-aarch64-linux.tar.bz2

Edit .bashrc file, configure the environment variables, and add the following lines to the last line:

  • sudo vi ~/.bashrc

  • export ARMGCC_DIR=~/M7_SDK/gcc-arm-none-eabi-9-2019-q4-major

  • source ~/.bashrc

4.Compile Firmware

Enter the armcc directory of the hello_world project:

  • cd ~/M7_SDK/boards/evkmimx8mp/demo_apps/hello_world/armgcc/

Run the build_all.sh script, it will generate these folders below in the current directory. Usually use the release version:

  • ./build_all.sh

5.Use the FirmwareCreate a root directory in the M7_SDK directory, mount partition 1 of the SD card to this directory, and then copy the hello_world.bin file compiled in the previous step to this directory:

  • cd ~/M7_SDK

  • mkdir root && cd root

  • sudo cp -f ../boards/evkmimx8mp/demo_apps/hello_world/armgcc/release/hello_world.bin ./

Reset Debix and execute the run run_m7_image command in uboot to load the new firmware running the M7 core.

④ Burn the M7 Core Firmware to Debix and Start It

1. Prepare the firmwareDuring the third compile step, the resulting release folder will have a firmware for hello_world.elf.

2. Check the M7 core statusSwitch to the root user and modify the kernel log printing level.

  • sysctl kernel.printk=7;

Check the M7 core status:

  • cat /sys/class/remoteproc/remoteproc0/state

If the M7 core is started in uboot, it needs to be turned off first:

  • echo stop > /sys/class/remoteproc/remoteproc0/state

3.Burning firmwarel 

  • echo/home/debix/M7_SDK/boards/evkmimx8mp/demo_apps/hello_world/armgcc/release/hello_world.elf > /sys/class/remoteproc/remoteproc0/firmware

4.Start the M7 core

  • echo start > /sys/class/remoteproc/remoteproc0/state

Check the serial port. The following output indicates that the M7 core has started normally, and at this point, serial port 4 will output log information.