ARMv8 没开mmu执行memset引起的非对齐访问异常

发布于:2025-07-09 ⋅ 阅读:(13) ⋅ 点赞:(0)

最近在haps上验证一个新的芯片,记录一下memset访问出错的问题。

在没开mmu和cache的情况下,对全局变量指针进行memset清零操作,发现每次都会出现异常。最后发现是没开mmu导致出现了数据非对齐访问导致报错。

排查EC区域发现是0x25,产生了非对齐访问。

下面是非对齐访问的排查逻辑:

在ARM Cortex-A35处理器(ARMv8-A架构)上,可以通过检查以下状态寄存器来判断是否发生了非对齐内存访问异常:

1. 异常状态寄存器 (ESR_ELx)

这是判断异常类型的关键寄存器:

  • EC 字段 (Exception Class, 位[31:26]):

    • 数据中止异常:0b100101 (0x25)

  • ISS 字段 (Instruction Specific Syndrome, 位[24:0]):

    • 对齐错误:DFSC=0b100001 (0x21)

判断步骤


# 读取ESR_EL1(假设异常发生在EL1)
set esr_value [readreg ESR_EL1]

# 提取EC字段(高6位)
set ec [expr ($esr_value >> 26) & 0x3F]

# 提取DFSC字段(低6位)
set dfsc [expr $esr_value & 0x3F]

# 检查是否是非对齐数据访问异常
if {$ec == 0x25 && $dfsc == 0x21} {
    echo "检测到非对齐内存访问异常!"
}

2. 故障地址寄存器 (FAR_ELx)

记录触发异常的内存地址:


# 读取触发异常的地址
set fault_addr [readreg FAR_EL1]
echo "异常访问地址:0x[format %x $fault_addr]"

完整调试示例脚本


# 连接到目标
connect -p jtag -c cortex-a35

# 设置断点
break vector_data

# 运行程序
run

# 异常发生后检查状态
stop

# 读取关键寄存器
set esr [readreg ESR_EL1]
set far [readreg FAR_EL1]
set pc [readreg PC]

# 解析ESR
set ec [expr ($esr >> 26) & 0x3F]
set dfsc [expr $esr & 0x3F]

# 输出诊断信息
echo "-------------------------"
echo "异常诊断信息:"
echo "PC = 0x[format %x $pc]"
echo "FAR = 0x[format %x $far]"
echo "ESR_EL1 = 0x[format %x $esr]"
echo "EC = 0x[format %x $ec]"
echo "DFSC = 0x[format %x $dfsc]"

# 判断异常类型
if {$ec == 0x25} {
    if {$dfsc == 0x21} {
        echo ">> 非对齐内存访问异常!"
        echo ">> 地址 0x[format %x $far] 未按字长对齐"
    } else {
        echo ">> 其他类型数据中止 (DFSC=0x[format %x $dfsc])"
    }
} else {
    echo ">> 非数据中止异常 (EC=0x[format %x $ec])"
}

关键寄存器说明

寄存器 位域 含义
ESR_ELx EC[31:26] 0x25 数据中止异常
DFSC[5:0] 0x21 对齐错误
FAR_ELx - 任意地址 触发异常的内存地址
PC - 当前地址 发生异常时的指令地址

常见对齐要求

数据类型 ARM64对齐要求
Byte 1字节
Halfword 2字节
Word 4字节
Doubleword 8字节
128-bit向量 16字节

⚠️ 注意事项

  1. 异常级别需匹配:EL1异常查ESR_EL1,EL2查ESR_EL2

  2. 通过SCTLR_ELx.A位可配置对齐检查:

    • A=1:强制对齐检查(默认)

    • A=0:允许非对齐访问(但性能下降)

  3. 使用STM/LDM等多寄存器指令时,地址必须按8字节对齐

可通过以下命令检查对齐检查配置:


# 读取系统控制寄存器
set sctlr [readreg SCTLR_EL1]
set alignment_check [expr ($sctlr >> 1) & 1]  # 提取A位

if {$alignment_check} {
    echo "对齐检查已启用"
} else {
    echo "警告:非对齐访问被允许!"
}


网站公告

今日签到

点亮在社区的每一天
去签到