deadhacker.com

security research repository of nathan andrew fain / cyphunk

JTAG Enumeration

Update: added section with references to all the OSS jtag tools I know of. Can be of assistance when debugging or adding features.
Update: added user submitted voltage conversion board design for bidirectional i/o

JTAGenum is an open source Arduino (and RaspberryPi) based hardware platform I built last year with three primary goals: [1. Given a large set of pins on a device determine which are JTAG lines 2. Enumerate the Instruction Register to find undocumented functionality 3. be easy to build and apply] (For a detailed discussion and tutorial video see here.) The development of a device has various distinct stages handled by different people/companies that each assume the other has properly secured their part. The security of devices often rely on obfuscation which makes it dificult for any part of the chain to evaluate the security of the whole. This is a problem that JTAGenum helps address. This was built for personal research and while working on various projects at Recurity Labs. Please feel free to contact me with any questions, problems, targets or updates. I would be more than happy to share credit.

Related work: There are two other tools for finding JTAG pins: JTAGScan presented by Benedikt Heinz (hunz) at ph-neutral which inspired Arduinull by Sébastien Bourdeauducq (lekernel). JTAGenum is most similar to the latter with the added feature of finding undocumented functionality. Felix Domke (tmbinc) recently gave a lecture on enumarating undocumented JTAG instructions and anyone considering using JTAGenum would do well to check his paper(cache)/lecture from the 26c3.

About JTAG

JTAG is a common hardware debugging interface. It is used throughout the development chain of a device. Layout designers and board manufactures that employ pick-and-place machines will use JTAG to test interconnectivity of components. ASIC designers use it to test the internal state of the chips they build. Software developers often use it to load firmware onto the device and to debug software.

For a varity of reasons JTAG is often left in the final product. As such each stage of the development chain will attempt to obfuscate its existence or functionality. ASIC manufactures often build in added functionality (such as logic analysis tools) and avoid mentioning both extended and often basic functionality from their final documentation. Layout designers might remove JTAG pins from the board, spread their contacts throughout on the board, remove contacts and hide JTAG lines on inner layers of the board. As mentioned before, this can make it difficult for any one part of the development chain to evaluate the security of the device as a whole. If you are unfamiliar with the inner workings of JTAG skip to the A bit more about JTAG section for the basics.

Hardware

To use JTAGenum you need an arduino compatible microcontroller. Arduino is a simple development enviornment (IDE) for various microcontrollers. At the moment AVR and PIC variants are available and can be purchased anywhere from $10 to $50. JTAGenum has been tested on the official Arduino Duemilanove, Arduino Mega (see hackerspace.be modifications), RBBB clone and Teensy++. When picking your microcontroller platform consider two issues: 1. How many pins do you want to check on your target. 2. what voltage level does your target device require.  Concerning voltage most Arduinos work at 5 volts. Some are switchable but even those that are not can be modified. For example revision 1.0 of the Teensy++ with over 30 pins of i/o can be modified by hand to operate at 3.3 volts. I show where to cut lines and install a voltage regulator over here (Update: Teensy++ version 2.0 has a spot on the pcb to install a 3.3v regulator). For voltages other than 3.3v and 5v there are a variety of solutions that depend on if you need uni-directional or bi-directional support on your i/o lines. Alessandro provides schematics and board/shield design for bi-direction i/o voltage conversion. Finally, check your microcontroller on your Arduino board. The Atmega328P supports a supply voltage of 1.8v to 5 so you could modify the board to support 1.8v. In contrast, the AT90USB on the Teensy boards only support 2.4 to 5.

When connecting the microcontroller to the pins of your target one thing to be aware of is possible cross-talk between wires. I’ve been using a patch cable from Amontec that has a lot of cross talk.  JTAGenum has a mode that helps check for this which I will get into more detail later.

Usage

Download the JTAGenum code and open it in the Arduino IDE. The following needs to be changed in the code depending on your microcontroller:

  • pins[] define which pins on the microcontroller are being used to connect to the target
  • pinname[] is a convenient way to map the pins to names which correspond to the names of pins on your target
  • IR_LEN defines the length of the JTAG instruction register. If you change this you should also add ‘0’s to each of the coresponding IR_** instruction definitions. You can find the IR_LEN in the documentation for your target. If you cannot find it just guess. (10 is the current value, 8 is also common)

Upload the sketch to your microcontroller and open the serial console with a baud of 115200.  Sending a ‘h’ to the console will print usage information that describes each function. Each function is enacted by sending the defined one character code:

