danusha2345/xgecu-t48-reverse

GitHub: danusha2345/xgecu-t48-reverse

Stars: 3 | Forks: 0

# xgecu-t48-reverse Reverse-engineered USB protocol notes and a working Python tool for talking to the **XGecu T48 (TL866-3G)** universal programmer, with a focus on **eMMC** read/write operations (including in-circuit / ISP). The XGecu T48 is a popular universal chip programmer; its first-party software (`Xgpro`) is Windows-only and the device's USB protocol is undocumented. The open-source [`minipro`](https://gitlab.com/DavidGriffith/minipro) project covers the classic-chip part of the protocol but explicitly does **not** implement eMMC. This repository documents the eMMC extension of the protocol — what the wire-format actually looks like — and ships a working Python tool that uses the same encoding to read and write an eMMC in-circuit from Linux. ## What's in here - [`docs/PROTOCOL.md`](docs/PROTOCOL.md) — the full reverse-engineering write-up: USB identity (`a466:0a53`, WinUSB), endpoint roles (EP1 OUT/IN command + EP2 OUT bulk), the top-opcode / sub-opcode hierarchy, eMMC command table, init flow, RPMB frame layout, the `.alg` algorithm-file format, and the bulk transfer formats. - [`docs/ISP_SETTINGS.md`](docs/ISP_SETTINGS.md) — a plain-language reference for the Xgpro **eMMC ISP settings** (bus width, VCCQ, `ICSP_VCC Enable`, CLK, `Vcc current Imax`, partitions, RST_n wiring): what each does and what to enable / disable, cross-checked against the wire captures. Russian: [`ISP_SETTINGS.ru.md`](docs/ISP_SETTINGS.ru.md). - [`examples/t48_emmc_isp.py`](examples/t48_emmc_isp.py) — **the working in-circuit eMMC tool.** Reads and writes arbitrary regions over the XGecu eMMC-ISP adapter by replaying the captured protocol parameterised by block address. Hardware-verified at 1-bit / 3.3 V. Supports partition selection (`USER` / `BOOT1` / `BOOT2` / `RPMB`), erase, partition-table / filesystem-magic parsing, a boot-sector round-trip self-test, and VCCQ `--voltage {3.3,1.8}`. Modes: read-only validation (default, non-destructive), `--write-test`, `--partitions`, `--boot-roundtrip`. Includes anti-wedge teardown/recovery so a timeout no longer requires a physical replug. - [`examples/t48_emmc.py`](examples/t48_emmc.py) — the lower-level transport the ISP tool builds on: connect to the T48 by VID:PID, build the documented packets, and call them through high-level methods (`switch_partition`, `read_ecsd`, `bulk_read`, RPMB frame builder, etc.). Has an offline sanity test that verifies the three decoded CMD6 SWITCH arguments match the bytes seen in `Xgpro.exe`. Every USB transfer can be logged to a file (`T48Emmc(log_path=…)`) so a real session becomes ground truth for the protocol doc. - [`examples/first_contact.py`](examples/first_contact.py) — a **zero-risk** first-session probe to run the moment a T48 is plugged in: `connect → identify → measure voltages → status → read pins`. It applies **no programming voltage**, needs **no chip** and **no eMMC-ISP adapter**, and logs every transfer. The safe way to validate the transport and the classic opcodes before touching a chip. - [`tools/extract_alg.py`](tools/extract_alg.py) — standalone unpacker for the proprietary `.alg` files that ship with `Xgpro`. Each `.alg` contains a zero-RLE-compressed Xilinx Spartan-6 FPGA bitstream (340 604 bytes uncompressed) with a 32-bit CRC. No `.alg` files themselves are included — bring your own from a legitimate Xgpro install. ## Quick look at the protocol A `Xgpro` USB command on EP1 OUT starts with a 1-byte top-opcode. The ones in the classic range (`0x02..0x3F`) are already implemented by `minipro`. The eMMC extension adds these top-opcodes: | Top-opcode | Purpose | |------------|------------------------------------------------------| | `0x08` | Long-recv envelope (e.g. sub-op `0x48` → read 512 B) | | `0x14` | Bulk-write setup before N × 512 B on EP2 OUT | | `0x21` | eMMC init / algorithm select | | `0x27` | eMMC sub-command dispatcher (sub-op in byte 1) | For `0x27`-class commands the layout is 8 bytes: `[0x27][sub-op][u16 = 0][u32 arg LE]`. Among the sub-ops the **CMD6 SWITCH** encoding is the most informative: the 32-bit `arg` is exactly the JEDEC eMMC CMD6 argument in big-endian, so e.g. SWITCH PARTITION_CONFIG → RPMB → arg = 0x01B30300 SWITCH HS_TIMING → HS-200 → arg = 0x01AF0100 restore PARTITION_ACCESS → USER → arg = 0x02B30700 (CLEAR_BITS of 0x07) See `docs/PROTOCOL.md` §7 for the full table. ## Offline sanity test pip install pyusb python3 examples/t48_emmc.py This runs the byte-level sanity test without touching any hardware: == Проверка структур пакетов (offline) == cmd_A(SWITCH→RPMB) = 274600000003b301 cmd_A(SWITCH→USER restore)= 274600000007b302 cmd_A(SWITCH→HS200) = 274600000001af01 ... [OK] Все три расшифрованные команды сходятся с реверсом Xgpro.exe. With a T48 plugged in, `python3 examples/t48_emmc.py --connect` will attempt to open the device via libusb. On Linux you may need a udev rule to grant your user access to the device interface; on Windows the official WinUSB driver from XGecu is fine. For the **first** run on a fresh device, prefer the safe probe — it applies no voltage, needs no chip, and saves a full transfer trace: python3 examples/first_contact.py # → t48_first_contact.log ## Read/write an eMMC in-circuit With the XGecu eMMC-ISP adapter wired to a target eMMC, the ISP tool reads and writes arbitrary regions. The default mode is non-destructive (handshake + init, print CID, read one 16 KB chunk and hexdump it): python3 examples/t48_emmc_isp.py # read-only @ block 0x8000 python3 examples/t48_emmc_isp.py --block 0x100000 # read-only @ another block python3 examples/t48_emmc_isp.py --partitions # parse the partition table python3 examples/t48_emmc_isp.py --boot-roundtrip # read boot sectors, write them back, verify python3 examples/t48_emmc_isp.py --write-test 0x8000 # write marker + read-back verify (DESTRUCTIVE) python3 examples/t48_emmc_isp.py --voltage 1.8 # 1.8 V VCCQ (UNVERIFIED — use only on a known 1.8 V chip) See [`docs/ISP_SETTINGS.md`](docs/ISP_SETTINGS.md) for what the Xgpro settings (bus width, VCCQ, CLK, partitions, RST_n wiring) mean and a stable starting point, and `docs/PROTOCOL.md` §33–§35 for the wire-level breakdown of the ISP read/write flow. ## Unpacking a `.alg` (optional) If you want to look at the FPGA bitstream that ships with `Xgpro` for a given chip family, the unpacker writes the raw 340604-byte payload: python3 tools/extract_alg.py path/to/Xgpro/algorithm/EMMC_41_18.alg # → EMMC_41_18.bit (340604 bytes, with 16-byte 0xFF preamble + FPGA sync) ## What's *not* here Per the project's purpose this repository contains only original material — the reverse-engineering write-up and our own code that *talks the documented protocol*. It deliberately does **not** ship: - any binary from XGecu (`Xgpro.exe`, drivers, firmware updates) - any `.alg` algorithm files - the chip database (`InfoIC2Plus.dll` dump) - decompressed FPGA bitstreams Those are XGecu's copyrighted material. The `Xgpro` software is available for free from the manufacturer (https://www.xgecu.com/), and the `dumpic` tool in `minipro` produces the chip-database dump locally from a legitimate install. ## Why this exists The intended consumer of this material is a separate eMMC-reader application that already supports other USB-eMMC backends and wants to add the T48 as one more backend on Windows and Linux. Documenting the protocol publicly is also useful for anyone running the T48 from Linux who wants something more programmable than running `Xgpro` under Wine. This work piggybacks on the excellent [`minipro`](https://gitlab.com/DavidGriffith/minipro) (GPL-3.0) — it already implements the shared T48 transport (opcodes `0x02..0x3F`, USB handshake, voltage / clock control) — and on [`radiomanV/TL866`](https://github.com/radiomanV/TL866) for the firmware side of the device family. ## License [MIT](LICENSE). Reverse engineering for the purpose of interoperability between independently-developed software and the hardware its owner purchased.