请阅读【嵌入式开发学习必备专栏 】
文章目录
- ARMv8/v9 软件设置断点地址
- 断点地址软件配置流程
- 代码实现
 
 
ARMv8/v9 软件设置断点地址
在ARMv8/9架构中,可以通过寄存器 DBGBVR0_EL1 设置断点。这个寄存器是一系列调试断点值寄存器中的第一个DBGBVRn_EL1,其中n表示寄存器编号,对于ARMv8/9,通常可以有多个这样的寄存器,具体数量取决于实现:
• DBGBCR0_EL1 and DBGBVR0_EL1 are for breakpoint number zero.
• DBGBCR1_EL1 and DBGBVR1_EL1 are for breakpoint number one.
• DBGBCR2_EL1 and DBGBVR2_EL1 are for breakpoint number two.
• …
• …
• DBGBCR<n-1>_EL1 and DBGBVR<n-1>_EL1 are for breakpoint number (n-1).
DBGBVR0_EL1允许在EL1(异常级别1,通常是操作系统级别)控制下设置断点,从而帮助开发人员进行代码调试。
DBGBVR0_EL1寄存器通常在软件调试过程中使用,它使得调试器能够指定程序中的一个地址,当处理器执行到这个地址时自动触发一个调试事件(如断点异常)。这对于调试复杂的软件问题非常有用,尤其是在需要理解程序流程或识别特定代码执行路径时。
此外,DBGBVR0_EL1 可以进行下面内容匹配:
— An instruction virtual address.
— A Context ID.
— A VMID value.
— A concatenation of both a Context ID value and a VMID value.
关于 ARM Debug 相关内容推荐阅读:请阅读【ARM Coresight SoC-400/SoC-600
专栏导读】
为了方便测试,在PC执行到设置的断点地址之后让CPU停下来,这里需要配置下系统debug 寄存器 EDSCR.HDE: Halting debug enable 位,EDSCR 寄存器的内容如下:
 
 STATUS, bits [5:0]: debug 状态的 flag, 具体含义如下:
- 0b000001PE is restarting, exiting Debug state.
- 0b000010PE is in Non-debug state.
- 0b000111Breakpoint.
- 0b010011External debug request.
- 0b011011Halting step, normal.
- 0b011111Halting step, exclusive.
- 0b100011OS Unlock Catch.
- 0b100111Reset Catch.
- 0b101011Watchpoint.
- 0b101111HLT instruction.
- 0b110011Software access to debug register.
- 0b110111Exception Catch.
- 0b111011Halting step, no syndrome
其它位的含义这里就不再过多介绍
注意:为了使软件可以配置对 breakpoint 相关寄存器进行配置,还需要对寄存器oslar_el1配置,进行解锁操作。
在断点地址配置好之后,如还需配置具体的触发方式及断点使能配置,需要对寄存器DBGBCR<n>:Debug Breakpoint Control Registers, n = 0 - 15:
 
Bit[13]   (HMC) - 1'b1    - State matching (match all states)
Bits[8:5] (BAS) - 4'b1111 - Match A32/A64 instructions
Bits[2:1] (PMC) - 2'b11   - State matching (match all states)
Bit[0]    (E)   - 1'b1    - Enable this breakpoint
断点地址软件配置流程
- 设置断点地址:将你希望断点触发的代码地址写入DBGBVR0_EL1。
- 配置断点控制寄存器(DBGBCR0_EL1):与DBGBVR0_EL1一起使用的还有控制寄存器(例如DBGBCR0_EL1),它用于配置断点的类型(如硬件断点)和行为(如断点触发条件)。你需要根据需求配置这些控制寄存器,以确保断点以正确的方式被触发。
- 运行调试会话:当程序执行到达DBGBVR0_EL1指定的地址时,将触发断点,此时可以通过调试器查看程序状态,包括寄存器、内存和其他有用的调试信息。
- 处理断点触发:一旦断点触发,你可以使用调试器来检查程序的状态、修改变量或寄存器的值,或是单步执行程序来进一步调试。
代码实现
cpu_bkpt_test:stp  x0, x1, [sp, #-0x10]!mrs     x0, mdscr_el1orr     x0, x0, #(0x1 << 14)   msr     mdscr_el1, x0mov     x0, #0msr     oslar_el1, x0          isbadr     x0, bkpt0msr     dbgbvr0_el1, x0   mov     x0, #0x21E7       msr     dbgbcr0_el1, x0  isbbkpt0:bl bkpt_testldp x0, x1, [sp], #0x10ret
关于 ARMv8/v9 汇编指令的学习推荐阅读:ARM64 常见汇编指令学习
为了方便观察测试,在汇编代码中调用一个打印函数,如果测试不成功,会进行打印,具体实现如下:
void bkpt_test(void)
{log_info("-------------\n");
}
在执行到上面断点函数bkpt0之后,可以通过trace32观察到 trace32 状态改变:
 
关于 trace32 的使用推荐阅读专栏:请阅读【Trace32 ARM 专栏导读】