This is an old revision of the document!
JTAG Reverse Engineering
Introduction
JTAG is a rather ubiquitous technology for debugging and testing circuit boards, integrated circuits, and embeded software. JTAG stands for Joint Test Action Group and the standard was initially developed to enable testing of assembled circuit boards. With the invention of surface mount components and the continual increase in complexity and desnity of circuit boards, the JTAG interface allowed for non-intrusive testing of all of a board's connections at a cost of 4 pins per chip and a single JTAG header on the board.
This application of JTAG is called 'boundary scan' and it allows the JTAG TAP (test access port) on the chip to take control of all of its IO pins. When multiple chips with JTAG TAPs are installed on a board, their JTAG interfaces can be daisy-chained into a JTAG scan chain. This enables a single test connector on the board to access all of the JTAG controllable I/O pins at he same time, allowing boundary scan software to check all of the connections in the board's netlist for any faults.
Later on, JTAG was extended to also access the interior of the chip as well. JTAG can be used on many chips for loading firmware and configuration information as well as debugging embedded software. This makes JTAG a very powerful tool for not only manufacture but also development of complex circuitry. With JTAG, a board can be tested and programmed in a sigle step during manufacture. The same JTAG port can also be used for development and debugging of device firmware.
The capabilities of the JTAG TAP also make it a very good tool for reverse-engineering PCBs. The ability to control the I/O pins of chips on a JTAG scan chain can be used not only to check a netlist, but also to reconstruct one. The JTAG TAP can also be used to download firmware and configuration information for disassembly and further reverse-engineering.
Netlist Extraction
Once a JTAG access port is located on a board, extracting a netlist is relatively straightforward. Well, with the right tools, anyway. The utility of having the netlist depends on the purpose of the board. For some boards, the netlist is of little use. However, some very good deals on boards with very large FPGAs on them pop up from time to time on eBay and other surplus and auction sites. These boards can be used as very powerful FPGA development boards, but without information about the interconnections between the FPGAs, they are quite difficult to use. When each FPGA is a BGA package with over 1000 pins and the board has 4 or more layers, the process becomes prohibitively tedious to perform manually. The folks over at NSA@home used repurposed HD video transform boards loaded with FPGAs to build an MD5 hash cracking machine, and they developed a JTAG reverse-engineering tool called jrev to expedite the prcess of extracting the netlist.
The process of netlist extraction is very simple. Turn all the I/O pins to inputs, turn one on, look at all the pins, turn it off, look at all the pins again, and see what changed. Repeat this for every JTAG accessible pin on the board. The jrev tool does this for a parallel port JTAG cable, and the ftjrev tool does this for FTDI based USB jtag cables. However, these tools can only find connections between JTAG enabled pins.
As the JTAG boundary scan functionality allows for access to the IO pins of the chips, it is possible to probe pins with external signal sources and sinks as well as other JTAG enabled pins. I created a github repository for ftjrev to store the modified code as well as the required device definition files.
ftjrev
ftjrev is a powerful JTAG reverse-engineering tool. When coupled with an FTDI based JTAG cable and connected to a target board, ftjrev can be used to extract a netlist of interconnections between JTAG enabled components. Successful use of ftjrev also requires some general reverse-engineering; it cannot always be used in isolation to determine netlists without some extra work.
ftjrev performs four main functions: scanning for clocks, scanning for JTAG accessible connections, probing inputs, and probing outputs.
Clock scanning
Scanning for clocks looks for pins that change without any stimulus. Generally this is just clock pins, but sometimes other pins will be picked up by clock scans as well. Clock pins can appear as connected in scans if they are not identified separately.
Example:
$ ./ftjrev clocks Found 3 devices with total IR length of 26 Device 0: IDCODE 2295C093 (XC5VLX330-FFG1760) Device 1: IDCODE 21C2E093 (XC3S1200E-FT256) Device 2: IDCODE 2295C093 (XC5VLX330-FFG1760) Total boundary scan chain: 8572 Clock pass... CLOCK: 0[XC5VLX330-FFG1760]:IO_AN14 CLOCK: 0[XC5VLX330-FFG1760]:IO_J13 CLOCK: 0[XC5VLX330-FFG1760]:IO_K13 CLOCK: 1[XC3S1200E-FT256]:IPAD78 CLOCK: 1[XC3S1200E-FT256]:K2 CLOCK: 1[XC3S1200E-FT256]:IPAD258 CLOCK: 1[XC3S1200E-FT256]:L8 CLOCK: 2[XC5VLX330-FFG1760]:IO_AM13 CLOCK: 2[XC5VLX330-FFG1760]:IO_J30 CLOCK: 2[XC5VLX330-FFG1760]:IO_P37
Scanning
Scanning for JTAG accessible connections looks for connections between JTAG pins. It works by setting all of the IO pins as inputs, and then walking a toggling output around and reading in all the input pins. Pins that are pulled along with the test output are noted and reported. This method finds most of the connections between JTAG enabled components, but it cannot identify nets with only a single JTAG pin nor can it locate what else might be connected to a given trace besides the JTAG pins.
Example:
$ ./ftjrev scan Found 3 devices with total IR length of 26 Device 0: IDCODE 2295C093 (XC5VLX330-FFG1760) Device 1: IDCODE 21C2E093 (XC3S1200E-FT256) Device 2: IDCODE 2295C093 (XC5VLX330-FFG1760) Total boundary scan chain: 8572 Clock pass... CLOCK: 0[XC5VLX330-FFG1760]:IO_AN14 CLOCK: 0[XC5VLX330-FFG1760]:IO_J13 CLOCK: 0[XC5VLX330-FFG1760]:IO_K13 CLOCK: 1[XC3S1200E-FT256]:IPAD78 CLOCK: 1[XC3S1200E-FT256]:K2 CLOCK: 1[XC3S1200E-FT256]:IPAD258 CLOCK: 1[XC3S1200E-FT256]:L8 CLOCK: 2[XC5VLX330-FFG1760]:IO_AM13 CLOCK: 2[XC5VLX330-FFG1760]:IO_J30 CLOCK: 2[XC5VLX330-FFG1760]:IO_P37 Pin pass... 0[XC5VLX330-FFG1760]:IO_BB13 --> 2[XC5VLX330-FFG1760]:IO_AT16 0[XC5VLX330-FFG1760]:IO_AY12 --> 2[XC5VLX330-FFG1760]:IO_AW17 0[XC5VLX330-FFG1760]:IO_AY13 --> 2[XC5VLX330-FFG1760]:IO_AT20 0[XC5VLX330-FFG1760]:IO_BA11 --> 2[XC5VLX330-FFG1760]:IO_AT19 0[XC5VLX330-FFG1760]:IO_BB11 --> 2[XC5VLX330-FFG1760]:IO_AT17 0[XC5VLX330-FFG1760]:IO_BB12 --> 2[XC5VLX330-FFG1760]:IO_AU16 0[XC5VLX330-FFG1760]:IO_AW12 --> 2[XC5VLX330-FFG1760]:IO_AW18 0[XC5VLX330-FFG1760]:IO_AW11 --> 2[XC5VLX330-FFG1760]:IO_AV35 ....
Input probing
Input probing does the same thing as scanning, but instead of walking an output pin around on the board, it toggles a GPIO pin on the FTDI chip in the JTAG cable. A wire connected to this pin can be used to probe for JTAG connections on the board. With this mode, conectors and non-JTAG chips can be probed. However, input probing only works for connections that are not already being driven by other circuitry, nor does it work for output-only pins.
Example:
$ ./ftjrev iprobe Found 3 devices with total IR length of 26 Device 0: IDCODE 2295C093 (XC5VLX330-FFG1760) Device 1: IDCODE 21C2E093 (XC3S1200E-FT256) Device 2: IDCODE 2295C093 (XC5VLX330-FFG1760) Total boundary scan chain: 8572 Clock pass... CLOCK: 0[XC5VLX330-FFG1760]:IO_AN14 CLOCK: 0[XC5VLX330-FFG1760]:IO_J13 CLOCK: 0[XC5VLX330-FFG1760]:IO_K13 CLOCK: 1[XC3S1200E-FT256]:IPAD78 CLOCK: 1[XC3S1200E-FT256]:K2 CLOCK: 1[XC3S1200E-FT256]:IPAD258 CLOCK: 1[XC3S1200E-FT256]:L8 CLOCK: 2[XC5VLX330-FFG1760]:IO_AM13 CLOCK: 2[XC5VLX330-FFG1760]:IO_J30 CLOCK: 2[XC5VLX330-FFG1760]:IO_P37 Probing inputs, press ctrl+c to stop... 0[XC5VLX330-FFG1760]:IO_K20 0[XC5VLX330-FFG1760]:IO_K20 0[XC5VLX330-FFG1760]:IO_K20 0[XC5VLX330-FFG1760]:IO_K20 0[XC5VLX330-FFG1760]:IO_K20 0[XC5VLX330-FFG1760]:IO_K20 ....
Output probing
Output probing walks a toggling output pin around the board while at the same time printing the name of the pin to STDOUT. This is not terribly useful in and of itself, but in addition to an oscilloscope with serial decode capability, output pins can be traced. The simplest way to set this up is to pipe the output of ftjref running an output probe to a serial port, and then connecting one of the oscilloscope probes to the serial port and enabling serial decode. Put the oscilloscope in normal trigger mode to trigger on any edge on a free probe, and then use this probe to browse the board. When the probe picks up a JTAG triggered edge, the serial decode displayed alongside will correspond to the connected pin. Sometimes multiple pins will trigger the same edge; it can take some work to determine the precise cause. Output probing can sometimes determine what pins driven from external sources are connected to, but this does not always work. If the non-JTAG device's driver is weak enough, the JTAG controlled driver may be able to produce enough of a change in the line to detect on an oscilloscope.
Example:
$ stty -F /dev/ttyUSB2 speed 115200 $ ./ftjrev oprobe > /dev/ttyUSB2 Found 3 devices with total IR length of 26 Device 0: IDCODE 2295C093 (XC5VLX330-FFG1760) Device 1: IDCODE 21C2E093 (XC3S1200E-FT256) Device 2: IDCODE 2295C093 (XC5VLX330-FFG1760) Total boundary scan chain: 8572 Clock pass... CLOCK: 0[XC5VLX330-FFG1760]:IO_AN14 CLOCK: 0[XC5VLX330-FFG1760]:IO_J13 CLOCK: 0[XC5VLX330-FFG1760]:IO_K13 CLOCK: 1[XC3S1200E-FT256]:IPAD78 CLOCK: 1[XC3S1200E-FT256]:K2 CLOCK: 1[XC3S1200E-FT256]:IPAD258 CLOCK: 1[XC3S1200E-FT256]:L8 CLOCK: 2[XC5VLX330-FFG1760]:IO_AM13 CLOCK: 2[XC5VLX330-FFG1760]:IO_J30 CLOCK: 2[XC5VLX330-FFG1760]:IO_P37 Probing outputs, press ctrl+c to stop...