Zum Inhalt springen

JTAG Cheat Sheet

Overview

JTAG (Joint Test Action Group) is an industry standard (IEEE 1149.1) originally designed for testing printed circuit board connections via boundary scan, but now widely used for in-system programming, hardware debugging, and reverse engineering of embedded devices. The JTAG interface provides direct access to a chip’s internal registers, memory, and debug capabilities through a simple 4-5 wire serial interface. Nearly all modern microcontrollers, CPUs, FPGAs, and SoCs include JTAG ports, making it the primary interface for firmware development, production testing, and security research.

JTAG uses a Test Access Port (TAP) with four mandatory signals: TDI (Test Data In), TDO (Test Data Out), TMS (Test Mode Select), and TCK (Test Clock), plus an optional TRST (Test Reset). Multiple devices can be daisy-chained on a single JTAG bus. Through JTAG, you can halt the processor, read and write memory, set breakpoints, single-step code execution, dump firmware, program flash memory, and perform boundary scan testing of I/O pins. Tools like OpenOCD, SEGGER J-Link, and various low-cost adapters (FTDI-based, Bus Pirate) provide JTAG connectivity from a PC.

JTAG Signals

SignalDirectionDescription
TCKInputTest Clock - synchronizes operations
TMSInputTest Mode Select - controls TAP FSM
TDIInputTest Data In - serial data input
TDOOutputTest Data Out - serial data output
TRSTInputTest Reset (optional) - resets TAP
VCCPowerReference voltage
GNDGroundGround reference

Common JTAG Pinouts

ConnectorPinsStandards
ARM 20-pin20ARM standard JTAG
ARM 10-pin10Compact ARM JTAG
MIPS EJTAG14MIPS processors
Intel 60-pin60Intel XDP
AVR 6-pin6Atmel/Microchip ISP
TI 14-pin14Texas Instruments
Custom headersVarVaries by vendor

ARM 20-Pin Standard

Pin 1:  VCC        Pin 2:  TMS
Pin 3:  GND        Pin 4:  TCK
Pin 5:  GND        Pin 6:  TDO
Pin 7:  -          Pin 8:  TDI
Pin 9:  GND        Pin 10: nRESET
Pin 11: GND        Pin 12: -
Pin 13: GND        Pin 14: -
Pin 15: GND        Pin 16: -
Pin 17: GND        Pin 18: -
Pin 19: GND        Pin 20: -

JTAG Adapters

AdapterInterfaceSpeedPrice
SEGGER J-LinkUSBVery fast$$$$
SEGGER J-Link EDUUSBVery fast$$
ST-LINK V2USBFast$
FTDI FT2232HUSBMedium$
Bus PirateUSBSlow$
Raspberry Pi GPIOGPIOSlow$
Black Magic ProbeUSBFast$$
TigardUSBMedium$$

FTDI-Based Adapter Setup

# Install FTDI drivers
sudo apt install libftdi1-dev

# Check FTDI device
lsusb | grep -i ftdi

# Common FTDI JTAG pinout (FT2232H)
# ADBUS0 = TCK
# ADBUS1 = TDI
# ADBUS2 = TDO
# ADBUS3 = TMS

JTAG TAP State Machine

                    ┌─────────────────┐
                    │  Test-Logic-Reset │
                    └────────┬─────────┘
                             │ TMS=0
                    ┌────────▼─────────┐
            ┌──────►│   Run-Test/Idle   │◄──────┐
            │       └────────┬─────────┘        │
            │                │ TMS=1             │
            │       ┌────────▼─────────┐        │
            │       │  Select-DR-Scan   │        │
            │       └───┬──────────┬───┘        │
            │    TMS=0  │          │ TMS=1       │
            │  ┌────────▼──┐  ┌───▼─────────┐   │
            │  │ Capture-DR │  │Select-IR-Scan│   │
            │  └────┬───────┘  └───┬─────────┘   │
            │       │              │              │
            │  (DR chain)     (IR chain)          │
            │       │              │              │
            └───────┴──────────────┘              │
                    │ TMS=1 (Update-xR)           │
                    └─────────────────────────────┘

Finding JTAG Pins

Manual Identification

# Look for:
# - Unpopulated headers (4-20 pins in a row)
# - Labeled pads: TCK, TMS, TDI, TDO, TRST, SRST
# - Test points near CPU/SoC
# - Grouped vias near processor

# Use multimeter to identify:
# - GND: continuity to ground plane/shield
# - VCC: steady 3.3V or 1.8V
# - TCK: may have pull-down resistor
# - TMS: may have pull-up resistor
# - TDI: may have pull-up resistor

JTAGulator (Automated Discovery)

# JTAGulator finds JTAG pins automatically
# Connect all candidate pins to JTAGulator channels

# In JTAGulator terminal:
> u                    # Set target voltage
> Enter voltage: 3.3

> b                    # BYPASS scan (find JTAG)
> Enter start channel: 0
> Enter end channel: 7
# Tries all pin combinations

> i                    # IDCODE scan
> Enter start channel: 0
> Enter end channel: 7
# Reads JTAG device IDs

Using OpenOCD for Discovery

# Boundary scan with unknown device
openocd -f interface/ftdi/tigard.cfg \
  -c "transport select jtag" \
  -c "adapter speed 1000" \
  -c "jtag newtap auto0 tap -irlen 4 -expected-id 0" \
  -c "init" \
  -c "scan_chain" \
  -c "shutdown"

OpenOCD Usage

Basic Commands

