June 3, 2024

Antminer S9 board - JTAG, OpenOCD, and the bootrom

I am working on writing a python script that will use the "secret" uart boot loader to load and run binary files. I got to a point where I decided that only JTAG would enable me to make progress (or a lot of trial and error). I spent a few hours soldering a 14 pin 2mm header onto the Antminer S9. Then I built an adapter to go from my Segger J-link (20 pin cable) to the 14 pin header on the Antminer. It seems to work. The trick now is remembering how to work with OpenOCD.

The bootrom

In general, the bootrom disables JTAG until it is entirely done loading whatever it is supposed to load. This means that if you set the board jumpers for uart boot, then try to fire up OpenOCD you will get errors like:
Warn : JTAG tap: zynq.cpu       UNEXPECTED: 0xffffffff (mfg: 0x7ff (), part: 0xffff, ver: 0xf)
Error: Invalid ACK (7) in DAP response
The answer to this is to run my python script and load something, then when I fire up OpenOCD, I get:
Info : JTAG tap: zynq_pl.bs tap/device found: 0x13722093 (mfg: 0x049 (Xilinx), part: 0x3722, ver: 0x1)
Info : JTAG tap: zynq.cpu tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)

My files and setup

I am using files in the /u1/Projects/OpenOCD directory on my Fedora linux machine. These are laying around from when I was working with my EBAZ boards earlier this year. I do this: Then in the telnet window, I do this:
targets
targets zynq.cpu0
halt
arm disassemble 0 64
The "halt" command shows the PC at address 0. The disassemble takes a surprisingly long time, but then shows me what I want. After some inspection I realize that what is loaded at address 0 is what should be loaded at address 0x60. So the first 0x60 bytes of my code have been lost! This certainly explains why things are not working.

Adding some pad bytes to the header fixes all that.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org