v > verbose

Toggles verbose output. At times verbose might present too much information or without it too little.

l > loopback check

Find loopback pairs that will generate false-positives for other tests. After running you should remove any loopback pairs from your pins[]/pinnames[]. Looback pairs are found by sending a predetermined pattern[] to all possible pins while checking all pins for matching output.  Because the JTAG clock (TCK) and state (TMS) pins are NOT being stimulated the input/output pairs where the pattern is found represent loopbacks. NOTE: you should probably run this once with and without internal pull-up resistors set (‘r’) to avoid problems of cross-talk which is discussed in detail later.

s > scan

This routine is used to check all possible pins and find JTAG  clock, state, input and output pins lines (TCK,TMS,TDI,TDO). This is done by setting the JTAG state (TMS) into Shift_IR mode and then sending pattern[] to TDI and checking for it on TDO while clocking TCK. This check is run for every possible pin combination and it is important that you remove loopback pins before running. While this scan is meant to determine all of the JTAG pins required it is possible that the  TMS pin found is incorrect.  This depends on if the target uses the bypass register by default (described later). If an IDCODE register is present then bypass mode is not the default and you can assume that the pin this scan defines as TMS is correct.  Otherwise, only the TCK, TDI and TDO pins can be determined.  NOTE: run with pull-ups on (‘r’) as any cross-talk might result in false-positives.

y > brute force IR search

This will set the instruction register (IR) to all possible values and check the output. This can be used to find undocumented instructions and examine their results via the data register (DR). To run this scan you should have already determined the 4 JTAG pins and define pins[] as such: [0]=TCK [1]=TMS [2]=TDO [3]=TDI.  NOTE: run with pull-ups on (‘r’) as any cross-talk might result in false-positives.

x > boundary scan

This will return the state of all the pins on the target.  Actually it is not just the pins but the contents of the scan/sample register. This should be a rather large register and is defined in the code by SCAN_LEN+100. You can check your targets documentation and specify this or just leave it as a large number (currently 1800). To run this scan you should have already determined the 4 JTAG pins and define pins[] as such: [0]=TCK [1]=TMS [2]=TDO [3]=TDI.  NOTE: run with pull-ups on (‘r’) as any cross-talk might result in false-positives.

i > idcode scan

The JTAG standards specify that if an idcode register is present it should be set as the default data register (DR) and attached to output (TDO) by default. Meaning, regardless of the state of the JTAG chip (set with TMS line) and regardless of input being sent to the chip (TDI) by clocking the chip (TCK) it should return the contents of the idcode to the output (TDO). Hence, this routine iterates through all possible TCK,TDO pairs of pins, CLK’ing each bit along the way, and prints the output when there is any change (we assume an idcode will not be all 0’s or 1’s). You should examine the documentation of your target(s) to see if the idcode matches. NOTE: run with pull-ups on (‘r’) as any cross-talk might result in false-positives.

b > shift_bypass

Broken atm (need to add TCK enumeration). The JTAG standards specify that if and idcode register is NOT present on the chip then the bypass register (length of 1) should be the default DR. Essentially this means what is sent to the input (TDI) should come out on the output (TDI) with a one clock delay (TCK). It is important that you remove loopbacks before running this test otherwise the loopback pins will look like valid JTAG lines. NOTE: run with pull-ups on (‘r’) as any cross-talk might result in false-positives.

r > set pull-up resistors & cross-talk

If like me the cables you use to connect between JTAGenum to your targets are flimsy or uninsulated you might run into issues of cross-talk whereby when one pin is transmitting a nearby pin picks up the transmission even though they are not connected. To avoid this you can turn on the internal pull-up resistors which will force the pin to a default state. If for some reason you continue to have sporadic issues run the following in sequence to check if the problem is the cable, target or other:

  1. Disconnect the cables between your target and JTAGenum. Disconnected them entirely from JTAGenum as well.
  2. Run a loopback check (‘l’) with pull-ups off. In this state the pins are in open mode and might fluctuate.  You’ll notice that as you move the microcontroller around, turn lights on and off or move other devices close to or away from it that the results change.
  3. Turn on pull-ups (‘r’) and run the test again. The results should now be consistent. If they aren’t, then let me know.
  4. Now attach your cables to JTAGenum but not the target.  Run steps 2 and 3 again. Step 2 will give you a feel for how much inconsistency the cable may add. If the loopback check results in actual pattern matches then your cable has cross-talk. Step 3 should still result in a consistent state of either all high (1’s) or all low (0’s) and if it doesn’t then your cross-talk issues are such that all JTAGenum tests are going to be buggy at best. Feel free to give me an email and I will happily try to help solve the problem.

