Files
bs_explorer/README.md
François 4b924629be doc: update README for the proxy flash path and current state
Reflect what now works: per-FPGA registry, BSCAN proxy SPI bridge, and
flash detect/read/erase/program/verify (~100 KB/s). Switch the typical
flow to the proxy path, add the fpga/bscan/flash command rows, note
persistent history, the KU040 BSDL, the new modules + bscan_proxies/ in
the layout, and the quartiq MIT proxies in the license section.
2026-05-24 01:11:39 +02:00

172 lines
6.7 KiB
Markdown

# bs_explorer — Boundary Scan Explorer
Command-line tool to explore a JTAG chain, drive an FPGA's pins through
boundary scan (BSDL), and program the SPI configuration flash attached
to an FPGA (Xilinx and others) over JTAG — fast, via a BSCAN proxy
bitstream loaded into the fabric (~100 KB/s), or slowly via EXTEST pin
bit-bang for one-shot checks.
Based on the [jtag-boundary-scanner](https://github.com/viveris/jtag-boundary-scanner)
library by Viveris (LGPL).
## Status
- JTAG chain detection through FTDI / J-Link / Linux GPIO / Digilent SMT2 probes: OK
- Automatic BSDL loading by IDCODE: OK
- Pin control in SAMPLE / EXTEST, incl. slow SPI bit-bang: OK
- Per-FPGA registry (IDCODE → BSDL, IR opcodes, proxy, caveats): OK
- BSCAN proxy SPI bridge (load proxy bitstream, talk SPI via `USER1`): OK
- SPI flash detect / read / erase / program / verify: OK (~100 KB/s via the proxy)
Bundled BSDLs: Xilinx Kintex UltraScale+ KU15P
(`bsdl_files/xcku15p_ffve1517.bsd`) and Kintex UltraScale KU040
(`bsdl_files/xcku040_ffva1156.bsd`). Add more by dropping `.bsd` files
in `bsdl_files/` (see [`doc/tutorial.md`](doc/tutorial.md) for adding a
target).
## Dependencies
- CMake ≥ 3.10, gcc/clang
- `readline` (Arch: `readline`, Debian/Ubuntu: `libreadline-dev`)
- `libftd2xx` for FTDI probes (vendored in `libs/libftd2xx/`)
- *To drive a Digilent SMT2/SMT2-NC probe:* the Digilent
[Adept Runtime](https://digilent.com/shop/software/digilent-adept/)
installed system-wide (provides `libdjtg.so` + `libdmgr.so`).
Nothing from Digilent is vendored — the backend is `dlopen`'d at
runtime, so it's built in by default and simply reports no probe if
the libs are missing.
## Build
```sh
mkdir build && cd build
cmake ..
make
```
The binary is produced at `build/bs/bs`.
The Digilent SMT2 backend is built by default on Linux. To leave it out:
```sh
cmake -DBS_ENABLE_DIGILENT=OFF ..
```
## Run
```sh
cd build
./bs/bs
```
At startup, `bs_explorer` looks for a `config.script` file in the
current directory to override default settings (FTDI clock, TRST/SRST
pin mapping, etc.). See `modules/config/config.script` for the full
list of variables.
## REPL
- `<Tab>` completes command names.
- Persistent history (GNU readline) in `~/.bs_explorer_history`:
up/down arrows and Ctrl-R recall commands across sessions.
- `help` or `?` lists commands; `help <cmd>` shows details.
- `exit`, `quit`, or Ctrl-D to leave.
## Typical flow
```sh
# 1. List probes, open one by its index (the [N] in the list)
bs_explorer> jtag_probes
[0] 0x00000000 <probe description>
bs_explorer> jtag_open 0 # or the raw 0x id shown next to it
# 2. Scan the chain and auto-load matching BSDLs
bs_explorer> jtag_autoinit
# 3. Load the BSCAN proxy into the fabric (fast SPI bridge)
bs_explorer> bscan_load_bitstream 0 bscan_proxies/bscan_spi_xcku040.bit
# 4. Talk to the SPI flash through the proxy
bs_explorer> flash_detect 0 # JEDEC ID -> chip name / size
bs_explorer> flash_read 0 0x0 256 # hex dump
bs_explorer> flash_erase 0 0x10000 4096
bs_explorer> flash_write 0 0x10000 image.bin
bs_explorer> flash_verify 0 0x10000 image.bin
```
The slow EXTEST path (bit-bang SPI on boundary-scan pins, `jtag_mode 0
EXTEST` + `jtag_spi_*`) is only useful for one-shot checks — see the
tutorial. A minimal example script is in `scripts/example_script.txt`;
the full walkthrough (probe → proxy → flash) lives in
[`doc/tutorial.md`](doc/tutorial.md).
## Main commands
| Category | Commands |
|----------|----------|
| Script control | `set`, `print`, `print_env_var`, `if`, `goto`, `call`, `return`, `rand`, `init_array`, `system`, `pause` |
| Probe / chain | `jtag_probes`, `jtag_open`, `jtag_scan`, `jtag_autoinit`, `jtag_ndev`, `jtag_devices` |
| BSDL / pins | `jtag_bsdl`, `jtag_pins`, `jtag_mode`, `jtag_pin_dir`, `jtag_pin_set`, `jtag_pin_get`, `jtag_push_pop` |
| I²C / MDIO / SPI over BS pins (EXTEST) | `jtag_i2c_scl`, `jtag_i2c_sda`, `jtag_i2c_rd`, `jtag_i2c_wr`, `jtag_mdio_mdc`, `jtag_mdio_io`, `jtag_mdio_rd`, `jtag_mdio_wr`, `jtag_spi_cs/mosi/miso/clk`, `jtag_spi_xfer` |
| FPGA registry | `fpga_list`, `fpga_info` |
| BSCAN proxy | `bscan_load_bitstream`, `bscan_jedec`, `bscan_set_ir`, `bscan_shift_dr` |
| SPI flash (via proxy) | `flash_detect`, `flash_read`, `flash_erase`, `flash_write`, `flash_verify` |
| Misc | `help`, `?`, `version`, `exit` |
Use `help <command>` for per-command help.
## Supported probes
- **FTDI** MPSSE (FT2232D/H, FT4232H, …) — see the `PROBE_FTDI_*` block
in `modules/config/config.script` for pin mapping and TCK frequency.
- **SEGGER J-Link**
- **Linux GPIO** (sysfs; deprecated on recent kernels, libgpiod migration TBD)
- **Digilent JTAG-SMT2 / SMT2-NC** — built in by default on Linux
(`-DBS_ENABLE_DIGILENT=OFF` to drop it). Required for the USB-JTAG on
Xilinx eval boards like the KCU105: those modules ship a
Digilent-proprietary firmware that does not respond to plain MPSSE,
so the FTDI driver appears to enumerate them but the JTAG chain stays
silent.
## Known Xilinx caveats
On 7-Series / UltraScale / UltraScale+, `CCLK` is not a regular I/O pin
and goes through the `STARTUPE3` primitive, so it cannot be driven
directly in EXTEST — the slow EXTEST SPI path therefore can't clock the
flash on these parts.
The **BSCAN proxy sidesteps this entirely**: it drives `CCLK` from the
fabric internally, so flashing runs at full speed. Parts affected are
flagged with the `CCLK_VIA_STARTUP` caveat in the registry (`fpga_info`
shows it).
## Repository layout
```
bs/ Application (readline REPL)
modules/
├── jtag_core/ TAP state machine, IR/DR shifts
├── bsdl_parser/ .bsd loader
├── bus_over_jtag/ SPI / I²C / MDIO / parallel mem bit-bang (EXTEST)
├── drivers/ FTDI, J-Link, Linux GPIO, LPT, Digilent (optional)
├── fpga/ Per-target registry (IDCODE, BSDL, IR opcodes, caveats)
├── bscan_spi/ BSCAN proxy loader + fast SPI-over-USER1 bridge
├── spi_flash/ SPI NOR chip database + read/erase/program/verify
├── script/ Script engine
├── config/ Built-in config.script
├── os_interface/ Portable fs/network wrappers
└── natsort/ Natural-order pin-name sorting
bsdl_files/ BSDL files for target FPGAs
bscan_proxies/ BSCAN proxy bitstreams (MIT, from quartiq)
scripts/ Example scripts
doc/ Tutorial and longer-form docs
libs/libftd2xx/ Vendored FTDI SDK
```
## License
`modules/jtag_core/` and the original Viveris files are under LGPL 2.1.
See `LICENSE` and `modules/jtag_core/COPYING.LESSER`. The proxy
bitstreams in `bscan_proxies/` are from quartiq (MIT) — see
`bscan_proxies/LICENSE.quartiq`.