Welcome to MOV r0, and my first blog post. The goal of this article is to teach you how to JTAG the Raspberry Pi 2 without having to compile a custom kernel to enable the GPIOs to do JTAG. Let’s begin!
The tools and equipment I’ll be using today are as follows:
- TIAO USB Multi-protocol JTAG adapter. This device is like a BusPirate on steroids. It’ll do everything. It’s got an FT2232H chip inside, and supports dual-MPSSE. That means we can use UART/JTAG simultaneously, or SPI1/SPI2, or SWD. It’s really an amazing device at a great price. You can find it here (Link)
- Raspberry Pi 2 running Raspbian (Jessie)
- Female-to-female jumper wires (Can’t ever have enough of these)
- Host system is using Ubuntu Mate 15.04, with latest OpenOCD and FTDI support
- Grab the latest build of OpenOCD (On your host machine, not your Raspberry Pi, these directions are specific to an FTDI JTAG adapter)
git clone git://git.code.sf.net/p/openocd/code
sudo apt-get install libtool autoconf texinfo libusb-dev libftdi-dev libusb-1.0.0 libusb-1.0.0-dev pkg-config
cd code ./bootstrap ./configure --enable-maintainer-mode --enable-ftdi make sudo make install
- Next we’re going to compile a small binary written by the guys over at SysProgs (Link). This will be done on the Raspberry Pi 2 itself.
I’ve modified the original source to change the peripheral base address to support the Raspberry Pi 2. (Working on some server stuff.) The peripheral base went from 0x20000000 to 0x3F000000.
NOTE: Before we compile this, we must edit the peripheral base and change it to 0x3F000000. I use nano since it’s my favorite editor.wget http://sysprogs.com/VisualKernel/tutorials/raspberry/jtagsetup/JtagEnabler.cpp nano JtagEnabler.cpp (Replace 0x20000000 with 0x3F000000) g++ -o JtagEnabler JtagEnabler.cpp
Remember the location of this binary on your RPi2, we’ll need it later. This binary simply changes the GPIOs to ALT functions (i.e, routes these specific GPIO pins to an alternative function, which in this case is routed to the ARM JTAG pins.)
- At this point, we’ll need to create a configuration file for OpenOCD to interface with the RPi2. We’ll use the configuration file found from Jitomesky’s GitHub (Link).
wget http://movr0.com/files/rpi2.cfg
- Finally, we’re ready to connect to the Pi’s JTAG pins.
JTAG RPi2 GPIO VREF* Pin 1 nTRST Pin 15 GND Pin 9 TDI Pin 7 TMS Pin 13 TCK Pin 22 TDO Pin 18 *Note: Pin 1 is optional, but useful for verifying voltage level.
- With our Pi wired up and ready to go, we’ll start by activating the JTAG pins using the binary we compiled earlier:
sudo ./JtagEnabler
Next we’ll fire up OpenOCD and attempt to connect! (You may need to use a different configuration file for your interface depending on which device you are using. FTDI devices are cheap and work very well) Since I have the TUMPA, I am using the TUMPA configuration file in the FTDI devices folder.
sudo openocd -f interface/ftdi/tumpa.cfg -f rpi2.cfg
If all goes well, we should see the four cores halt, and we’re ready to debug. If you have any questions or comments, please post in the comment section below! Thanks for reading.
(Note: I’m hoping to put together a SWD tutorial soon, so c’mon back in the near future.)
If I were to send you two Raspberry Pi 2 – Model B boards how much would you charge to enable JTAG for me?
Richard,
JTAG is enabled on all the Raspberry Pi boards. The pins are on the GPIOs but need to be set to alternative function. By following the steps in this guide, you will be able to utilize JTAG. Are you having difficulty with any of my instructions that I can assist you with?
Ryan
Hi,
I’m trying something pretty similar but in bare metal context, no OS. At boot I enable the necessary GPIO for JTAG (24, 25, 26, 27) but my debug module (RPi HUB module from FTDI) is unable to get any feedback from the PI2. The TDO line keeps always high.
I wonder if really JTAG is enabled on all PI boards :/
Doesn’t it depend on the proc mode (my PI2 boots in HYP mode) ? Or any hidden feature in the bootcode.bin program would prevent the JTAG cell to reply ?
Thanks for any ideas.
How are you enabling the GPIOs for JTAG? Do you have the proper interface configuration file for the RPi HUB and OpenOCD? JTAG is enabled on all models, all that needs to happen is for the GPIOs to be set to their proper ALT functions. Are you using OpenOCD?
I want to use an Atmel Dragon programmer to download code and use the Pi as a bare- metal embedded controller.
I want to bypass any operating system and boot directly to the application.
Can this be done?
In theory yes, you’ll probably need to do a soft_reset_halt in OpenOCD and clear all the registers and wipe the memory, then load your application. I’m not too familiar with the Atmel Dragon Programmer but if it uses standard JTAG protocol, it shouldn’t be an issue. There’s an example blink.elf somewhere on GitHub that serves as a bare-metal/GPIO example.
I appreciate the friendly words, I’m hoping to have some more good content coming soon!
Can we crack the video codecs with this ? I’m running a hash farm for several weeks and I have no match results yet. I thing it’ll be more straightforward, or maybe we can glitch the runtimes into borking the comm.
I wonder if it is possible to configure JTAG on raspberry pi3 with raspbian on board and use it to program other devices directly from the same PI (without any additional PC with Linux or Windows).
That’s absolutely possible! I could do a how-to on that if you’re interested.
Yes I’m interested with that how-to 🙂
Thanks for this great guide!
If you get errors in the bootstrap make sure you have pkg-config installed:
sudo apt-get install pkg-config
(author: you may want to just add this to the packages you call out to be installed)
I’ve updated the article to reflect the additional dependency
I am trying to enable JTAG. Followed the exact step but still, I am getting this error. Please help me unlock the JTAG
I am on ubuntu 17 with ft232h adapter.
Open On-Chip Debugger 0.9.0 (2015-09-02-10:42)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
adapter speed: 1000 kHz
adapter speed: 1000 kHz
adapter_nsrst_delay: 400
none separate
Info : auto-selecting first available session transport “jtag”. To override use ‘transport select ‘.
Info : clock speed 1000 kHz
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway…
Error: rpi2.dap: IR capture error; saw 0x0f not 0x01
Warn : Bypassing JTAG setup events due to errors
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
Warn : Invalid ACK 0x7 in JTAG-DP transaction
It looks like the GPIO have not been set to the proper alternative function. Please be sure that during the section where you compile ‘JtagEnabler’ you go into the source code and modify the line ‘#define BCM2708_PERI_BASE 0x20000000’ to ‘#define BCM2708_PERI_BASE 0x3F000000’ (without the quotes) then compile following the rest of the directions. 0x3F000000 is for Raspberry Pi 2 and 3, where 0x20000000 is for the original Raspberry Pi. Be sure to run the JtagEnabler binary before attempting to connect to JTAG. Double check your pins are connected correctly.