
The black swift nanocomputer promotion campaign is
in full swing (see also the
publication on habrahabr ). black swift is based on
SoC Atheros AR9331 , which made it on the one hand tiny, inexpensive, and low-consuming, and on the other hand, the user has the MIPS 24Kc core operating at 400 MHz.
Recently
a question was asked on the forum black-swift.ruThere is a need for documentation on the use of the JTAG interface in the device. Can we expect anything in this direction?
In this publication, I will
insert my five cents. I’ll give you a specific simple scenario of using the Atheros AR9331 SoT JTAG interface for debugging software.
The publication may be of interest not only to software developers for the AR9331, but also to all those interested in in-circuit debugging on processors with MIPS architecture using free software.
There is no black swift card in the public domain at the time of this writing, however, ready-made devices based on SoC Atheros AR9331 are available; For the demonstration, I will use the
TP-Link MR3020 .
The difference between the MR3020 and the black swift is minimal, moreover, the transition to the black swift who has mastered working with the MR3020 may even seem to be a relief: connecting to the external interfaces of the SoC will be easier, and there will be fewer software obstacles.
Demonstration plan: we will stop the processor immediately after the start and launch on it, instead of the U-Boot boot loader installed in the ROM, another boot loader -
barebox .
What benefits (as applied to the MR3020) can be derived from using an EJTAG?
- TP-Link guys put restrictions on making changes to the device firmware (although they didn’t try very hard) - the ability to use the EJTAG removes these restrictions;
- the ability to use the EJTAG immediately after the processor starts greatly simplifies debugging the initial stage of the barebox loader (indeed, it is much more comfortable to use the EJTAG than to bother with flashing the boot ROM on the programmer);
- EJTAG allows you to restore the device after “scaling” as a result of damage to the contents of the boot ROM.
In order not to reach the presentation level “do it once, do two, press the button - you will get the result” I will try to give minimal explanations. You should start by explaining what an EJTAG is.
EJTAG in MIPS architecture processors
Development of any software product does not do without a debugging stage, and happiness for a programmer if he has an intelligent debugger at his disposal.
Software developers for * nix or Windows can use advanced debugging tools - you can run your program step by step, see the values ​​of variables at one time or another, set breakpoints.
But how to be a software developer for an embedded system? Such software can work outside the environment of any OS, and the embedded system itself is a little like a PC - as a rule, there is neither a keyboard nor a monitor.
In order to somehow simplify life in the described situation, in-circuit debugging technology (in-circuit debugging) was invented, which is as follows: a special block is introduced into the processor (let's call it “debugging unit”), which monitors the process of executing instructions and able to influence him. This block does not act by itself, but by the user's commands (which is the programmer who debugs the software). The JTAG interface is often used for external control of this debugging unit.
Why choose JTAG? JTAG is a serial bus (it is possible to use only 4 signals), allowing you to connect dozens of devices (possibly very different devices!) In a chain, and, as necessary, send commands to each of the devices. JTAG is widely used for testing connections in printed circuit boards - currently, LSIs for any more or less non-trivial boards are connected in a JTAG chain. It is quite reasonable to use JTAG not only for checking connections, but also for delivering debug control commands to the processor.
For MIPS processors, the standard is a set of hardware and software for in-circuit debugging called EJTAG. The EJTAG is standardized in the MIPS EJTAG Specification; there are several versions of this specification at once; for example, the 24Kc processor core includes a debugging unit conforming to the EJTAG 2.60 specification.
Thus, do not mix JTAG and EJTAG: JTAG is a data interface; EJTAG is a standard way for MIPS to perform in-circuit debugging using JTAG.
')
What do you need to work with EJTAG?
- MIPS processor with EJTAG support (target English or target processor);
- Instrumental computer with which we will manage the target processor;
- A device that provides a computer connection to the JTAG interface (English dongle);
- Software that runs on an instrumental computer receives instructions from the user to control the target processor, and through the dongle sends the necessary commands to the target processor.
Immediately, we note that the user does not need in-depth knowledge of the organization of the EJTAG, instructions for controlling the target processor are completely abstract, for example:
- stop the execution of instructions by the processor;
- start the execution of instructions from the address of such and such;
- execute one instruction and stop;
- view the contents of the processor registers.
For our demonstration, we will use:
- EJTAG processor - MIPS 24Kc from SoC Atheros AR9331;
- instrumental computer - PC with x86 / amd64 processor running Debian Linux OS (although other Linux OSs will work too);
- JTAG dongle - breadboard with FT2232H microcircuit (namely, microsin.net/adminstuff/hardware/ft2232h-board.html ) (hereinafter simply a layout);
- Management software for AR9331 via EJTAG -
openocd
(http://openocd.sourceforge.net/).
In addition, it is very desirable to connect also to the UART AR9331 interface, it is useful for interacting with programs running on the processor (without connecting to the UART, the demonstration would be rather boring). To send and receive symbols in the UART AR9331, use the
minicom
program.
Layout FT2232H provides connectivity immediately to both the UART and JTAG.
A command line interface will be used to interact with the instrumental computer, so prepare your terminals.
Connecting the FT2232H layout to the MR3020
Here is the wiring diagram (see also the
article on wikidevi.com ):

Someone such a connection scheme JTAG seem barbaric, but in our simple situation, it is quite justified.
Appearance of the MR3020 with the FT2232H breadboard connected:

Connect to UART
The output of the UART interface from the MR3020 is not a problem: the board already has holes for soldering pins.

The TX and RX designations in the photograph are from the point of view of AR9331, i.e. TX AR9331 (pin 1 on board) must be connected to the RX FT2232 (BDBUS1).
I recommend to connect the UART MR3020 to the breadboard, and the breadboard itself to the instrumental computer, and then, turning on the power of the MR3020, to observe the messages of the regular U-Boot loader using
minicom
.
This is what you need to do in a number of steps.
Checking the connection of the layout to the instrumental computer
Connect the UART MR3020 to the breadboard; connect the FT2232H breadboard to the instrumental computer via USB; on the instrumental computer in the command line, run dmesg - make sure that messages like
[1573965.608101] usb 1-2: new high-speed USB device number 63 using ehci-pci [1573965.740851] usb 1-2: New USB device found, idVendor=0403, idProduct=6010 [1573965.740862] usb 1-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [1573965.740868] usb 1-2: Product: Dual RS232-HS [1573965.740874] usb 1-2: Manufacturer: FTDI [1573965.741737] ftdi_sio 1-2:1.0: FTDI USB Serial Device converter detected [1573965.741938] usb 1-2: Detected FT2232H [1573965.741948] usb 1-2: Number of endpoints 2 [1573965.741957] usb 1-2: Endpoint 1 MaxPacketSize 512 [1573965.741966] usb 1-2: Endpoint 2 MaxPacketSize 512 [1573965.741974] usb 1-2: Setting MaxPacketSize 512 [1573965.742920] usb 1-2: FTDI USB Serial Device converter now attached to ttyUSB0 [1573965.743493] ftdi_sio 1-2:1.1: FTDI USB Serial Device converter detected [1573965.743662] usb 1-2: Detected FT2232H [1573965.743672] usb 1-2: Number of endpoints 2 [1573965.743681] usb 1-2: Endpoint 1 MaxPacketSize 512 [1573965.743690] usb 1-2: Endpoint 2 MaxPacketSize 512 [1573965.743699] usb 1-2: Setting MaxPacketSize 512 [1573965.744669] usb 1-2: FTDI USB Serial Device converter now attached to ttyUSB1
From this message, it follows that two new serial interfaces
/dev/ttyUSB0
and
/dev/ttyUSB1
have appeared on the instrumental computer. In accordance with the connection scheme to the UART MR3020, the second of the two interfaces is connected, that is
/dev/ttyUSB1
.
Install and configure minicom
Installing the
minicom
program on Debian-based distributions is very simple:
$ sudo apt-get install minicom
The
minicom
program is very kind to the beginner - all settings can be made through the menu, however this kindness has a downside - it is rather inconvenient to explain exactly how to set the necessary settings.
In order not to get involved with the
minicom
menu system, we will proceed more easily - we will make the settings using the configuration file. For simplicity, we will create a global configuration file, for this we will execute as root:
# cat <<EOF > /etc/minicom/minirc.USB1 pu port /dev/ttyUSB1 pu baudrate 115200 pu escape-key ^B pu rtscts No EOF
Note to non-Debian distribution users: the minicom
configuration files may be located in a location other than /etc/minicom/
.
The specified configuration file tells
minicom
'y that deviations from the default settings are as follows:
- port / dev / ttyUSB1 is used;
- configure port speed 115200;
- Minicom command start key - ctrl-b; for example, to call the main menu, press ctrl-b, then z;
- hardware flow control is disabled (indeed, for the connection we used only the RX and TX lines, which hardware flow control is already there).
Launch minicom
For simplicity, run
minicom
as root;
# minicom USB1
At the same time,
minicom
uses the settings from the
/etc/minicom/minirc.USB1
file (unless the
~/.minirc.USB1
file exists).
Of course, it is more competent to add your user to the dialout group ...; but let's not complicate things.
Now we turn on the power of the MR3020 and see in the
minicom
messages from the U-Boot:
U-Boot 1.1.4 (Aug 17 2012 - 15:21:03) AP121 (ar9330) U-boot DRAM: 32 MB led turning on for 1s... id read 0x100000ff flash size 4194304, sector count = 64 Flash: 4 MB Using default environment
Next will be given messages about loading linux, but they are not very interesting to us; If any reasonable output from the UART arrives, then you can proceed to connecting the JTAG.
Connect to JTAG
Connecting to JTAG is not trivial, but possible. See the
article on wikidevi.com .
In addition to the four lines of JTAG, you must also ensure that the boot ROM is turned off; In an article on wikidevi.com for this, it is proposed to break the ChipSelect line with a jumper (jumper). The fact is that the regular U-boot bootloader, located in the ROM, almost immediately after the start blocks the operation of JTAG.
In the case of the start of the processor with a non-working ROM, nothing terrible will happen, the processor will perform “garbage” instead of the program from the ROM. The processor will fall into a difficult situation, but the EJTAG will remain available.
After all the JTAG lines have been connected to the corresponding FT2232H pins, and the boot ROM is disabled, you can try scanning the JTAG chain using
openocd
. But before you start
openocd
, you have to install and configure it ...
Installing the
openocd
program is as
openocd
installing
minicom
:
$ sudo apt-get install openocd
openocd: initial setup
openocd
has a built-in tcl language, all scripts and configuration files are written on it. However, for our simplest case, the configuration file will be quite simple.
Create a file
ft2232h-scan.cfg
, in which we indicate
openocd
that we will use an FT2232H-based dongle to access the JTAG:
$ cat <<EOF > ft2232h-scan.cfg interface ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_layout_init 0x0018 0x05fb adapter_khz 100 shutdown EOF
In this file, we indicate that to connect to the JTAG we will use the ftdi “driver”, which serves all the numerous dongles based on the FT2232H. The ftdi_vid_pid option specifies the Vendor ID and Device ID of the FT2232H chip on the USB bus (by default, this is just 0x0403 0x6010; these IDs were in the
dmesg
output, you can view them at any time using the
lsusb
program). The ftdi_layout_init option specifies the settings for the GPIO outputs of the FT2232H. The adapter_khz option specifies the maximum JTAG clock frequency; 100 kHz (low frequency) is well suited for scanning.
The shutdown directive will force
openocd
to shut down immediately after a JTAG scan.
Let's run
openocd
as root (Warning:
openocd
should be
openocd
after powering on the MR3020, and the SW2 button on the MR3020 must be pressed at the time of power-on; also remember to lock the boot ROM):
# openocd -f ft2232h-scan.cfg Open On-Chip Debugger 0.8.0 (2014-10-20-22:02) Licensed under GNU GPL v2 For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' adapter speed: 100 kHz shutdown command invoked Info : clock speed 100 kHz Warn : There are no enabled taps. AUTO PROBING MIGHT NOT WORK!! Warn : AUTO auto0.tap - use "jtag newtap auto0 tap -expected-id 0x00000001 ..." Warn : AUTO auto0.tap - use "... -irlen 5" Warn : gdb services need one or more targets defined
In this conclusion, the lines containing
AUTO auto0.tap
deserve the most attention - they contain information about the JTAG subscribers found (tap controllers), and an example of the line that should be entered into the
openocd
configuration file to work with a freshly detected tap controller is immediately given.
We use these lines and create a configuration file for
openocd
, which will ensure that the
openocd
image is loaded into RAM.
But before loading the image of a barebox, you need to take it somewhere; and since there are no ready-made suitable images anywhere, it will collect the image independently from the source code.
Build barebox
The AR9331 barebox image should consist of MIPS32 processor instructions, and our instrumental computer is almost certainly built on the basis of a processor with the x86 or amd64 command system (as they are called Debian, anyway).
In order to generate MIPS32 instructions using an x86 / amd64 processor, we need a cross-compiler (that is, a compiler that runs on a computer with one instruction architecture, and generates code for a computer with another instruction set).
Building a cross-compiler with the required properties is not a trivial task at all, and to facilitate it, many different tools have been created that are known for the keywords buildroot, openwrt, crosstool-ng.
However, in this demonstration we will go easy - download the ready-made cross-compiler from MentorGraphics.
So, download and unpack the ready-made cross-compiler in / opt:
$ wget http://sourcery.mentor.com/public/gnu_toolchain/mips-linux-gnu/mips-2014.11-22-mips-linux-gnu-i686-pc-linux-gnu.tar.bz2 $ sudo tar fx mips-2014.11-22-mips-linux-gnu-i686-pc-linux-gnu.tar.bz2 -C /opt
As a result, for example, the path to the C cross-compiler will be: /
/opt/mips-2014.11/bin/mips-linux-gnu-gcc
/
/opt/mips-2014.11/bin/mips-linux-gnu-gcc
/
/opt/mips-2014.11/bin/mips-linux-gnu-gcc
/
/opt/mips-2014.11/bin/mips-linux-gnu-gcc
/
/opt/mips-2014.11/bin/mips-linux-gnu-gcc
.
Now download and unpack the source files of the barebox loader:
$ wget http://barebox.org/download/barebox-2015.01.0.tar.bz2 $ tar fx barebox-2015.01.0.tar.bz2
Build the barebox:
$ cd barebox-2015.01.0 $ make ARCH=mips tplink-mr3020_defconfig $ make ARCH=mips CROSS_COMPILE=/opt/mips-2014.11/bin/mips-linux-gnu- $ cd ..
If everything went well, we will get the file
barebox-2015.01.0/barebox.bin
.
openocd: more complete setup
Now we have what we can load in the RAM MR3020; paradoxically, but we do not have the RAM itself!
The fact is that when we have disabled the boot ROM with it, we have disabled the initial initialization of the AR9331 hardware, including the initialization of the RAM controller and the UART controller, in order to preserve the efficiency of the EJTAG.
Fortunately, the
sequence of entries in the registers for the initialization of the equipment is already known.
Finally, the file
ft2232h-mr3020.cfg
, which will connect the AR9331 debug unit, initialize the hardware, load the
barebox.bin
image
barebox.bin
RAM at
0xa0100000
and launch it for execution:
interface ftdi ftdi_vid_pid 0x0403 0x6010 ftdi_layout_init 0x0018 0x05fb adapter_khz 600 jtag newtap auto0 tap -expected-id 0x00000001 -irlen 5 target create auto0.tap mips_m4k -endian big -chain-position auto0.tap init halt
In openocd, a fairly reasonable practice is adopted, in which the description of the dongl, the description of the target processor, and the current debugging script are usually placed in different files, but in this publication we will not do this to simplify the presentation.
openocd: loading barebox
So, load and run barebox (Do not forget about the ROM shutdown jumper. Also, do not forget to hold down the SW2 button while turning on the power of the MR3020! Be patient - loading takes more than 100 seconds):
# openocd -f ft2232h-mr3020.cfg Open On-Chip Debugger 0.8.0 (2014-10-20-22:02) Licensed under GNU GPL v2 For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' adapter speed: 600 kHz Info : clock speed 600 kHz Info : JTAG tap: auto0.tap tap/device found: 0x00000001 (mfg: 0x000, part: 0x0000, ver: 0x0) target state: halted target halted in MIPS32 mode due to debug-request, pc: 0xb0ddd068 Error: No working memory available. Specify -work-area-phys to target. Warn : not enough working area available(requested 128) Error: No working area available Warn : Falling back to non-bulk write 185568 bytes written at address 0xa0100000 downloaded 185568 bytes in 102.970634s (1.760 KiB/s) shutdown command invoked
After the
openocd
working in the
minicom
window, we can observe messages about the start of the barebox:
barebox 2015.01.0 #1 Thu Jan 29 02:13:17 MSK 2015 Board: TP-LINK MR3020 m25p80 m25p80@00: unrecognized JEDEC id 900040 m25p80 m25p80@00: probe failed: No such device malloc space: 0xa0400000 -> 0xa07fffff (size 4 MiB) environment load /dev/env0: No such file or directory running /env/bin/init... /env/bin/init not found barebox:/
Then anyone can play with the barebox commands, the list of which opens with the help command.
Pay attention to the
probe failed: No such device
error message, it appeared due to the fact that barebox tried to “grope” the boot ROM on the SPI bus. But since the boot ROM was disabled to revive the EJTAG, an attempt by barebox to find anything was doomed to failure.
If you manage to put on a jumper that disconnects the boot ROM when the barebox is loaded into memory, you can instead
m25p80 m25p80@00: unrecognized JEDEC id 900040
observe more optimistic
m25p80 m25p80@00: s25sl032p (4096 Kbytes)
Although barebox-2015.01.0 supports SoC AR9331 hardware in the minimum amount (USB and Ethernet interfaces are not supported), but barebox can read and write the boot ROM.
What's next? (instead of epilogue)
Loading data into RAM is not the limit of EJTAG capabilities. But it is impossible to grasp the immensity - the publication does not cover the issues of debugging itself - this material remains for future publications.
Legal indignation causes a low data transfer rate - less than 2 KB in a second, this moment should also be tried to be corrected.
Thanks
The author is grateful to the people, without whose participation this publication would hardly have been possible:
- Alexey Rempel, who mastered connecting to the JTAG MR3020 and published his notes ;
- Alexei Sokolov, who absolutely perfectly soldered the wires to the board resistors of my copy of the MR3020;
- Petr Mamonov, for explaining to me the details of the work of the EJTAG and the various dongles.