# Start OpenOCD with specific target
openocd -f interface/jlink.cfg -f target/stm32f4x.cfg

# Start with FTDI adapter
openocd -f interface/ftdi/tigard.cfg -f target/stm32f1x.cfg

# Custom configuration
openocd -f my_target.cfg

# Connect GDB to OpenOCD
arm-none-eabi-gdb firmware.elf
(gdb) target remote localhost:3333
(gdb) monitor reset halt
(gdb) load
(gdb) continue

OpenOCD Telnet Commands

# Connect to OpenOCD telnet
telnet localhost 4444

# Halt processor
> halt

# Resume execution
> resume

# Reset target
> reset
> reset halt
> reset init

# Read memory
> mdw 0x08000000 16     # Read 16 words from flash
> mdb 0x20000000 64     # Read 64 bytes from RAM
> mdh 0x40000000 8      # Read 8 halfwords

# Write memory
> mww 0x20000000 0xDEADBEEF    # Write word
> mwb 0x20000000 0x42          # Write byte

# Dump memory to file
> dump_image firmware.bin 0x08000000 0x100000

# Load binary to memory
> load_image firmware.bin 0x08000000

# Flash programming
> flash write_image erase firmware.bin 0x08000000
> flash verify_image firmware.bin 0x08000000

# Flash info
> flash info 0
> flash banks

# Set breakpoints
> bp 0x08001234 4 hw     # Hardware breakpoint
> rbp 0x08001234          # Remove breakpoint

# Single step
> step

# Register access
> reg                     # Show all registers
> reg pc                  # Show program counter
> reg r0 0x12345678      # Set register value

# JTAG chain info
> scan_chain
> jtag names

OpenOCD Configuration Files

# my_target.cfg
source [find interface/ftdi/tigard.cfg]
transport select jtag

adapter speed 1000

source [find target/stm32f4x.cfg]

# Custom JTAG settings
jtag newtap mytarget cpu -irlen 4 -expected-id 0x2ba01477

# Reset configuration
reset_config srst_only srst_nogate

# Flash configuration
flash bank myflash stm32f2x 0x08000000 0 0 0 mytarget.cpu

Firmware Extraction

Dump Flash Memory

# Using OpenOCD
openocd -f interface/jlink.cfg -f target/stm32f4x.cfg \
  -c "init" \
  -c "reset halt" \
  -c "flash read_image firmware.bin 0x08000000 0x100000" \
  -c "shutdown"

# Using J-Link Commander
JLinkExe -device STM32F407VG -if JTAG -speed 4000
J-Link> connect
J-Link> halt
J-Link> savebin firmware.bin 0x08000000 0x100000
J-Link> exit

Analyze Dumped Firmware

# Basic analysis
file firmware.bin
strings firmware.bin | head -50
hexdump -C firmware.bin | head -100
binwalk firmware.bin

# Look for file systems
binwalk -e firmware.bin

# Entropy analysis (find encrypted/compressed sections)
binwalk -E firmware.bin

Advanced Usage

Boundary Scan

# Boundary scan tests I/O pin connectivity
# Using OpenOCD
openocd -f interface/jlink.cfg -f target/stm32f4x.cfg \
  -c "init" \
  -c "jtag_reset 0 0" \
  -c "irscan stm32f4x.cpu 0x00" \
  -c "drscan stm32f4x.cpu 32 0x00000000" \
  -c "shutdown"

# Using BSDL files for pin mapping
# BSDL (Boundary Scan Description Language) files
# describe pin functions for boundary scan

JTAG Daisy Chain

# Multiple devices on JTAG chain
# my_chain.cfg
jtag newtap fpga tap -irlen 6 -expected-id 0x0123abcd
jtag newtap mcu tap -irlen 4 -expected-id 0x2ba01477

# The first device in chain (closest to TDO) is listed first

SWD Alternative (ARM)

# SWD uses only 2 wires (SWDIO + SWCLK) instead of 4
# Most ARM Cortex-M devices support SWD

openocd -f interface/jlink.cfg \
  -c "transport select swd" \
  -f target/stm32f4x.cfg

# SWD pinout:
# SWDIO = TMS (bidirectional data)
# SWCLK = TCK (clock)

Troubleshooting

IssueSolution
No JTAG device foundVerify wiring, check voltage levels
IDCODE all zeros/onesWrong pin assignment, check TCK/TMS
Can’t halt processorTry TRST/SRST reset, check JTAG lock fuses
Flash read protectionDevice may have RDP enabled (read protection)
Slow JTAG speedReduce adapter speed, shorten wires
OpenOCD connection failsCheck adapter driver, verify config files
GDB can’t connectVerify OpenOCD is running, check port 3333
Daisy chain detection failsVerify IR lengths, check device order

Common Error Messages

# "JTAG scan chain interrogation failed"
# -> Wrong wiring or no target power

# "Timeout waiting for SYSCOMP"
# -> Target is in low-power mode, add reset

# "Could not find MEM-AP to control the core"
# -> Device may use SWD instead of JTAG

# "Error: flash write failed"
# -> Flash may be locked, check protection bits

JTAG Security Countermeasures

# Some devices disable JTAG:
# - Fuse bits (OTP) that permanently disable JTAG
# - Software JTAG lock (sometimes reversible)
# - Debug authentication required (ARM CoreSight)
# - JTAG pins repurposed as GPIO

# Bypass techniques (for security research):
# - Voltage glitching during boot
# - UV exposure to clear OTP fuses (older devices)
# - Microprobing internal test pads
# - Exploiting boot ROM vulnerabilities