Code references

Examining code of various jtag scanning derivitives is probably the best way to modify JTAGenum however you want or when wanting to cross reference JTAG logic to debug a problem.

  • JTAG Finder – the microcontroller provides a pin protocol/interface to a C client running on the PC which does the actual scanning logic. This was one of the first (if not the) JTAG scanner.  It trades simplicty of code and protocol for efficiency and speed.
  • JRev – Not meant for scanning pins to find JTAG. It does however implement some logic not in any of the JTAG scanners mentioned here.  In paticular, support for chain mapping, IR length detection and perhaps others I’m missing.
  • JTAGulator – Scanner supporting adjustable target voltage 1.2 to 3.3v. Based on Parallax processor.
  • Arduinull – The first simplified scanner running all in the microcontroller.
  • JTAG pinout detector – a port of Arduinull and JTAGenum for the Arduino Mega board.

Additionally Jal2 and Zoobab have written their branches of JTAGenum.  I will try to merge their features to the JTAGenum branch as quickly as possible but if you run into problems or for general curiosity you can check their code.

A bit more about JTAG

Basic understanding of how JTAG works will be helpful when using JTAGenum. There are 4 lines/pins: TDO=output, TDI=input, TCK=clock, TMS=state machine control.  Say you want to read the ID of the chip. First you would send the IDCODE instruction to the instruction register (IR). The JTAG controller then places the actual id code value of the chip in a data register which you could then read out. You would think that it would be enough to have one input line going to the IR and one output coming from the DR but JTAG also supports writing to the DR. As opposed to adding another input line specific to the DR instead JTAG works by moving the input and output lines between IR and DR. The TMS line is used to switch TDI/TDO to IR when you want to place an instruction and back to DR when you want to read or write data. With all operations, be it state change (TMS) reading (TDI) or writing (TDO), the clock line must be cycled once (TCK) for every bit or change. This was a brutal and drastic simplification but with that understood reading the Usage section should be comprehensible.  — For further details on how non-standard commands work, such as those for reading memory or halting the CPU, few manufacturers detail this but one implementation can be found in the Atmel ATMEGA128 datasheet (cache), from pages 252 and 305.

Advertisement

Published by

