NXP iMX8MM 修改 UART4至 Cortex-A53 核心

By Toradex秦海

1). 简介

NXP iMX8MM SoC UART-4 接口在默认的 ATF(ARM Trusted Firmware) 中被 RDC 分配给了 Cortex-M4 核心,用作 M4 核心的 Debug UART。如果这时候在 Cortex-A53 核心 Linux Devcie-tree 配置中使能 UART-4,就会出现 Kernel Oops 错误,本文就简单示例如何通过修改 ATF 固件来将 UART-4 重新分配给 Cortex-A53 核心使用。

本文测试使用的是 Toradex 基于 iMX8MM SoC 的 Verdin iMX8MM 计算机模块。

2). 准备

a). Verdin iMX8MM Quad 2GB WB IT ARM核心版配合 Dahlia 载板,连接调试串口UART3(载板X18)到开发主机方便调试。

b). 本文测试 iMX8MM Linux基于 Toradex Ycoto Linux BSP 6.x,更多信息可以参考这里

3 ). ATF 固件修改编译

a). ATF 固件是 iMX8MM Boot Container Image的一部分,其中多核心资源管理分配就在这部分固件实现,因此这里先对其进行修改编译,来将 uart4 由默认的 Cortex-M4 重新分配给 Cortex-A53 核心使用。

b). 获取ATF源代码


$ cd ~/workdir

$ git clone https://github.com/nxp-imx/imx-atf.git -b lf_v2.6


c). 应用保证 Verdin iMX8MM 正常工作的 patches

./ 从这里下载如下两个 patches,或者也可以从 Ycoto 编译环境下 eta-toradex-nxp/recipes-bsp/imx-atf/files/ 位置获取。

0001-Revert-Add-NXP-s-SoCs-partition-reboot-support.patch 0002-imx8m-hab.c-work-around-gcc-12.1-false-positives.patch

./ 将补丁应用到 ATF 源码


$ cd ~/workdir/imx-atf

$ git am 0001-Revert-Add-NXP-s-SoCs-partition-reboot-support.patch \

0002-imx8m-hab.c-work-around-gcc-12.1-false-positives.patch


d). 参考++++这里++++说明配置编译toolchain,因为ATF运行于Cortex-A核心,因此需要使用GCC ARM针对Coretx-A核心的GNU-A toolchain,这里使用了9.2 aarch64 64bit版本。


$ cd ~/workdir/toolchain/

解压下载的toolchain压缩包

$ tar xvf gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz

$ ls gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu

9.2-2019.12-x86_64-aarch64-none-linux-gnu-manifest.txt bin lib libexec

aarch64-none-linux-gnu include lib64 share

export 编译环境变量

$ export ARCH=arm

$ export CROSS_COMPILE=aarch64-none-linux-gnu-

$ export PATH=$PATH:~/workdir/toolchain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin

测试toolchain

$ aarch64-none-linux-gnu-gcc --version

aarch64-none-linux-gnu-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025

Copyright © 2019 Free Software Foundation, Inc.

......


e). 参考如下Patch文件修改 ATF 源码


diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c

index 8702d5160..c5bb66040 100644

--- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c

+++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c

@@ -61,7 +61,7 @@ static const struct imx_rdc_cfg rdc[] = {

RDC_MDAn(RDC_MDA_M4, DID1),

/* peripherals domain permission */

  • RDC_PDAPn(RDC_PDAP_UART4, D1R | D1W),
  • RDC_PDAPn(RDC_PDAP_UART4, D0R | D0W),

RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W),

RDC_PDAPn(RDC_PDAP_UART1, D0R | D0W),

@@ -108,7 +108,7 @@ static const struct imx_rdc_cfg rdc[] = {

RDC_MDAn(RDC_MDA_M4, DID1),

/* peripherals domain permission */

  • RDC_PDAPn(RDC_PDAP_UART4, D1R | D1W),
  • RDC_PDAPn(RDC_PDAP_UART4, D0R | D0W),

RDC_PDAPn(RDC_PDAP_UART2, D0R | D0W),

RDC_PDAPn(RDC_PDAP_UART1, D0R | D0W),


f). 编译ATF


