Turn Your Raspberry Pi into a JTAG Adapter

3 minute read

I have several Raspberry Pis in hand, they are all not being used for a very long time because of the poor performance of the MMC controller, but it doesn’t hurt much to make it act as a JTAG adapter, actually, ryan already done this, I just made some adaptions to make it working for new version of openocd.

OpenOCD already have driver for this, you can find here if interested, in this post I will be using 3A to show how to make a JTAG adapter.

Install Raspberry Pi OS and OpenOCD

Download Raspberry Pi OS Lite from official website, then follow the instruction below to install OpenOCD:

$ sudo apt update
$ sudo apt install -y git autoconf libtool libusb-1.0-0-dev

$ git clone https://git.code.sf.net/p/openocd/code openocd
$ ./bootstrap
$ ./configure --enable-sysfsgpio --enable-bcm2835gpio
$ make && sudo make install

This will configure OpenOCD with bcm2835gpio driver enabled.

Wiring GPIO with Target Board

Before connect 3A to target board (ok6410), let’s take a look at the interface configuration file first, the file named raspberrypi2-native.cfg is located in directory /usr/local/share/openocd/scripts/interface/, the pins used for JTAG interfaces are list in that file, which are:

FUNC GPIO PIN #
TRST GPIO7 26
TDI GPIO10 19
TMS GPIO25 22
TCK GPIO11 23
TDO GPIO9 21
SRST GPIO18 12
GND GND 20

Pin map for the raspberry pi board as follow: Raspberry Pi Pinout

There is also a handy tool called gpiozero to do the same job, to use it, install with:

pi@raspberrypi:~ $ sudo apt install -y python3-pip
pi@raspberrypi:~ $ pip3 install --user gpiozero

The pinout for 3A board looks like this:
gpiozero output for Raspberry Pi

OK6410 use a standard 20-pin jtag connector, the definition can be found in the schematic file, I put it here for a quick reference: JTAG schematic on ok6410 JTAG interface on ok6410

This is how our JTAG adapter looks when connected to target board: Final setup

The pin not connected is VCC.

Debugging with Pi-JTAG

Just include the interface script and make a few adaptions to it, I am using the this as my openocd.cfg to debug do debug with ok6410:

source [find interface/raspberrypi2-native.cfg]
transport select jtag
adapter speed 1000
bcm2835gpio_trst_num 7
bcm2835gpio_srst_num 18
reset_config trst_and_srst srst_push_pull

bindto 0.0.0.0

source [find target/samsung_s3c6410.cfg]
nand device $_CHIPNAME.flash s3c6400 $_CHIPNAME.cpu

Now is the show time, connect to raspberry pi via ssh, and start openocd and do some test.

pi@raspberrypi:~ $ openocd
Open On-Chip Debugger 0.11.0-rc1+dev-00001-g0dd3b7f-dirty (2020-12-14-05:07)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : clock speed 601 kHz
Info : JTAG tap: s3c6410.etb tap/device found: 0x2b900f0f (mfg: 0x787 (<unknown>), part: 0xb900, ver: 0x2)
Info : JTAG tap: s3c6410.cpu tap/device found: 0x07b76f0f (mfg: 0x787 (<unknown>), part: 0x7b76, ver: 0x0)
Info : found ARM1176
Info : s3c6410.cpu: hardware has 6 breakpoints, 2 watchpoints
Warn : ETMv2+ support is incomplete
Info : ETM v3.2
Info : starting gdb server for s3c6410.cpu on 3333
Info : Listening on port 3333 for gdb connections
> reset
JTAG tap: s3c6410.etb tap/device found: 0x2b900f0f (mfg: 0x787 (<unknown>), part: 0xb900, ver: 0x2)
JTAG tap: s3c6410.cpu tap/device found: 0x07b76f0f (mfg: 0x787 (<unknown>), part: 0x7b76, ver: 0x0)
found ARM1176
> halt
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x200000d3 pc: 0xc01e2434
> poll
target halted in ARM state due to debug-request, current mode: Supervisor
cpsr: 0x200000d3 pc: 0xc01e2434
background polling: on
TAP: s3c6410.cpu (enabled)

> nand probe 0
NAND flash device 'K9GAG08 2GB NAND 3.3V x8 MLC 2b/cell (Samsung)' found

> nand list
#0: K9GAG08 2GB NAND 3.3V x8 MLC 2b/cell (Samsung) pagesize: 8192, buswidth: 8,
	blocksize: 1048576, blocks: 2048

After reset, the chip was recognized, about the unknown info, it should be safe to ignore it, because same info show up with a real jtag.

Don’t set adapter speed too high, otherwise, unknown errors may happen:

Info : JTAG tap: s3c6410.etb tap/device found: 0x2b800f0f (mfg: 0x787 (<unknown>), part: 0xb800, ver: 0x2)
Warn : JTAG tap: s3c6410.etb       UNEXPECTED: 0x2b800f0f (mfg: 0x787 (<unknown>), part: 0xb800, ver: 0x2)
Error: JTAG tap: s3c6410.etb  expected 1 of 1: 0x2b900f0f (mfg: 0x787 (<unknown>), part: 0xb900, ver: 0x2)
Info : JTAG tap: s3c6410.cpu tap/device found: 0x07376e0f (mfg: 0x707 (<unknown>), part: 0x7376, ver: 0x0)
Warn : JTAG tap: s3c6410.cpu       UNEXPECTED: 0x07376e0f (mfg: 0x707 (<unknown>), part: 0x7376, ver: 0x0)
Error: JTAG tap: s3c6410.cpu  expected 1 of 1: 0x07b76f0f (mfg: 0x787 (<unknown>), part: 0x7b76, ver: 0x0)
Error: Trying to use configured scan chain anyway...
Error: s3c6410.etb: IR capture error; saw 0x03 not 0x01
Warn : Bypassing JTAG setup events due to errors
Error: unexpected ARM11 ID code
Warn : target s3c6410.cpu examination failed
Info : starting gdb server for s3c6410.cpu on 3333
Info : Listening on port 3333 for gdb connections