编译i.MX8M Plus的ARM可信固件时bl31设置异常向量后挂死
自行编译ATF bl31导致系统挂死的调试建议
问题背景
在Phytec phyCORE-i.MX 8M Plus/phyBOARD-Pollux开发板上编译ARM Trusted Firmware(ATF)与U-Boot后,出现以下问题:
- U-Boot SPL执行完成后,系统在加载ATF bl31组件后挂死,控制台仅输出SPL日志,无bl31相关输出:
U-Boot SPL 2024.10 (Jan 02 2025 - 11:24:26 -0800) SoM: PCM-070-0F3243I.A6 PCB rev: 3 WDT: Started watchdog@30280000 with servicing every 1000ms (60s timeout) Trying to boot from BOOTROM Boot Stage: Primary boot image offset 0x8000, pagesize 0x200, ivt offset 0x0
- 已定位问题出在ATF的
include/arch/aarch64/el3_common_macros.S代码段:
/* --------------------------------------------------------------------- * Set the exception vectors. * --------------------------------------------------------------------- */ adr x0, \_exception_vectors msr vbar_el3, x0 isb
msr指令前的调试代码可正常执行,但指令后无响应,推测设置向量表后立即触发了异常,但无法确定类型。
- 使用Phytec BSP提供的预编译
bl31.bin时系统可正常启动,说明SPL及镜像打包流程无问题,仅自编译bl31存在缺陷。 - 主线ATF源码和NXP定制的imx-atf均出现相同问题,且无适配该处理器的JTAG适配器。
调试建议
- 对齐编译配置与官方BSP
对比Phytec BSP中预编译bl31对应的ATF编译参数,确保自编译时的PLATFORM、TARGET_SOC、DEBUG、LOG_LEVEL等参数完全匹配。例如i.MX8MP对应的PLATFORM=imx8mp,TARGET_SOC=imx8mp,同时开启DEBUG=1和最高日志级别LOG_LEVEL=50,尝试输出更多调试信息到控制台。 - 给异常向量表添加硬件级调试输出
在\_exception_vectors对应的所有异常入口(同步异常、异步异常、IRQ、FIQ等)最开头添加汇编代码,直接操作UART硬件寄存器输出特定标记字符(比如给UART数据寄存器写入'A'表示同步异常,'B'表示IRQ等)。由于ATF初始化UART的代码在设置向量表前已执行,可通过这种方式确定触发异常的类型。 - 验证向量表地址合法性
通过查看自编译bl31.elf的反汇编结果,确认\_exception_vectors的实际地址是否处于i.MX8MP EL3允许的内存区域(通常是OCRAM或指定安全内存),且未被SPL或其他固件覆盖。对比硬件手册中EL3内存范围,排查地址越界问题。 - 逐步禁用安全特性缩小范围
临时关闭ATF中的部分安全或初始化特性,比如注释掉MMU初始化代码、跳过GIC中断控制器初始化,测试是否还会在设置向量表后挂死,逐步定位触发异常的根源。 - 对比预编译与自编译二进制的差异
使用objdump或readelf工具对比预编译bl31.bin和自编译版本的反汇编代码,重点查看向量表地址、关键寄存器配置、异常处理入口的差异,排查编译选项导致的代码生成问题。 - 匹配编译器版本
确认自编译使用的交叉编译器版本与Phytec BSP完全一致,不同版本的GCC可能在AArch64指令优化、寄存器分配上存在差异,进而导致异常。例如Phytec可能使用特定版本的Linaro GCC,需严格匹配版本号。
内容的提问来源于stack exchange,提问作者qt_prashle
相关产品推荐
相关产品推荐

