我正在尝试使用调试探针、OpenOCD 和 GDB 来调试 Raspberry Pi 5。我在所有四个核心上运行代码,因此我尝试设置 SMP 为每个核心获取一个 GDB 线程。
之前,我尝试在没有SMP的情况下调试每个核心(在GDB中为每个核心添加了一个下级并连接到四个不同的端口)。此设置有效,但产生了一些问题。其中之一是跳转到断点会在代码中创建一个暂停指令,OpenOCD 不会更改回原始指令。这些停止指令使调试变得棘手。为了通过它们,我必须手动设置程序计数器并将暂停指令更改回原始指令(如果它要再次运行)。我想要一个调试设置,这样我就不需要担心这个问题。
我认为我的 Raspberry Pi 5 的 OpenOCD 配置文件中缺少或有问题。我发现 这个类似的问题,此人的行为与我相同,但我已经将
-rtos hwthread
标志添加到目标。
这是我的配置文件:
# rpi5 chip name
set _CHIP_NAME bcm2712
# the rpi5 has four cortex-a76 cores
set _CORES 4
# Use SMP since we are running code on multiple cores
set _USE_SMP 1
#
set _DAP_TAPID 0x4ba00477
# Specify that the debug probe is using the SWD protocol
transport select swd
# Related to creating a new debug access port
swd newdap $_CHIP_NAME cpu -expected-id $_DAP_TAPID -irlen 4
# Sets clock speed in KHz
adapter speed 4000
# Create a debug access port
dap create $_CHIP_NAME.dap -chain-position $_CHIP_NAME.cpu
# TODO: don't know why this is needed or if it's messing up the SMP config
# MEM-AP for direct access
# target create $_CHIP_NAME.ap mem_ap -dap $_CHIP_NAME.dap -ap-num 0
# these addresses are obtained from the ROM table via 'dap info 0' command
# Each address if for is for a specific core
#
# Debug controller base address for each core
set _DBG_BASE {0x80010000 0x80110000 0x80210000 0x80310000}
#
set _CTI_BASE {0x80020000 0x80120000 0x80220000 0x80320000}
# Used for building the 'target smp' command for each core
set _SMP_COMMAND "target smp"
# Perform configuration for each of the four cores
for { set _CORE 0 } { $_CORE < $_CORES } { incr _CORE } {
# Set the CTI name for each core
set _CTI_NAME $_CHIP_NAME.cti$_CORE
# Set the target name for each core
set _TARGET_NAME $_CHIP_NAME.cpu$_CORE
# Add each target name to the SMP command
set _SMP_COMMAND "$_SMP_COMMAND $_TARGET_NAME"
# Create an ARM Cross-Trigger Interface for each core
# CTI is control core states and access registers
cti create $_CTI_NAME -dap $_CHIP_NAME.dap -ap-num 0 -baseaddr [lindex $_CTI_BASE $_CORE]
# Create debug target for GDB that refers to a JTAG TAP
# aarch64: this is an ARMv8-A core with an MMU
# -dap: debug access port to use for this target
target create $_TARGET_NAME aarch64 -dap $_CHIP_NAME.dap
#
# Configure the debug target
#
# Set the CTI for this core
$_TARGET_NAME configure -cti $_CTI_NAME
# Set the address of the debug controller for this core
$_TARGET_NAME configure -dbgbase [lindex $_DBG_BASE $_CORE]
# Set the access port for the target
$_TARGET_NAME configure -ap-num 0
# This is needed for GDB to correctly inspect the SMP system (section 20.7)
$_TARGET_NAME configure -rtos hwthread
}
# Run the SMP command to add each target to the SMP config
eval $_SMP_COMMAND
# Print to verify command
echo "Running SMP Command: $_SMP_COMMAND"
# Set the current target to the primary core before GDB starts
targets $_CHIP_NAME.cpu0
这是我启动 OpenOCD 并连接 GDB 时得到的输出:
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : Hardware thread awareness created
Info : Hardware thread awareness created
Info : Hardware thread awareness created
Info : Hardware thread awareness created
Running SMP Command: target smp bcm2712.cpu0 bcm2712.cpu1 bcm2712.cpu2 bcm2712.cpu3
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E6633861A32A5938
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: Test domain timer supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 4000 kHz
Info : SWD DPIDR 0x2ba01477
Info : bcm2712.cpu0: hardware has 6 breakpoints, 4 watchpoints
Info : bcm2712.cpu1: hardware has 6 breakpoints, 4 watchpoints
Info : bcm2712.cpu2: hardware has 6 breakpoints, 4 watchpoints
GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Reading symbols from ./fsix_files/fsix.arm64-rpi5.elf...
Info : bcm2712.cpu3: hardware has 6 breakpoints, 4 watchpoints
warning: Missing auto-load script at offset 0 in section .debug_gdb_scripts
of file /home/ubuntu/Documents/rpi5_debug/fsix_files/fsix.arm64-rpi5.elf.
Use `info auto-load python-scripts [REGEXP]' to list them.
Info : starting gdb server for bcm2712.cpu0 on 3333
Info : Listening on port 3333 for gdb connections
Breakpoint 1 at 0x80000
Breakpoint 2 at 0x8087c
Remote debugging using :3333
Info : accepting 'gdb' connection on tcp/3333
Info : bcm2712.cpu0 cluster 0 core 0 multi core
Info : bcm2712.cpu1 cluster 1 core 0 multi core
bcm2712.cpu1 halted in AArch64 state due to debug-request, current mode: EL3H
cpsr: 0x200002cd pc: 0x1c14
MMU: disabled, D-Cache: disabled, I-Cache: enabled
Info : bcm2712.cpu2 cluster 2 core 0 multi core
bcm2712.cpu2 halted in AArch64 state due to debug-request, current mode: EL3H
cpsr: 0x200002cd pc: 0x1c14
MMU: disabled, D-Cache: disabled, I-Cache: enabled
Info : bcm2712.cpu3 cluster 3 core 0 multi core
bcm2712.cpu3 halted in AArch64 state due to debug-request, current mode: EL3H
cpsr: 0x200002cd pc: 0x1c14
MMU: disabled, D-Cache: disabled, I-Cache: enabled
bcm2712.cpu0 halted in AArch64 state due to debug-request, current mode: EL2H
cpsr: 0x000003c9 pc: 0x80000
MMU: disabled, D-Cache: disabled, I-Cache: disabled
Info : New GDB Connection: 1, Target bcm2712.cpu0, state: halted
现在我在 GDB 中运行
info threads
时只得到一个线程:
(gdb) info threads
Id Target Id Frame
* 1 Thread 1 "bcm2712.cpu3" (Name: bcm2712.cpu3, state: debug-request) 0x0000000000080000 in _start ()
我想在运行时为每个核心获取一个线程
info threads
,如下所示:
(gdb) info threads
Id Target Id Frame
* 1 Thread 1.1 (CPU#0 [running]) 0x0000000000080000 in _start ()
2 Thread 1.2 (CPU#1 [running]) 0x000000000000030c in ?? ()
3 Thread 1.3 (CPU#2 [running]) 0x000000000000030c in ?? ()
4 Thread 1.4 (CPU#3 [running]) 0x000000000000030c in ?? ()
运行
monitor targets
表明 OpenOCD 已识别四个核心。
(gdb) monitor targets
TargetName Type Endian TapName State
-- ------------------ ---------- ------ ------------------ ------------
0* bcm2712.cpu0 aarch64 little bcm2712.cpu halted
1 bcm2712.cpu1 aarch64 little bcm2712.cpu halted
2 bcm2712.cpu2 aarch64 little bcm2712.cpu halted
3 bcm2712.cpu3 aarch64 little bcm2712.cpu halted
我感谢任何帮助!我是 OpenOCD 新手。我已经阅读了大量的 OpenOCD 用户指南,但我有点困惑。
我需要在创建目标时指定一个coreid。我添加了这一行以将其添加到每个目标。
$_TARGET_NAME configure -coreid $_CORE
第 11.3 节目标配置状态中的 coreid 描述之一:
这个值coreid目前也作为通用CPU在其他上下文中使用 索引,例如在 SMP 节点中或选择芯片中的特定 CPU。
在我能够将所有核心视为线程后,我遇到了一个问题,即无法在辅助核心中执行指令。我认为这与每个核心的目标状态有关。
为了解决这个问题,我运行
monitor targets <core number>
来选择一个核心。然后我运行 monitor step
将核心置于单步状态。然后我就可以在 GDB 中单步执行了。