Firmware Storage Formats
The SkyWalker-1 firmware exists in multiple container formats depending on context: the onboard EEPROM uses the Cypress C2 IIC boot format, the Linux kernel expects a custom binary hexline format, and analysis tools work with flat extracted binaries.
Format Overview
Section titled “Format Overview”Cypress C2 IIC Second-Stage Boot Format Device Storage
Section titled “Cypress C2 IIC Second-Stage Boot Format ”This is the native format stored in the SkyWalker-1’s onboard I2C EEPROM. The FX2’s internal boot ROM reads this format on power-up.
The 0xC2 marker byte in the header identifies this as “external memory, large code model” — it tells the boot ROM to load code from the EEPROM into internal RAM using the segment map that follows.
Kernel Binary Hexline Format Linux Driver
Section titled “Kernel Binary Hexline Format ”Used only by dvb-usb-gp8psk-01.fw for Rev.1 Cold devices. This is a compact binary representation of Intel HEX records parsed by dvb_usb_get_hexline() in the kernel. It is NOT standard Intel HEX text.
Flat Extracted Binary Analysis
Section titled “Flat Extracted Binary ”Raw 8051 machine code extracted from C2 segments. No headers or framing — just code bytes at their target RAM addresses. Used for Ghidra analysis and binary diffing.
C2 EEPROM Format
Section titled “C2 EEPROM Format”Header Structure (8 bytes)
Section titled “Header Structure (8 bytes)”Offset Size Field Value (SkyWalker-1)------ ---- ---------- -------------------0x00 1 marker 0xC2 (external memory, large code model)0x01 2 VID 0xC009 -> 0x09C0 (little-endian, Genpix)0x03 2 PID 0x0302 -> 0x0203 (little-endian, SkyWalker-1)0x05 2 DID 0x0000 (device ID, unused)0x07 1 config 0x40 (400 kHz I2C bus speed)The VID and PID in the C2 header determine the USB identifiers that the FX2 enumerates with after boot. This is how the kernel driver identifies the device model.
Config Byte (offset 0x07)
Section titled “Config Byte (offset 0x07)”| Value | I2C Speed | Notes |
|---|---|---|
0x00 | 100 kHz | Default if EEPROM missing |
0x20 | 200 kHz | |
0x40 | 400 kHz | Used by SkyWalker-1 |
Code Segment Structure
Section titled “Code Segment Structure”Following the 8-byte header, one or more code segments:
Offset Size Field------ ---------- -----0 2 seg_len (big-endian) -- number of data bytes2 2 seg_addr (big-endian) -- target RAM address4 seg_len data[] -- code/data bytesSegments are packed contiguously. The 1023-byte maximum segment size is the limit of the FX2 boot ROM’s internal I2C read buffer.
Terminator
Section titled “Terminator”Offset Size Field------ ---- -----0 2 0x8001 -- high bit set signals terminator (length with MSB set)2 2 entry -- entry point address (big-endian) = 0xE600 (CPUCS)Writing to CPUCS (0xE600) with value 0x00 releases the CPU from reset and begins execution at the reset vector (0x0000).
Decoded C2 Files
Section titled “Decoded C2 Files”Header Comparison
Section titled “Header Comparison”| File | VID | PID | DID | I2C Speed | Code Size |
|---|---|---|---|---|---|
skywalker1_eeprom.bin (v2.06) | 0x09C0 | 0x0203 | 0x0000 | 400 kHz | 9,472 bytes |
sw1_v213_fw_1_c2.bin (v2.13.1) | 0x09C0 | 0x0203 | 0x0000 | 400 kHz | 9,322 bytes |
sw1_v213_fw_2_c2.bin (v2.13.2) | 0x09C0 | 0x0203 | 0x0000 | 400 kHz | 9,377 bytes |
sw1_v213_fw_3_c2.bin (v2.13.3) | 0x09C0 | 0x0203 | 0x0000 | 400 kHz | 9,369 bytes |
rev2_v210_fw_1_c2.bin (Rev.2) | 0x09C0 | 0x0202 | 0x0000 | 400 kHz | 8,843 bytes |
Segment Layout (SkyWalker-1 Variants)
Section titled “Segment Layout (SkyWalker-1 Variants)”All SkyWalker-1 C2 files use uniform 1023-byte segments (except the last):
| Segment | Address | Length | Notes |
|---|---|---|---|
| 1 | 0x0000 | 1023 | Reset vector, interrupt handlers |
| 2 | 0x03FF | 1023 | |
| 3 | 0x07FE | 1023 | |
| 4 | 0x0BFD | 1023 | |
| 5 | 0x0FFC | 1023 | |
| 6 | 0x13FB | 1023 | |
| 7 | 0x17FA | 1023 | |
| 8 | 0x1BF9 | 1023 | |
| 9 | 0x1FF8 | 1023 | |
| 10 | 0x23F7 | varies | 115—265 bytes depending on version |
The address of each segment is exactly previous_addr + 1023, creating a contiguous mapping from 0x0000 to the end of the firmware image.
Rev.2 Segment Layout
Section titled “Rev.2 Segment Layout”Rev.2 has only 9 segments (one fewer than SkyWalker-1 variants) because its firmware is smaller:
| Segment | Address | Length |
|---|---|---|
| 1 | 0x0000 | 1023 |
| 2 | 0x03FF | 1023 |
| 3 | 0x07FE | 1023 |
| 4 | 0x0BFD | 1023 |
| 5 | 0x0FFC | 1023 |
| 6 | 0x13FB | 1023 |
| 7 | 0x17FA | 1023 |
| 8 | 0x1BF9 | 1023 |
| 9 | 0x1FF8 | 659 |
Kernel Binary Hexline Format
Section titled “Kernel Binary Hexline Format”This format is used exclusively by dvb-usb-gp8psk-01.fw for loading firmware into Rev.1 Cold devices (PID 0x0200). The SkyWalker-1 never uses this format at runtime.
Record Structure
Section titled “Record Structure”Offset Size Field------ ---- -----0 1 len Number of data bytes in this record1 1 addr_lo Target address, low byte2 1 addr_hi Target address, high byte3 1 type Record type4 len data[] Payload bytes4+len 1 chk Checksum byte
Total per record: len + 5 bytesRecord Types
Section titled “Record Types”| Type | Name | Purpose |
|---|---|---|
0x00 | Data | Write data bytes to FX2 RAM at address (addr_hi * 256 + addr_lo) |
0x01 | EOF | End of file, no more records |
0x04 | Extended Linear Address | data[0]:data[1] = upper 16 bits of target address |
Comparison With Other DVB-USB Firmware
Section titled “Comparison With Other DVB-USB Firmware”Files from other DVB-USB devices confirm the format:
| File | Size | First Record |
|---|---|---|
dvb-usb-dib0700-1.20.fw | 33,768 | len=2, addr=0x0000, type=0x04 |
dvb-usb-it9135-01.fw | 8,128 | len=3, addr=0x0000, type=0x03 |
dvb-usb-it9135-02.fw | 5,834 | len=3, addr=0x0000, type=0x03 |
64K Full EEPROM Dump
Section titled “64K Full EEPROM Dump”The complete EEPROM can be dumped as a 65,536-byte raw image. The firmware occupies the first ~10 KB; the remainder contains:
| Offset Range | Content |
|---|---|
0x0000—0x0007 | C2 header (8 bytes) |
0x0008—0x25xx | Code segments (varies by version) |
0x25xx—0x26xx | C2 terminator |
0x2700—0x3FFF | Padding / unused (typically 0xFF) |
0x4000—0x7FFF | Mirror/unused (some EEPROMs wrap at 32K) |
Format Conversion
Section titled “Format Conversion”C2 to Flat Binary
Section titled “C2 to Flat Binary”Extract raw code from a C2 file by stripping headers:
def c2_to_flat(c2_data): """Extract flat binary from C2 EEPROM format.""" pos = 8 # Skip 8-byte C2 header flat = bytearray(0x10000) # 64K address space
while pos < len(c2_data): seg_len = (c2_data[pos] << 8) | c2_data[pos + 1] seg_addr = (c2_data[pos + 2] << 8) | c2_data[pos + 3] pos += 4
if seg_len & 0x8000: # Terminator (high bit set) break
flat[seg_addr:seg_addr + seg_len] = c2_data[pos:pos + seg_len] pos += seg_len
return flatC2 to Kernel Hexline
Section titled “C2 to Kernel Hexline”Theoretical conversion for producing a dvb-usb-gp8psk-01.fw equivalent:
def c2_to_hexline(c2_data): """Convert C2 EEPROM format to kernel binary hexline.""" records = bytearray() flat = c2_to_flat(c2_data) code_end = find_code_end(flat)
for addr in range(0, code_end, 16): chunk = flat[addr:addr + 16] rec_len = len(chunk) addr_lo = addr & 0xFF addr_hi = (addr >> 8) & 0xFF rec_type = 0x00 # Data record chk = (rec_len + addr_lo + addr_hi + rec_type + sum(chunk)) & 0xFF records.extend([rec_len, addr_lo, addr_hi, rec_type]) records.extend(chunk) records.append((~chk + 1) & 0xFF)
# EOF record records.extend([0x00, 0x00, 0x00, 0x01, 0xFF]) return recordsFor the v2.06 firmware (9,472 code bytes), this produces approximately 12,442 bytes in hexline format.
File Identification
Section titled “File Identification”Quick format identification by examining the first byte:
| First Byte | Format | Notes |
|---|---|---|
0xC2 | C2 EEPROM | Standard SkyWalker-1 EEPROM dump |
0xC0 | C0 EEPROM | VID/PID-only header (no code segments) |
0x02 | Flat binary | Likely starts with LJMP instruction (0x02 xx xx) |
| Other | Hexline or unknown | Check record structure |