Debugging Raspberry Pi 3 B+
This article records my experiments on studying ARMv8-A with RPi3. Hardware environment:
Software environment:
- Windows 7
- OpenOCD
- GDB
After RPi3 boots, FT4232H can control RPi3 through JTAG signals. While JTAG signals are just a bunch of high and low voltage levels, we need a mechanism to translate high-level concepts, such as “read register”, “load image”, “single step”, etc., to JTAG signals. OpenOCD is an open source project for the translation. Furthermore, OpenOCD has built-in GDB server for GDB source level debugging.
Hardware Wiring
For detail, check FT4232H datasheet for pin definition and BCM2835 datasheet for GPIO pin table. (While RPi3 uses BCM2837B0, it claims to be 2835-compatible.)
Software Configuration
RPi3
RPi3’s GPIO pins are shared between multiple internal modules. Its pin-mux must be configured correctly to enable JTAG. Adding enable_jtag_gpio=1 to config.txt is the easiest way at the moment I writing this. Otherwise, you can also set it pin-by-pin manually, check this for the config.txt commands to set GPIO.
OpenOCD
OpenOCD doesn’t provide windows binary officially. While there are many unofficially build on web, I only figured a way to bring up the one provided by SysProgs. The version I tried is 20190426. (They have an article on setting debug flow on RPi3 too. A bit outdated and with different debugger though. Still worth reading.)
Installing OpenOCD is not enough to debug RPi3 with FT4232H. You still need the corresponding configuration files since both are not built-in. For the given version of OpenOCD, following is what I figured after a lot of googling.
Get Burst Accessing’s stories in your inbox
Join Medium for free to get updates from this writer.
For FT4232H, create ./interface/ftdi/ft4232h.cfg with following content:
# FTDI FT4232H Mini Moduleinterface ftdi
ftdi_device_desc "FT4232H MiniModule"
ftdi_vid_pid 0x0403 0x6011ftdi_channel 0ftdi_layout_init 0x18 0x1b
ftdi_layout_signal nTRST -data 0x10
# ftdi_layout_signal nRST -oe 0x40
For RPi3, create ./target/rpi3.cfg with following content:
# Credits to Petr Tesarik from SUSE who provided this updated configuration,
# source: https://www.suse.com/c/debugging-raspberry-pi-3-with-jtag/
transport select jtag# we need to enable srst even though we don't connect it
reset_config trst_and_srstadapter_khz 1000
jtag_ntrst_delay 500if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME rpi3
}#
# Main DAP
#
if { [info exists DAP_TAPID] } {
set _DAP_TAPID $DAP_TAPID
} else {
set _DAP_TAPID 0x4ba00477
}jtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -enable
dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tapset _TARGETNAME $_CHIPNAME.a53
set _CTINAME $_CHIPNAME.ctiset DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}
set CTIBASE {0x80018000 0x80019000 0x8001a000 0x8001b000}
set _cores 4for { set _core 0 } { $_core < $_cores } { incr _core } {cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 0 \
-ctibase [lindex $CTIBASE $_core]target create $_TARGETNAME.$_core aarch64 \
-dap $_CHIPNAME.dap -coreid $_core \
-dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core$_TARGETNAME.$_core configure -event reset-assert-post "aarch64 dbginit"
$_TARGETNAME.$_core configure -event gdb-attach { halt }
}
Windows
Before kicking off OpenOCD, you need to install “correct” FT4232H driver. The official FTDI FT4232H driver is not supported by OpenOCD. Use Zadig to switch FT4232H driver to WinUSB. Zadig is a windows utility to change USB driver.
Action
Open cmd.exe, and execute openocd.exe -f .\interface\ftdi\ft4232h.cfg -f .\target\rpi3.cfg. Seeing
Open On-Chip Debugger 0.10.0 (2019-04-26) [https://github.com/sysprogs/openocd]
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
trst_and_srst separate srst_gates_jtag trst_push_pull srst_open_drain connect_deassert_srst
adapter speed: 1000 kHz
jtag_ntrst_delay: 500
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : clock speed 1000 kHz
Info : JTAG tap: rpi3.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd.), part: 0xba00, ver: 0x4)
Info : rpi3.a53.0: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.1: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.2: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.3: hardware has 6 breakpoints, 4 watchpoints
Info : rpi3.a53.0 cluster 0 core 0 multi core
Info : rpi3.a53.3 cluster 0 core 3 multi core
Info : Listening on port 3333 for gdb connections
Info : Listening on port 3334 for gdb connections
Info : Listening on port 3335 for gdb connections
Info : Listening on port 3336 for gdb connectionsmeans that the whole signal path is enabled:
- FT4232H hardware ID is check okay. (Defined in ft4232.h of OpenOCD)
- RPi3’s BCM2837B0 ID is read through FT4232H. (0x4ba00477)
- Four ARMv8 A53 cores in RPi3’s BCM2837B0 are detected and under OpenOCD’s control.
Attach GDB for remote debug:
(gdb) target remote :3333
Remote debugging using :3333
warning: No executable has been specified and target does not support
determining executable automatically. Try using the "file" command.
0x0000000000000018 in ?? ()
(gdb) info registers x0
x0 0x140 320
(gdb) info registers pc
pc 0x18 0x18
(gdb)GDB works from now on.