$ cd ~/workdir/imx-atf

$ make PLAT=imx8mm IMX_BOOT_UART_BASE=0x30860000 bl31

编译出 bl31.bin 再后续组装Boot Container Image中会需要

$ ls build/imx8mm/release/bl31.bin

build/imx8mm/release/bl31.bin


4 ). Boot Container Image编译组装

a). 本文以下编译流程都是基于当前Toradex 最新Linux BSP V6.3版本操作,其他版本以及后续更新版本和不同硬件平台 (比如 Verdin iMX8MP) 差异可以参考这里说明修改适配。

b). 首先获取 DDR Training firmware


$ cd ~/workdir

$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.17.bin

$ chmod u+x firmware-imx-8.17.bin

$ ./firmware-imx-8.17.bin

$ ls firmware-imx-8.17/firmware/ddr/synopsys/


Verdin iMX8MM 需要的是如下 DDR Training firmware 文件


lpddr4_pmu_train_1d_dmem.bin

lpddr4_pmu_train_2d_dmem.bin

lpddr4_pmu_train_1d_imem.bin

lpddr4_pmu_train_2d_imem.bin


c). U-boot编译

./ 参考++++这里++++说明进行U-boot源代码下载以及编译,这个就是比较常规的bootloader修改编译过程了,针对iMX8MM/iMX8MP平台,如果只是需要修改U-boot(ATF不做修改)的话也需要参考本文流程重新组装Boot Container Image文件后再进行部署。

./ 下载对应BSP版本U-boot源代码


$ cd ~/workdir

$ git clone -b toradex_imx_lf_v2022.04 git://git.toradex.cn/u-boot-toradex.git


./ 编译toolchain和上一章节编译ATF是同样toolchain配置,这里不再赘述。

./ 编译,生成 u-boot-nodtb.bin/u-boot-spl.bin/imx8mm-verdin.dtb用于后续Boot Container Image组装


$ cd ~/workdir/u-boot-toradex

$ make verdin-imx8mm_defconfig

$ make -j$(nproc) 2>&1 | tee build.log

$ ls u-boot-nodtb.bin

u-boot-nodtb.bin

$ ls spl/u-boot-spl.bin

spl/u-boot-spl.bin

$ ls arch/arm/dts/imx8mm-verdin.dtb

arch/arm/dts/imx8mm-verdin.dtb


d). Boot Container Image组装

./ 首先下载 imx-mkimage 工具


$ cd ~/workdir/

$ git clone -b lf-5.15.32_2.0.0 https://github.com/nxp-imx/imx-mkimage.git


./ 将上述章节准备好的DDR Training Firmware、ATF、U-boot binary等文件复制到imx-mkimage对应目录


$ cd ~/workdir/imx-mkimage/

$ cp ~/workdir/firmware-imx-*/firmware/ddr/synopsys/lpddr4_pmu_train_1d_dmem.bin iMX8M

$ cp ~/workdir/firmware-imx-*/firmware/ddr/synopsys/lpddr4_pmu_train_2d_dmem.bin iMX8M

$ cp ~/workdir/firmware-imx-*/firmware/ddr/synopsys/lpddr4_pmu_train_1d_imem.bin iMX8M

$ cp ~/workdir/firmware-imx-*/firmware/ddr/synopsys/lpddr4_pmu_train_2d_imem.bin iMX8M

$ cp ~/workdir/imx-atf/build/imx8mm/release/bl31.bin iMX8M

$ cp ~/workdir/u-boot-toradex/spl/u-boot-spl.bin iMX8M

$ cp ~/workdir/u-boot-toradex/u-boot-nodtb.bin iMX8M

$ cp ~/workdir/u-boot-toradex/arch/arm/dts/imx8mm-verdin.dtb iMX8M/fsl-imx8mm-evk.dtb

$ cp ~/workdir/u-boot-toradex/tools/mkimage iMX8M/mkimage_uboot


./ 组装Boot Container Image,最终生成 flash.bin 文件


$ make clean; make SOC=iMX8MM flash_evk_emmc_fastboot

$ ls iMX8M/flash.bin


5 ). Linux 内核设备树 (Device-Tree) 修改

