Debugging Tools
The tools/ directory includes a suite of diagnostic scripts developed during the reverse engineering of the SkyWalker-1. These tools were instrumental in isolating the I2C STOP corruption bug in the FX2 controller and verifying correct BCM4500 initialization.
All debugging tools require pyusb, root access, and the kernel dvb_usb_gp8psk module to be unloaded.
pip install pyusbsudo modprobe -r dvb_usb_gp8psk gp8psk_feBoot Testing Tools
Section titled “Boot Testing Tools”Two scripts test the BCM4500 boot sequence using debug modes in the custom v3.01.0 firmware.
test_boot.py — Full Boot Verification
Section titled “test_boot.py — Full Boot Verification”Runs a complete BOOT_8PSK sequence and reports success or failure with detailed register readback.
sudo python3 tools/test_boot.pyWhat it does:
- Reads firmware version via
GET_FW_VERS(0x92) - Reads config status via
GET_8PSK_CONFIG(0x80) - Sends
BOOT_8PSK(0x89, wValue=1) with a 10-second timeout - Decodes the 3-byte response: config status, boot stage, probe byte
- On success: reads BCM4500 direct registers (0xA2—0xA8), indirect registers (pages 0x00—0x0F), I2C diagnostic data, signal strength, and lock status
- On failure: runs I2C bus scan (0xB4), attempts raw I2C reads to BCM4500
Boot stage codes:
| Stage | Code | Meaning |
|---|---|---|
NOT_STARTED | 0x00 | Boot not attempted |
GPIO_SETUP | 0x01 | GPIO pins configured |
PWR_SETTLED | 0x02 | Power-on delay complete |
I2C_PROBE | 0x03 | Probing BCM4500 on I2C |
INIT_BLK0 | 0x04 | Writing init block 0 |
INIT_BLK1 | 0x05 | Writing init block 1 |
INIT_BLK2 | 0x06 | Writing init block 2 |
COMPLETE | 0xFF | Boot finished |
Config status flags after successful boot:
| Flag | Bit | Expected |
|---|---|---|
bm8pskStarted | 0x01 | ON |
bm8pskFW_Loaded | 0x02 | ON |
test_boot_debug.py — Incremental Stage Testing
Section titled “test_boot_debug.py — Incremental Stage Testing”Sends debug boot modes (wValue=0x80 through 0x83) one at a time to isolate which stage of the boot sequence fails. Can test a single stage or run all sequentially.
sudo python3 tools/test_boot_debug.pysudo python3 tools/test_boot_debug.py 0x82Debug modes:
| wValue | Action | Tests |
|---|---|---|
0x80 | No-op: return current state | Firmware responsive? |
0x81 | GPIO setup + power + delays (no I2C) | Power rails working? |
0x82 | GPIO + I2C bus reset + BCM4500 probe | I2C communication working? |
0x83 | GPIO + I2C probe + write init block 0 | Register writes accepted? |
Each mode returns a 3-byte response: config status, boot stage, and probe byte. The tool reports timing (ms) for each stage and checks if the device is still responsive after failures.
I2C Debugging Suite
Section titled “I2C Debugging Suite”Three scripts that implement a progressive isolation methodology to identify I2C bus faults. These were developed in sequence, each informed by the results of the previous one.
Methodology
Section titled “Methodology”- Broad scan (
test_i2c_debug.py) — Power on the BCM4500 and probe the entire I2C bus. Does the chip respond at any address? - Isolation (
test_i2c_isolate.py) — Determine whether the fault is in the BCM4500, the I2C bus, or the FX2 controller. Test the chip when already powered vs. after a reset. - Pinpoint (
test_i2c_pinpoint.py) — Identify the exact operation that corrupts communication. Compare I2C read-only, GPIO+reset, and GPIO+bus-reset+probe modes.
test_i2c_debug.py — Bus Discovery
Section titled “test_i2c_debug.py — Bus Discovery”Powers on the BCM4500 via GPIO-only mode (0x81), then runs progressively detailed diagnostics.
sudo python3 tools/test_i2c_debug.pyTest sequence:
| Step | Action | Purpose |
|---|---|---|
| 1 | Send mode 0x81 (GPIO power on) | Start BCM4500 without any I2C |
| 2 | I2C bus scan (0xB4) immediately | Check for devices right after power-on |
| 3 | Wait 500 ms, scan again | Maybe chip needs more time? |
| 4 | Raw I2C reads to candidate addresses | Try 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x11, 0x68, 0x69, 0x60, 0x61 |
| 5 | Check I2C controller state | Observe bus health |
| 6 | Send mode 0x82 after 1s delay | Test probe with extra settling time |
Candidate addresses cover different BCM4500 pin-strap configurations and common demodulator/tuner addresses.
test_i2c_isolate.py — Fault Isolation
Section titled “test_i2c_isolate.py — Fault Isolation”Determines whether the failure is caused by bcm_direct_read, re-reset timing, or the I2C bus reset (bmSTOP).
sudo python3 tools/test_i2c_isolate.pyTest sequence:
| Test | Action | Question |
|---|---|---|
| A | Power on (0x81), wait 1s, raw read | Is BCM4500 alive from cold start? |
| B | Run mode 0x82 (re-resets + probe) | Does bcm_direct_read work after reset? |
| C | Immediately raw read after 0x82 | Is I2C function itself broken? |
| D | Raw reads at 100, 200, 500, 1000, 2000 ms | Is it a timing issue? |
| E | Re-power (0x81), wait, then 0x82 | Repeatable? |
test_i2c_pinpoint.py — Root Cause Identification
Section titled “test_i2c_pinpoint.py — Root Cause Identification”The definitive test that identified the I2C STOP corruption bug. Compares three modes on a chip that is already proven alive.
sudo python3 tools/test_i2c_pinpoint.pyTest sequence:
- Power on BCM4500 via mode 0x81, confirm alive with raw read
- Mode 0x84:
bcm_direct_readonly (no GPIO, chip already powered) — tests if the read function itself is broken - Mode 0x85: GPIO + reset + power but NO I2C bus reset (no
bmSTOP) — tests if re-reset breaks things - Mode 0x82: GPIO + I2C
bmSTOP+ reset + power + probe — the mode that was failing
Interpretation:
| Result Pattern | Diagnosis |
|---|---|
| 0x84 works, 0x85 works, 0x82 fails | bmSTOP (I2C bus reset) is the culprit |
| 0x84 fails | bcm_direct_read has a bug |
| 0x85 fails | Re-reset timing needs more delay |
Windows Memory Dump (wine_memdump.py)
Section titled “Windows Memory Dump (wine_memdump.py)”Extracts firmware from the Genpix Windows driver/updater by running it under Wine and dumping process memory. The Windows updater executable contains embedded firmware images that are unpacked into memory at runtime.
sudo python3 tools/wine_memdump.py SkyWalkerUpdater.exesudo python3 tools/wine_memdump.py SkyWalkerUpdater.exe --skip-launchsudo python3 tools/wine_memdump.py SkyWalkerUpdater.exe -o dumps/ --wait 5Options
Section titled “Options”| Flag | Description |
|---|---|
EXE | Windows PE executable to run under Wine (positional, required) |
-o, --output-dir DIR | Output directory for dumps (default: .) |
--wait SECONDS | Seconds to wait after launch for unpacking (default: 3) |
--skip-launch | Attach to an already-running Wine process |
How It Works
Section titled “How It Works”- Launches the
.exeunder Wine withWINEDEBUG=-allto suppress noise - Waits for the process to unpack (configurable delay)
- Finds the Wine process PID by scanning
/proc - Reads
/proc/PID/mapsto identify readable memory regions - Reads each region from
/proc/PID/meminto a contiguous dump - Saves the full dump (
wine_memdump.bin) and region map (wine_memdump_regions.txt) - Searches the dump for firmware signatures
Firmware Signature Search
Section titled “Firmware Signature Search”The tool searches for 7 categories of signatures:
| Search | Pattern | Purpose |
|---|---|---|
| C2 EEPROM headers | C2 C0 09 03 02 | Find embedded firmware images |
| FX2 init sequence | 78 7F E4 F6 D8 FD 75 81 | FX2 RAM clear/init code |
| RAM clear pattern | 78 7F E4 F6 D8 FD | Partial match variant |
| C2 load records | LEN + addr 0x0000 + LJMP | Record chain starts |
| VID references | C0 09 near 03 02 | VID/PID byte pairs |
| Version strings | 2.13, SkyWalker, Genpix, 8PSK, etc. | Text markers |
| USB transfer setup | 0x40 0xA0, 0x40 0x83, 0x40 0x84 | WinUSB vendor request patterns |
Each hit is reported with the dump offset, virtual address, containing memory region, and context bytes.
Output Files
Section titled “Output Files”| File | Contents |
|---|---|
wine_memdump.bin | Full concatenated memory dump |
wine_memdump_regions.txt | Region map with virtual addresses, permissions, and dump offsets |
Diagnostic Command Reference
Section titled “Diagnostic Command Reference”The custom v3.01.0 firmware adds these diagnostic vendor commands used by the test scripts:
| Command | Code | Direction | Purpose |
|---|---|---|---|
I2C_BUS_SCAN | 0xB4 | IN | Probe all 128 I2C addresses, return 16-byte bitmap |
I2C_RAW_READ | 0xB5 | IN | Read from any I2C device (wValue=addr, wIndex=reg) |
I2C_DIAG | 0xB6 | IN | Step-by-step indirect register read with intermediate values |
RAW_DEMOD_READ | 0xB1 | IN | Read any BCM4500 indirect register |
RAW_DEMOD_WRITE | 0xB2 | OUT | Write any BCM4500 indirect register |
These commands are only available when running the custom firmware. Stock firmware will STALL on these command codes.
See Also
Section titled “See Also”- I2C STOP Corruption Bug — the bug these tools helped discover
- Boot Sequence — the initialization flow being tested
- Custom Firmware v3.01.0 — the firmware that enables debug modes
- I2C Bus Architecture — I2C protocol and controller details
- Firmware Loader — load custom firmware before running debug tools