树莓派3B+通过JTAG GDB无法触发断点的问题排查
树莓派3B+ U-Boot JTAG调试问题
环境与前期操作
- 制作搭载RPi OS Lite的SD卡,修改
config.txt启用JTAG并设置引导u-boot.bin(替代默认kernel.img),树莓派3B+可正常启动U-Boot。 - 使用基于FT2232H的Flyswatter2 JTAG调试器连接设备,执行以下命令建立OpenOCD连接,状态正常:
$ sudo openocd -f /usr/local/share/openocd/scripts/interface/ftdi/flyswatter2.cfg -f /usr/local/share/openocd/scripts/board/rpi3.cfg [sudo] password for naveen: Open On-Chip Debugger 0.12.0-g4d87f6dca (2024-03-22-16:22) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'. Warn : Transport "jtag" was already selected trst_only separate trst_push_pull Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections Info : clock speed 4000 kHz Info : JTAG tap: bcm2837.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4) Info : bcm2837.cpu0: hardware has 6 breakpoints, 4 watchpoints Info : bcm2837.cpu1: hardware has 6 breakpoints, 4 watchpoints Info : bcm2837.cpu2: hardware has 6 breakpoints, 4 watchpoints Info : bcm2837.cpu3: hardware has 6 breakpoints, 4 watchpoints Info : gdb port disabled Info : starting gdb server for bcm2837.cpu0 on 3333 Info : Listening on port 3333 for gdb connections Info : starting gdb server for bcm2837.cpu1 on 3334 Info : Listening on port 3334 for gdb connections Info : starting gdb server for bcm2837.cpu2 on 3335 Info : Listening on port 3335 for gdb connections Info : starting gdb server for bcm2837.cpu3 on 3336 Info : Listening on port 3336 for gdb connections
- 成功连接GDB并查看目标数据:
$ /opt/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gdb u-boot Reading symbols from u-boot... (gdb) target remote :3333 Remote debugging using :3333 0x000000003b379450 in ?? () (gdb) mon halt (gdb) mon reg pc pc (/64): 0x000000003b379450
问题1:断点无法触发
尝试设置断点后,断点始终未触发,串口显示U-Boot正常启动到shell:
(gdb) mon load_image /home/naveen/.repos/src/arm64/u-boot/u-boot.bin 0x80000 597272 bytes written at address 0x00080000 downloaded 597272 bytes in 2.389555s (244.093 KiB/s) (gdb) b *0x80000 Breakpoint 1 at 0x80000: file arch/arm/cpu/armv8/start.S, line 31. (gdb) mon resume 0x80000 (gdb)
原因与修复方案
- 地址不匹配:检查U-Boot链接脚本
u-boot.lds确认实际入口地址,若SD卡启动的U-Boot加载地址不是0x80000,断点不会触发。 - 硬件断点优先级:ARMv8核心中,代码在RAM运行时可尝试用硬件断点替代软件断点,执行
(gdb) hbreak *0x80000设置硬件断点。 - 核心选择问题:树莓派3B+为四核,当前连接的是cpu0(3333端口),尝试连接其他核心端口(3334/3335/3336)后再设置断点。
- OpenOCD配置优化:检查
rpi3.cfg,确保启用了对应核心的调试支持,可添加配置强制聚焦调试cpu0。
问题2:断电重启后JTAG连接中断,无法预设置断点
断电重启树莓派后,JTAG连接中断并出现以下错误,且U-Boot正常启动未触发断点:
Examination failed, GDB will be halted. Polling again in 3100ms Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Polling target bcm2837.cpu1 failed, trying to reexamine Error: Invalid ACK (7) in DAP response Error: JTAG-DP STICKY ERROR Error: Could not initialize the APB-AP Examination failed, GDB will be halted. Polling again in 3100ms Error: Invalid ACK (7) in DAP response Error: Debug regions are unpowered, an unexpected reset might have happened Error: JTAG-DP STICKY ERROR Polling target bcm2837.cpu2 failed, trying to reexamine Info : bcm2837.cpu2: hardware has 6 breakpoints, 4 watchpoints Polling target bcm2837.cpu3 failed, trying to reexamine Info : bcm2837.cpu3: hardware has 6 breakpoints, 4 watchpoints Polling target bcm2837.cpu0 failed, trying to reexamine Info : bcm2837.cpu0: hardware has 6 breakpoints, 4 watchpoints Polling target bcm2837.cpu1 failed, trying to reexamine Info : bcm2837.cpu1: hardware has 6 breakpoints, 4 watchpoints
尝试用mon reset报错:
(gdb) mon reset JTAG tap: bcm2837.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4) bcm2837.cpu0: how to reset?
原因与修复方案
- JTAG连接恢复:断电重启后BCM2837调试模块复位,可在OpenOCD的telnet控制台执行
init命令重新初始化调试目标,或在配置文件中添加自动重连逻辑。 - 预设置断点流程优化:
- 让树莓派从SD卡启动U-Boot,在OpenOCD中执行
halt暂停所有核心; - 连接GDB后加载U-Boot符号,设置断点后继续执行:
(gdb) target remote :3333 (gdb) symbol-file u-boot (gdb) b *0x80000 # 确认入口地址正确 (gdb) c
- 让树莓派从SD卡启动U-Boot,在OpenOCD中执行
- 复位配置修复:修改
rpi3.cfg添加复位配置:
之后尝试reset_config trst_only separate $_TARGETNAME configure -event reset-post { halt }mon reset init命令完成复位与调试模块初始化,再设置断点。
内容的提问来源于stack exchange,提问作者InsaneCoder
相关产品推荐
相关产品推荐