a). 除了上面 ATF 固件的修改,由于uart4 接口默认 Linux Device Tree 配置是关闭的,这里需要修改打开后重新编译生成新的 Device Tree 文件。

b). 参考这里说明下载 Verdin iMX8MM Ycoto Linux BSP 6.3对应的Linux Kernel branch (toradex_5.15-2.1.x-imx),并配置相应的编译环境,参考如下 patch 修改 device tree源文件后,重新编译生成新的device tree binary 文件 imx8mm-verdin-wifi-dev.dtb


diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi

index a8a906e18d1e..59977b8a3698 100644

--- a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi

+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi

@@ -141,6 +141,11 @@

status = "okay";

};

+/* Verdin UART_4, used by M4 by default need corresponding ATF firmware modification to active */

+&uart4 {

  • status = "okay";

+};

/* Verdin USB_1 */

&usbotg1 {

disable-over-current;


6 ). 部署 测试

a). 从++++这里++++下载Toradex Ycoto Linux BSP Multimedia Image Quarterly 6.3.0+build.7版本,默认image通过Toradex Easy Installer安装后,将 /boot 目录下的默认 imx8mm-verdin-wifi-dev.dtb device-tree 文件替换为章节6 生成的文件后启动测试,由于没有修改 ATF (默认版本是v2.6(release):lf_v2.6-g3c1583ba0a),会报出 kernel Oops 错误。


U-Boot SPL 2022.04-6.3.0+git.c71ae7141f30 (May 15 2023 - 16:20:01 +0000)

DDRINFO: start DRAM init

DDRINFO: DRAM rate 3000MTS

DDRINFO:ddrphy calibration done

DDRINFO: ddrmix config done

Normal Boot

WDT: Started watchdog@30280000 with servicing (60s timeout)

Trying to boot from MMC1

NOTICE: BL31: v2.6(release):lf_v2.6-g3c1583ba0a

NOTICE: BL31: Built : 11:00:38, Nov 21 2022

......

......

0.795948] Internal error: synchronous external abort: 96000210 [#1] PREEMPT SMP

[ 0.803445] Modules linked in:

[ 0.806510] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.15.77-6.3.0+git.ddc6ca4d76ea #1

[ 0.814525] Hardware name: Toradex Verdin iMX8M Mini WB on Verdin Development Board (DT)

[ 0.822624] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)

[ 0.829593] pc : imx_uart_probe+0x31c/0x7d0

[ 0.833791] lr : imx_uart_probe+0x30c/0x7d0

[ 0.837984] sp : ffff800009c1bb60

[ 0.841300] x29: ffff800009c1bb60 x28: 0000000000000000 x27: ffff8000096904c0

[ 0.848452] x26: ffff000000a9de00 x25: 00000000fffffffa x24: 00000000fffffffa

[ 0.855603] x23: ffff000000394810 x22: 0000000000000032 x21: ffff000000394800

[ 0.862754] x20: 0000000000000000 x19: ffff000000889880 x18: ffffffffffffffff

[ 0.869904] x17: 647561625f657361 x16: 62202c3534203d20 x15: ffff000000a9da8a

[ 0.877051] x14: ffffffffffffffff x13: 0000000000000018 x12: 0101010101010101

[ 0.884202] x11: 0000000000000030 x10: 0101010101010101 x9 : 0000000000000000

[ 0.891356] x8 : ffff000000a9df00 x7 : 0000000000000000 x6 : ffff000000088000

[ 0.898504] x5 : 00000000000000c0 x4 : 0000000000000000 x3 : 0000000000000000

[ 0.905652] x2 : 0000000000000000 x1 : ffff80000a320080 x0 : 0000000000000000

[ 0.912805] Call trace:

[ 0.915256] imx_uart_probe+0x31c/0x7d0

[ 0.919103] platform_probe+0x68/0xe0

[ 0.922771] really_probe+0xbc/0x46c

[ 0.926356] __driver_probe_device+0x114/0x190

[ 0.930813] driver_probe_device+0x40/0x100

[ 0.935005] __driver_attach+0xac/0x210

[ 0.938850] bus_for_each_dev+0x70/0xd0

[ 0.942694] driver_attach+0x24/0x30