44 responses to “JTAG Enumeration”

  1. See also another adapted version for the Arduino Mega:

    http://hackerspace.be/JTAG_pinout_detector

  2. Thanks zoobab. I linked back to your wiki on the mega should anyone want to use that platform.

    You mention that only used 21 ports from the mega at 3.3v were used. How did you come to this limit? Seeduino mega has a switch for 3.3v but also mention that it only works with 2 pin banks. i’ve been using a teensy++ with 36 i/o at 3.3v but I’d like to see more alternatives, such as the mega.

    when i get a moment, which should figure out a way to patch/port/merge the code and properly link to your source in whatever way you are comfortable with.

    ps. the seeeduino mega mentions similar issues with 3.3v use. they say they only were able to get two pin banks working at 3.3v.

  3. zoobab, how shall we port this. my thought is to remove GPL entirely and just merge our codes into a github repository we share mutually? Or, would you rather I just port it myself and put a change log at the very top linking to you and your wiki page?

  4. Can you try this one a normal Arduino:

    http://hackerspace.be/images/4/49/Serjtar_table_atmega168.pde.txt

    11 IO pins might be enough if you remove the GND pins with a multimeter first.

    1. yo, that is great. im not sure what problems you ran into but i didnt have trouble running JTAGenum with the normal arduino. but happy to see you have another resource people can check should they run into problems.

  5. “im not sure what problems you ran into but i didnt have trouble running JTAGenum with the normal arduino.”

    How did you do for the 3.3v adaptation?

  6. Hi, could you please add which voltage regulator you used for the Teensy++ mod? I cannot find one with the given pinout, (1 = Vin, 2 = 4 = GND, 3 = Vout), e.g. the LT1117CS-3.3 has: 1 = GND, 2 = Vout, 3 = Vin in SOT223-3.

    1. MCP1825 (, the same one they mention on the teensy site: http://www.pjrc.com/teensy/3volt.html

  7. […] Embedded analysis, in Berne Switzerland at 0sec. This talk will include discussion and release of JTAGenum, a Serial Pin Scanner, Parallel FLASH dumper and DePCB, the PCB trace analysis tool in the works. […]

  8. I have STB with M28W320FS flash chip I am trying to dump. I have Ardiuno Duewilanove and I am trying to find the jtag pins. I uploaded the jtagenum code to the Ardiuno and can connect to it at 57600 baud so that part is working well.

    I am not sure how I connect this, am I supose to connect all the input pins on the Ardiuno to some pins on my stb? Do I need to connect anything else on the Ardiuno to the STB like power?

    One final stupid question is the stb supose to be powered during the scan?

    1. First you have to check to see that the voltage level of your target pins are the same or within range of your arduino. Provided they likely match, You need to connect the pins of the arduino that are defined in the pins[] section of the code to the pins of your target. Also connect the ground pin of the arduino to ground of your target. The target should be turned on during the scan.

      You should find this writeup helpful:
      http://events.ccc.de/congress/2010/wiki/Embedded_Analysis

  9. Connected pins 2-13 on Ardiuno and scanned.

    There is no loopback but I am getting lot of FOUND results, does this make any sense?

    Starting scan for pattern:0110011101001101101000010111001001
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_2 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_3 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_4 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_6 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_7 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_9 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_10 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_13 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_12 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_2 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_3 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_4 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_6 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_7 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_9 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_10 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_8 tdo:DIG_5 tdi:DIG_11 ntrst:DIG_13 IR length: 0
    FOUND! tck:DIG_12 tms:DIG_11 tdo:DIG_5 tdi:DIG_8 ntrst:DIG_13 IR length: 0

    1. Hey I recently had a target with the same issue. However I also had some “FOUND!”s with a non 0 IR Length so I just ignored the 0 lengths. I meant to look at the IR length code and patter code more closely to see why this happens. It is very odd that this doesnt show up during loopback tests. Can you mail me and perhaps we chat offline and both work to try to figure this out?

      1. One thing to check would be the voltage levels of your target. With my target I was pushing the max tolerance a little so this might be the reason.

      2. I’ll understand if this is not something you want to delve into anymore but if you have some thoughts on what to look at, it would be appreciated. I just tested JTAGenum on two boards with known JTAG pins to try it out. All 3 boards are on 3.3V, the first was identified correctly (Linksys WRT54G router) with the pattern scan, the second (TI Launchpad TMC4C123) came up with lots of active results as seen below, and none are correct. (this is a subset) I can connect to the TI Launchpad board with a J-Link, so I know it works.

        FOUND! ntrst:White tck:Purple tms:Grey tdo:Blue tdi:Green IR length: 0
        FOUND! ntrst:Purple tck:Green tms:Blue tdo:White tdi:Grey IR length: 0
        FOUND! ntrst:Purple tck:Green tms:Grey tdo:White tdi:Blue IR length: 0
        active ntrst:Purple tck:Green tms:White tdo:Blue tdi:Grey bits toggled:18
        active ntrst:Purple tck:Green tms:White tdo:Grey tdi:Blue bits toggled:70
        active ntrst:Purple tck:Blue tms:Green tdo:Grey tdi:White bits toggled:32
        FOUND! ntrst:Purple tck:Blue tms:Grey tdo:White tdi:Green IR length: 0
        active ntrst:Purple tck:Blue tms:White tdo:Grey tdi:Green bits toggled:50
        active ntrst:Purple tck:Grey tms:Green tdo:Blue tdi:White bits toggled:63
        active ntrst:Purple tck:Grey tms:Green tdo:White tdi:Blue bits toggled:38
        FOUND! ntrst:Purple tck:Grey tms:Blue tdo:White tdi:Green IR length: 0
        active ntrst:Purple tck:Grey tms:White tdo:Green tdi:Blue bits toggled:62
        active ntrst:Purple tck:Grey tms:White tdo:Blue tdi:Green bits toggled:66
        active ntrst:Purple tck:White tms:Green tdo:Blue tdi:Grey bits toggled:53
        FOUND! ntrst:Purple tck:White tms:Green tdo:Grey tdi:Blue IR length: 34
        active ntrst:Purple tck:White tms:Blue tdo:Green tdi:Grey bits toggled:72
        FOUND! ntrst:Purple tck:White tms:Blue tdo:Grey tdi:Green IR length: 0
        FOUND! ntrst:Purple tck:White tms:Grey tdo:Green tdi:Blue IR length: 34
        FOUND! ntrst:Purple tck:White tms:Grey tdo:Blue tdi:Green IR length: 0
        ..

      3. Sorry for the long delay. What you are getting with the TI Launchpad is an issue I’ve also been having with the same target. In the past, we had issues just figuring out the right mode to put the Launchpad into, which is covered here in-depth, though the issues you are having apparently are not due to Launchpad configuration.

        The fact that the FOUND’s have IRLENGTH 0 is suspicious as that would imply that the instruction register is length 0. It should always be more than 3, unless the target does something special when JTAG is “disabled” and a 0 length IR is an indication of that? Also, the IRLENGTH of 34 is suspicious. The largest IR I’ve seen was 8 bits. A IRLENGTH on the scan would imply at least 4 different JTAG TAPS (JTAG enabled chips) in a single chain. Possible, but not likely and definitely not the case on the Launchpad which just as one CPU and one TAP iirc.

        So this is not helping much. But I’d be happy to have a call to discuss it in more detail if you want. Perhaps send me an email (nathan—squimp.com) and we could try to figure out a time that works?

  10. Will it work also on Arduino Uno ?

    1. I am %90 certain it will though I have not tested. The AVR didnt change much with the Uno so there shouldnt be any difference from our perspective. I will probably test this in a couple weeks and can tell you with absolute certainty then.

      1. I confirm it works…tested with Arduino UNO + txs108 level shifter….

  11. @A can you provide more info regarding txs108 level shifter.. how did u connect it? any diagram.

  12. @cyphunk / @A / @jCom –> is there a diagram or something else to show on howto do this on a arduino uno?
    As im esp interested in the 3.3v method as i have some testing boards but they all run @ 3.3v and i dont want to damage them trying them on a trial and error method.
    —–
    Aside from that for future reference wouldnt it be good to make a general wiki which holds al the details for different type of boards :?

    1. JTAGenum works on the Uno. But by “this” I guess you mean changing the Uno to operate at 3.3v? You can purchase some that are switchable, the new ARM based arduinos due to come out at the end of the year have an IOREF pin so you can work with low voltages. Or, you can modify yours. The best way is to just modify the USB cable and use an external power supply. I can try to find the link for you (I think Adafruit documented this) if you want.

      About a wiki, absolutely. I thought the CCC wiki could work. Was planning at the end of this year to port all my knowledge there.

    2. I have the schematic and the board in eagle format for the TXS108 translator , I will load them on my (now empty) blog soon.
      @cyphunk: i preferred the translator to avoid the 3.3v mod. the level shifter also gives 1.2 -> 3.6 v range

  13. Thnx for the info @cyphunk and im also looking forward to the translator @A as i would like to avoid the mod so i can use it 5v and on 3.3v. Could u provide me with a link when you uploaded it.

    1. Here is the translator link post: http://blog.pmst.net/2012/01/shiftino-arduino-level-shifting-shield.html it can be enhanced of course to provide more outputs (at the time not required).

      1. thanks for that. will be helpful. linked in article for future reference.

  14. […] undocumented instructions and functionality. I run into this so often that I’ve written tools that search the instruction space and help one find those registers that are docile and those that […]

  15. how i can run a command into the registry
    through i/o
    the cpu is sti7100
    and i need to run a command in it and get the result from out
    i wanna know is there is a tool to do that also can i use the tdi and tdo as i/o port
    what is the baudrate i have to define it to transfer this tdk_cmd into the cpu aslo iam using usb ttl with ftdi4323 with 480m/s transfer rate
    and thank u for ur gr8 work
    please advice

    1. Not sure i clearly understood but Im starting with the assumption you found the JTAG pins on your target already since a lot of sti7100 targets i noticed online show the pin map already. So you wont need to scan. Also guessing you are using this JTAG interface or similar: http://www.avi-plus.com/categories/repair-tips-forum/repair-tips-forum/st40-stb71xx-jtag-interfacing.html So the issue is how to connect to the ST40 target. ST20/ST40 are not supported by openocd last that I checked. You can use the ST Micro Connect tools (http://www.stlinux.com/install/distribution/introduction/STMC) and the link before describes in some detail how to connect and use GDB. Last I dealt with STi was many years ago so I’m not sure I can help you much more then that, without the actual target infront of me. Good luck

  16. Hi,

    I just got my Arduino Uno ot of the box, and uploaded JTAGenum on it.
    One small remark, at first the serial console didn’t work and all I got was gibberish. I also tried using Putty instead of Arduino console and got the same result.

    Only when I decided to try other baud rates I found out that it works perfectly fine with 57600.

    1. strange as the setup() function is using 115200 by default. It could be that the prescaler causes issues so maybe comment out this line:

      CPU_PRESCALE(0x01);

  17. Hi,

    I’m having trouble understanding “brute force IR scan” output.
    I managed to find the pinout using scan, and updated the right pins in the code.
    Now, if I got it right, when I run IR scan I get an output with a list of the IR values for which at least one bit was flipped.

    my IR_LEN is 4 (according to scan), and I get an output for 8 different IR values:
    most of them say “1 bit changed”
    2 say “3 bits changed”
    and one say “14 bits changed”

    Is the number of bits changing indicate the length of the relevant DR?
    Or does it just output whats already stored in this DR? (and if the DR content is all 1’s It’ll tell me nothing)

    thanks,
    dvir

    1. Hey can you send me a full log if you still have it? https://deadhacker.com/contact

  18. […] I tried using an Arduino Mega with JTAGenum to differentiate the signal lines automatically. When either of two out of the six pads were […]

  19. Hi, one clarification about Instruction Register length: manual says: “IR_LEN defines the length of the JTAG instruction register. If you change this you should also add ‘0’s to each of the coresponding IR_** instruction definitions.
    I set IR_LEN = 4 bits
    What should I change in #define IR_IDCODE and #define IR_PRELOAD ?

    #define IR_LEN 4
    // IR registers must be IR_LEN wide:
    #define IR_IDCODE “01100” // always 011
    #define IR_SAMPLE “10100” // always 101
    #define IR_PRELOAD IR_SAMPLE

    1. IR_IDCODE “01100” implies an IR_LEN of 5. 011 is the important part of the instruction and the two 00’s are added to it due to a LEN being set to 5. IR_LEN of 4 would require IR_IDCODE = 0110. IR_IDCODE should always begin with 011.

      By the way, if you compare the instruction bits to other specifications you may notice JTAGenum’s instruction bits are in reverse. That is because JTAGenum sends bits starting with the bit furthest left in the string. That means when we change the IR_LEN we add or remove 0’s on the right side of the string. For example on page 7 of this Altera Stratix chip JTAG specification (cache) you can see the instructions are 10 bits wide and in the forward order where command bits start at the right most bit with padding 0’s added to left.

  20. Good, its clear now. One note about setting the pins[] & pinnames[] on Arduino Pro: for 8-pin JTAG header (one pin is GND), will it be correct like this

    byte pins[] = { 2, 3, 4, 5, 6, 7, 8 };
    char * pinnames[] = { ” TDI”, ” TMS”, ” TCK”, ” TDO”, “DIG_6”, “DIG_7”, “DIG_8” };

    1. With the Arduino UNO pins are defined using integers, as you have defined in your pins[]. The confusion maybe comes from the other examples in the code, such as that for the Teensy board where pins are defined instead using names like PIN_B1. But for UNO, how you have it is correct.

      The strings in pinnames are arbitrary and you can define them as you like. Those strings are printed to the console during scanning. With your example as a reference, whenever an activity involving pin pins[0] is printed to the console rather than printing “pin 2 did something” the software will print “pin TDI did something”. During analysis I typically orient myself mentally according to my target and not my testing tool (arduino in this case) so I put the numbers of the target pins in pinnames.

  21. One note: does it make sense use wires with 100 Ohm resistors soldered to wires as current limiters for safety, or it safe use just regular wires to connect JTAGenum and device? Arduino Pro mini version 3.3V

  22. Have an issue where my scan hangs at random points. Thought it could be related to speed although even with delay set pretty high It seems to reoccur.

    It could be related to the fact my loopback check gives varying ‘active’ results each iteration its ran, sometimes several results sometimes just one and if ran enough times pretty much mentions all of my 10 pins at some point. Definitely connected to a ARM 10 pin JTAG header and have the target on, ground of arduino connected to ground on board etc.

    Any suggestions?

    1. Sometimes “hanging” actually means the code segfaulted. Arduino does not have a debugger beyond printf so we cannot know the root cause but I would check for a code error. It is, definitely, strange that this happens at odd locations.

      The rest of the symptoms you describe I have had, often. It is a process of trying to figure out false positives, removing where needed. Happy to have a voice conversation or just chat over jabber if you have time. (see /contact)

      1. I am using an Adafruit board with 32K of flash and 2K of RAM as it uses 3.3V I/O so segfaults could be that tbf. Thanks for offer of help, I will try some ideas / other hardware, identify false positives.

Leave a Reply to cyphunk Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s