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 ITARM核心版配合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 am0001-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
$ makeverdin-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
$ cpimx-mkimage/iMX8QM/flash.binimx-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的流程。