PROTOCOL OVERVIEW
Quick reference for embedded/hardware protocols encountered during device security testing.
UART — Universal Async Receiver/Transmitter
Serial communication. Most common debug interface on embedded devices. Usually 3.3V. Baud rates: 9600, 115200, 57600, 38400, 19200 most common. Provides root shell access on Linux devices via bootloader interrupt.
TXOUTTransmit — connect to target RX. Typically HIGH (3.3V) when idle.
RXINReceive — connect to target TX. Never connect both TX to TX.
GNDPWRCommon ground. MUST connect before TX/RX.
VCCPWROptional — do NOT power device via VCC unless certain of voltage
JTAG — Joint Test Action Group
Debug/programming interface. 4-wire minimum (TDI/TDO/TCK/TMS) + optional TRST and SRST. Used for firmware extraction, memory dump, live debugging. OpenOCD + JLink/FTDI adapter.
TCKCLKTest Clock — provided by debugger
TMSOUTTest Mode Select — controls TAP state machine
TDIOUTTest Data In — data into device
TDOINTest Data Out — data from device
TRSTOUTTest Reset — optional, active low
SRSTOUTSystem Reset — optional, resets target CPU
SPI — Serial Peripheral Interface
4-wire synchronous. Used for flash memory, displays, sensors. Common for firmware extraction from SPI NOR/NAND flash (25QXX series). Flashrom + CH341A programmer.
SCLK/CLKCLKClock — from master
MOSI/SDIOUTMaster Out Slave In
MISO/SDOINMaster In Slave Out
CS/CEOUTChip Select — active low. One per slave.
I2C — Inter-Integrated Circuit
2-wire synchronous. Shared bus with addressing. Pull-up resistors required (4.7kΩ typical). Logic analyser needed to decode addresses. 7-bit addresses 0x00–0x7F.
SCLCLKSerial Clock — from master
SDAI/OSerial Data — bidirectional, open-drain
UART
⚠ Voltage — most embedded devices use 3.3V UART. Connecting a 5V adapter will damage the device. Measure voltage on TX pin before connecting. Use level shifter for 5V boards.
◆ To identify baud rate: connect to TX only (no RX), capture output in minicom/screen with different baud rates. Correct baud = readable text at boot. Common: 115200, 57600, 38400, 9600.
UART Adapter Wiring (USB → Device)
| Adapter | → Device | Notes |
| TX | → RX | Adapter transmit → Device receive |
| RX | → TX | Adapter receive ← Device transmit |
| GND | → GND | ALWAYS connect GND first |
| VCC | → — | Do NOT connect unless powering device |
minicom / screen Commands
| LINUX | ||
| screen /dev/ttyUSB0 115200 | Connect at 115200 baud | |
| minicom -D /dev/ttyUSB0 -b 115200 | ||
| picocom -b 115200 /dev/ttyUSB0 | ||
| WINDOWS | ||
| PuTTY → Serial → COMX → 115200 | ||
| mode COM3: BAUD=115200 PARITY=n DATA=8 | CMD check | |
JTAG
◆ JTAGulator (by Joe Grand) automates JTAG pin identification. Also try JTAGenum Arduino sketch. OpenOCD config files needed for each target — search for target CPU name in OpenOCD source.
20-Pin ARM JTAG (Cortex debug)
| Pin 1 | VCC | Target reference voltage |
| Pin 2 | VCC | Duplicate VCC |
| Pin 3 | TRST | Test Reset (active low) |
| Pin 4 | GND | Ground |
| Pin 5 | TDI | Test Data In |
| Pin 6 | GND | Ground |
| Pin 7 | TMS | Test Mode Select |
| Pin 8 | GND | Ground |
| Pin 9 | TCK | Test Clock |
| Pin 10 | GND | Ground |
| Pin 13 | TDO | Test Data Out |
| Pin 15 | SRST | System Reset |
SWD — Serial Wire Debug (ARM Cortex)
| VCC | VCC | 3.3V reference (do not power from here) |
| SWCLK | TCK | Serial Wire Clock |
| SWDIO | TMS | Serial Wire Data I/O |
| SWO | TDO | Serial Wire Output — optional trace |
| RESET | SRST | Optional reset pin |
| GND | GND | Ground |
| 2-wire only required: SWCLK + SWDIO + GND | ||
ESP32-S3
Key GPIO assignments. Exact pins vary by board (DevKitC vs Waveshare AMOLED vs Baguette S3 etc) — always cross-reference schematic. Strapping pins must be correct at boot.
◆ UART0 (GPIO43=TX, GPIO44=RX) is default debug UART. USB-OTG on GPIO19/20 for native CDC. I2C/SPI are configurable to almost any GPIO.
UART (ESP32-S3)
| GPIO43 | UART0 TX | Default debug TX (3.3V) |
| GPIO44 | UART0 RX | Default debug RX |
| GPIO17 | UART1 TX | Configurable |
| GPIO18 | UART1 RX | Configurable |
SPI (ESP32-S3 default)
| GPIO11 | FSPI CLK | SPI2 Clock |
| GPIO13 | FSPI MOSI | SPI2 MOSI |
| GPIO12 | FSPI MISO | SPI2 MISO |
| GPIO10 | FSPI CS0 | SPI2 CS |
I2C (ESP32-S3 default)
| GPIO8 | I2C SDA | Default I2C data |
| GPIO9 | I2C SCL | Default I2C clock |
| Any GPIO configurable via Wire.begin(SDA,SCL) | ||
Strapping Pins (ESP32-S3)
| GPIO0 | BOOT | LOW = download mode, HIGH = normal boot |
| GPIO3 | JTAG | LOW = JTAG enabled |
| GPIO45 | VDD_SPI | Flash voltage select |
| GPIO46 | ROM log | LOW = ROM log disabled |
RASPBERRY PI PICO W
RP2040 based. 3.3V I/O. USB device on pin 47/48. SWD debug on 3-pin header. CircuitPython / MicroPython / Arduino IDE.
UART (Pico W)
| GP0 (pin 1) | UART0 TX | 3.3V |
| GP1 (pin 2) | UART0 RX | |
| GP4 (pin 6) | UART1 TX | Alt UART |
| GP5 (pin 7) | UART1 RX | Alt UART |
SPI (Pico W)
| GP18 (pin 24) | SPI0 CLK | |
| GP19 (pin 25) | SPI0 MOSI | TX |
| GP16 (pin 21) | SPI0 MISO | RX |
| GP17 (pin 22) | SPI0 CSn | Chip Select |
I2C (Pico W)
| GP4 (pin 6) | I2C0 SDA | |
| GP5 (pin 7) | I2C0 SCL | |
| GP2 (pin 4) | I2C1 SDA | Alt I2C |
| GP3 (pin 5) | I2C1 SCL | Alt I2C |
Power / SWD (Pico W)
| Pin 36 | 3V3 OUT | 3.3V regulated output |
| Pin 40 | VBUS | 5V from USB |
| Pin 39 | VSYS | 1.8–5.5V input |
| SWDIO | SWD Data | Debug header (3-pin) |
| SWCLK | SWD Clock | Debug header |
RASPBERRY PI 4/5 GPIO
40-pin header. 3.3V I/O — NOT 5V tolerant on GPIO. Physical pin numbers vs BCM GPIO numbers differ.
Power Pins
| Pin 1 | 3.3V | 3.3V out (max ~50mA) |
| Pin 2 | 5V | 5V out (from PSU) |
| Pin 4 | 5V | 5V out |
| Pin 6,9,14,20,25,30,34,39 | GND | Ground |
UART (Pi 4/5)
| Pin 8 (GPIO14) | UART TX | Enable in raspi-config |
| Pin 10 (GPIO15) | UART RX | |
| Pi 4: PL011 on GPIO14/15 after disabling BT overlay | ||
SPI (Pi 4/5)
| Pin 23 (GPIO11) | SPI0 CLK | SCLK |
| Pin 19 (GPIO10) | SPI0 MOSI | |
| Pin 21 (GPIO9) | SPI0 MISO | |
| Pin 24 (GPIO8) | SPI0 CE0 | Chip Select 0 |
| Pin 26 (GPIO7) | SPI0 CE1 | Chip Select 1 |
I2C (Pi 4/5)
| Pin 3 (GPIO2) | I2C1 SDA | Has 1.8kΩ pull-up on board |
| Pin 5 (GPIO3) | I2C1 SCL | Has 1.8kΩ pull-up |
| Enable: raspi-config → Interface Options → I2C | ||
SPI
◆ SPI flash (25QXX series) is common in routers, cameras. Use CH341A programmer + flashrom to read/write. Clip onto SOIC-8 in-circuit with device powered off. Check datasheet for exact pin 1 (marked with dot).
SOIC-8 SPI NOR Flash (W25Q, MX25L, etc)
| Pin 1 | /CS | Chip Select (active low) → CS/CE on programmer |
| Pin 2 | DO/MISO | Data Out → MISO on programmer |
| Pin 3 | /WP | Write Protect — tie HIGH (3.3V) to enable write |
| Pin 4 | GND | Ground |
| Pin 5 | DI/MOSI | Data In → MOSI on programmer |
| Pin 6 | CLK | Clock → SCLK on programmer |
| Pin 7 | /HOLD | Pause — tie HIGH (3.3V) |
| Pin 8 | VCC | 3.3V power (use programmer VCC) |
CH341A Programmer Pinout
| Pin 1 | CS | Chip Select |
| Pin 2 | MISO | Data from flash |
| Pin 3 | WP | Write Protect |
| Pin 4 | GND | Ground |
| Pin 5 | MOSI | Data to flash |
| Pin 6 | CLK | Clock |
| Pin 7 | HOLD | Hold |
| Pin 8 | VCC | 3.3V |
| flashrom -p ch341a_spi -r dump.bin | ||
I2C
◆ Use i2cdetect -y 1 on Linux to scan for devices. Common addresses: 0x50-0x57 EEPROM, 0x68 RTC (DS3231), 0x3C/0x3D OLED display, 0x76/0x77 BME280 sensor.
Common I2C Addresses
0x50–57AT24Cxx EEPROM — may contain config/credentials
0x68/69MPU-6050 IMU / DS1307 RTC
0x3C/3DSSD1306 OLED display
0x20–27PCF8574 I/O expander
0x48–4FADS1115 ADC / TMP102 temp sensor
USB
USB Type-A / Type-B
| Pin 1 | VBUS | +5V (500mA USB2, 900mA USB3) |
| Pin 2 | D− | Data negative |
| Pin 3 | D+ | Data positive |
| Pin 4 | GND | Ground/Shield |
USB Micro-B
| Pin 1 | VBUS | +5V |
| Pin 2 | D− | Data− |
| Pin 3 | D+ | Data+ |
| Pin 4 | ID | OTG ID — GND = host mode, float = device |
| Pin 5 | GND | Ground |
USB Type-C (simplified)
| A1/B1 | GND | Ground |
| A4/B4 | VBUS | +5V (or up to 20V with PD) |
| A6 | D+ | USB 2.0 data+ |
| A7 | D− | USB 2.0 data− |
| A5/B5 | CC1/CC2 | Config channel — orientation, PD negotiation |
| A2/B11 | TX/RX | USB 3.1 SuperSpeed pairs |
IDENTIFY UNKNOWN PORTS
Systematic approach to identifying undocumented debug headers on PCBs.
◆ Tools needed: multimeter, logic analyser (Saleae/cheapo), USB-serial adapter (CP2102/CH340), JTAGulator (optional).
Step 1 — Power Analysis (Multimeter)
| Step 1 | Check voltage | DC voltage each pin to GND. Identify: 0V=GND, 3.3V, 5V, 1.8V |
| Step 2 | Continuity | Ring out to known ground/VCC. Identify power pins. |
| Step 3 | Idle state | UART TX idles HIGH. UART RX floats or HIGH. JTAG TDO often floats. |
Step 2 — UART Hunt
| Boot | Watch with scope | During power-on, TX pin will toggle rapidly — this is serial output |
| Baud | Auto-detect | minicom / baudrate.py — try 115200, 57600, 38400, 9600 |
| Confirm | Readable text | Bootloader strings confirm correct baud + TX pin |
| RX | Probe others | Remaining pin near TX = RX. Sending char should echo. |
Step 3 — JTAG Hunt
| JTAGulator | Automated | Connect all suspected pins, run BYPASS scan |
| Manual | OpenOCD scan | openocd -f interface/jlink.cfg -c "jtag scan" (enumerate chain) |
| TCK hint | Clock pin | TCK often has pull-down or capacitor to ground on PCB |
| TDO hint | Output | TDO may float — high-Z when JTAG not active |
Step 4 — Flash Extraction
| Locate | SOIC-8 chip | Look for 8-pin IC near CPU — check markings (W25Q, MX25L, GD25Q) |
| In-circuit | Clip on | Power device OFF. Use SOIC-8 clip → CH341A |
| Read | flashrom | flashrom -p ch341a_spi -r firmware.bin |
| Analyse | binwalk | binwalk -e firmware.bin — extract filesystem |