[ 0.946275] bus_add_driver+0x144/0x244

[ 0.950119] driver_register+0x78/0x130

[ 0.953964] __platform_driver_register+0x28/0x34

[ 0.958673] imx_uart_init+0x3c/0x64

[ 0.962259] do_one_initcall+0x50/0x1b0

[ 0.966102] kernel_init_freeable+0x20c/0x290

[ 0.970468] kernel_init+0x24/0x12c

[ 0.973968] ret_from_fork+0x10/0x20

[ 0.977556] Code: 2a0003f4 35001820 f9400a61 91020021 (b9400021)

[ 0.983674] ---[ end trace 600c5e6ad38c2c3e ]---

[ 0.988366] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

[ 0.996030] SMP: stopping secondary CPUs

[ 0.999963] Kernel Offset: disabled

[ 1.003454] CPU features: 0x00002001,20000846

[ 1.007817] Memory Limit: none

[ 1.010875] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000

00b ]---


b). 用上述章节4生成的 flash.bin文件替换掉刚才下载的BSP 6.3.0 image压缩包里面的imx-boot文件


$ cd ~/workdir/

$ tar xvf Verdin-iMX8MM_Reference-Multimedia-Image-Tezi_6.3.0+build.7.tar

$ cd Verdin-iMX8MM_Reference-Multimedia-Image-Tezi_6.3.0+build.7/

$ rm imx-boot

$ cp imx-mkimage/iMX8QM/flash.bin imx-boot


c). 将上述修改后的image重新通过Toradex Easy Installer更新到Verdin iMX8MM模块后,查看 ATF 版本变化(v2.6(release):lf-6.1.1-1.0.0-2-gc9c586a62-dirty),然后可以成功进入Linux并查看到 UART4 端口 (/dev/ttymxc3)。


U-Boot SPL 2022.04-21601-g7bd2074193 (Sep 04 2023 - 15:51:26 +0800)

DDRINFO: start DRAM init

DDRINFO: DRAM rate 3000MTS

DDRINFO:ddrphy calibration done

DDRINFO: ddrmix config done

Normal Boot

WDT: Started watchdog@30280000 with servicing (60s timeout)

Trying to boot from MMC1

NOTICE: BL31: v2.6(release):lf-6.1.1-1.0.0-2-gc9c586a62-dirty

NOTICE: BL31: Built : 14:49:42, Sep 6 2023

...

...

TDX Wayland with XWayland 6.3.0+build.7 (kirkstone) verdin-imx8mm-07276322 ttymxc0

Verdin-iMX8MM_Reference-Multimedia-Image

root@verdin-imx8mm-07276322:~# ls /dev/ttymxc*

/dev/ttymxc0 /dev/ttymxc1 /dev/ttymxc2 /dev/ttymxc3


d). 可以参考这里说明进行 UART4 串口的测试,UART4 通过 Dahlia载板 X18 USBC 引出。


root@verdin-imx8mm-07276322:~# echo Test_From_Verdin_iMX8MM > /dev/ttymxc3

root@verdin-imx8mm-07276322:~# cat < /dev/ttymxc3

Test_From_Host_PC


7 ). 总结

本文基于NXP iMX8M Mini嵌入式平台简单介绍了修改 ATF 固件来将 UART4 从 Cortex-M4 核心连接到 Cortex-A53以及组装 Boot Container Image 的流程。

相关推荐
IT果果日记18 分钟前
ubuntu 安装 conda
linux·ubuntu·conda
Python私教21 分钟前
ubuntu搭建k8s环境详细教程
linux·ubuntu·kubernetes
羑悻的小杀马特34 分钟前
环境变量简介
linux
小陈phd1 小时前
Vscode LinuxC++环境配置
linux·c++·vscode
是阿建吖!1 小时前
【Linux】进程状态
linux·运维
明明跟你说过2 小时前
Linux中的【tcpdump】:深入介绍与实战使用
linux·运维·测试工具·tcpdump
Komorebi.py3 小时前
【Linux】-学习笔记05
linux·笔记·学习
Mr_Xuhhh3 小时前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
内核程序员kevin6 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip
朝九晚五ฺ10 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习