skywalker-1/kernel-fw01-analysis.md
Ryan Malloy e4117421a1 Add GPIF streaming path and kernel firmware format analyses
GPIF streaming analysis (772 lines):
- IFCONFIG=0xEE: GPIF master mode, 48MHz async, BCM4500 data bus
- Fully hardware-managed path: BCM4500 -> GPIF -> EP2 FIFO -> USB bulk
- EP2FIFOCFG=0x0C (AUTOIN, 8-bit), FLOWSTATEA |= 0x09 (auto re-trigger)
- Byte-for-byte identical register config across all firmware versions
- ARM_TRANSFER (cmd 0x85) start/stop flow documented with disassembly

Kernel FW01 analysis (425 lines):
- FW01/FW02 files never existed in linux-firmware or any distribution
- SkyWalker-1 boots from onboard EEPROM, never needs host firmware
- DVB-USB binary hexline format documented (compact Intel HEX variant)
- C2 EEPROM format vs kernel hexline format comparison
- Binary comparison matrix for all 5 firmware dumps
- Anti-tampering string found in v2.13 at offset 0x1880
2026-02-11 12:18:09 -07:00

18 KiB

Genpix GP8PSK Kernel Firmware File Analysis

1. Firmware File Search Results

Standard Locations Checked

Path Result
/lib/firmware/dvb-usb-gp8psk-01.fw Not found
/lib/firmware/dvb-usb-gp8psk-02.fw Not found
/usr/lib/firmware/dvb-usb-gp8psk-01.fw Not found
/usr/lib/firmware/dvb-usb-gp8psk-02.fw Not found
/usr/share/firmware/ Directory does not exist
  • linux-firmware (v20260110-1) is installed but contains no gp8psk files
  • The /usr/lib/firmware/WHENCE manifest has no gp8psk entry
  • pacman -F dvb-usb-gp8psk-01.fw returns no results -- no Arch package provides it
  • pacman -Ss gp8psk finds nothing

linux-firmware Git Repository

The upstream linux-firmware repository at git.kernel.org was checked. The gp8psk firmware files have never been included in the linux-firmware collection. Other DVB-USB firmware files exist (dib0700, it9135, terratec-h5-drxk), but gp8psk is absent.

Kernel get_dvb_firmware Script

The kernel's scripts/get_dvb_firmware helper (which downloads firmware from various vendor sites) has no entry for gp8psk. The original firmware was presumably distributed by Genpix Electronics directly, likely packaged with their Windows BDA driver installer.

A full filesystem search (find / -name 'dvb-usb-gp8psk*') found only the compiled kernel module (.ko.zst), no .fw firmware files anywhere on the system.

Conclusion

Neither dvb-usb-gp8psk-01.fw nor dvb-usb-gp8psk-02.fw exist on this system or in any standard distribution channel. The gp8psk firmware was never open-sourced or contributed to linux-firmware.


2. Why SkyWalker-1 Works Without FW01/FW02

The Driver Device Table Tells the Story

From gp8psk.c (kernel source):

static struct dvb_usb_device_properties gp8psk_properties = {
    .usb_ctrl = CYPRESS_FX2,
    .firmware = "dvb-usb-gp8psk-01.fw",
    // ...
    .devices = {
        { .name = "Genpix 8PSK-to-USB2 Rev.1 DVB-S receiver",
          .cold_ids = { &gp8psk_usb_table[GENPIX_8PSK_REV_1_COLD], NULL },  // <-- HAS cold_ids
          .warm_ids = { &gp8psk_usb_table[GENPIX_8PSK_REV_1_WARM], NULL },
        },
        { .name = "Genpix 8PSK-to-USB2 Rev.2 DVB-S receiver",
          .cold_ids = { NULL },   // <-- NO cold_ids
          .warm_ids = { &gp8psk_usb_table[GENPIX_8PSK_REV_2], NULL },
        },
        { .name = "Genpix SkyWalker-1 DVB-S receiver",
          .cold_ids = { NULL },   // <-- NO cold_ids
          .warm_ids = { &gp8psk_usb_table[GENPIX_SKYWALKER_1], NULL },
        },
        // ...
    }
};

Only Rev.1 Cold (PID 0x0200) triggers firmware download. When cold_ids is NULL, the DVB-USB framework skips the firmware loading step entirely. The device is assumed to already be in "warm" state.

FW01 Loading Path

USB device enumeration
  |
  +-- DVB-USB framework matches USB IDs
  +-- Checks cold_ids vs warm_ids
  |     |
  |     +-- cold_ids match? -> dvb_usb_download_firmware()
  |     |     |                  -> request_firmware("dvb-usb-gp8psk-01.fw")
  |     |     |                  -> usb_cypress_load_firmware() [hexline parser]
  |     |     |                  -> Device re-enumerates with warm PID
  |     |     |
  |     +-- warm_ids match? -> Skip firmware, proceed to frontend attach
  |
  +-- SkyWalker-1 (PID 0x0203) -> warm_ids only -> NO FW01 NEEDED

FW02 Loading Path

From gp8psk_power_ctrl():

if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)  // Only for Rev.1!
    if (!(status & bm8pskFW_Loaded))
        if (gp8psk_load_bcm4500fw(d))
            return -EINVAL;

BCM4500 firmware loading (dvb-usb-gp8psk-02.fw) is only attempted for Rev.1 Warm devices (PID 0x0201). Rev.2 and SkyWalker devices have the BCM4500 firmware burned into ROM, so bm8pskFW_Loaded (bit 1 of GET_8PSK_CONFIG) is already set at boot.

Summary

Device PID Needs FW01? Needs FW02? Boot Source
Rev.1 Cold 0x0200 YES -- RAM (empty)
Rev.1 Warm 0x0201 No YES RAM (FW01 loaded)
Rev.2 0x0202 No No EEPROM
SkyWalker-1 0x0203 No No EEPROM
SkyWalker-2 0x0205 No No EEPROM
SkyWalker CW3K 0x0206 No No EEPROM

The SkyWalker-1 boots entirely from its onboard EEPROM. It never requests either firmware file from the host.


3. FW01 Expected Format: DVB-USB Binary Hexline

Format Specification

The DVB-USB framework's dvb_usb_get_hexline() parser reads a compact binary representation of Intel HEX records. This is NOT standard Intel HEX text (:10000000...), nor the kernel's ihex_binrec format from <linux/ihex.h>.

Record structure:

Offset  Size  Field
------  ----  -----
0       1     len       - Number of data bytes in this record
1       1     addr_lo   - Target address, low byte
2       1     addr_hi   - Target address, high byte
3       1     type      - Record type (0x00=data, 0x01=EOF, 0x04=extended addr)
4       len   data[]    - Payload bytes
4+len   1     chk       - Checksum byte

Total bytes per record: len + 5

The parser advances position by len + 5 each iteration. Type 0x04 records carry extended linear address bits in data[0] and data[1], allowing 32-bit addressing.

Loading Mechanism

usb_cypress_load_firmware() performs:

  1. Halt FX2 CPU: write 0x01 to CPUCS register (0xE600)
  2. For each hexline record: write data[0..len-1] to FX2 RAM at addr via 0xA0 vendor request
  3. Restart FX2 CPU: write 0x00 to CPUCS register (0xE600)

The 0xA0 vendor request is handled by the FX2's built-in boot ROM, which writes directly to program/data RAM regardless of whether user firmware is running.

Comparison with Other DVB-USB Firmware Files

Other firmware files installed on this system confirm the format:

File Size First Record
dvb-usb-dib0700-1.20.fw 33,768 bytes len=2, addr=0x0000, type=0x04 (ext addr)
dvb-usb-it9135-01.fw 8,128 bytes len=3, addr=0x0000, type=0x03
dvb-usb-it9135-02.fw 5,834 bytes len=3, addr=0x0000, type=0x03

4. Our Extracted Firmware Format: Cypress C2 EEPROM Boot

C2 Header Structure

All extracted firmware dumps are in Cypress C2 IIC second-stage boot format, as stored in the device's EEPROM. This format is read by the FX2's internal boot ROM on power-up.

C2 header (8 bytes):

Offset  Size  Field
------  ----  -----
0       1     marker    - Always 0xC2 (indicates external memory, large code model)
1       2     VID       - USB Vendor ID (little-endian) -> 0x09C0 (Genpix)
3       2     PID       - USB Product ID (little-endian)
5       2     DID       - Device ID (little-endian) -> 0x0000
7       1     config    - 0x40 (400kHz I2C bus speed)

Followed by code segments:

Offset  Size        Field
------  ----------  -----
0       2           seg_len   - Segment length (big-endian)
2       2           seg_addr  - Target RAM address (big-endian)
4       seg_len     data[]    - Code/data bytes

Terminated by:

0       2           0x8001    - High bit set signals terminator
2       2           entry     - Entry point address (big-endian) -> 0xE600 (CPUCS)

Decoded C2 Headers

File VID PID Segments Code Size Entry
skywalker1_eeprom.bin (v2.06) 0x09C0 0x0203 10 9,472 bytes 0xE600
sw1_v213_fw_1_c2.bin (v2.13.1) 0x09C0 0x0203 10 9,322 bytes 0xE600
sw1_v213_fw_2_c2.bin (v2.13.2) 0x09C0 0x0203 10 9,377 bytes 0xE600
sw1_v213_fw_3_c2.bin (v2.13.3) 0x09C0 0x0203 10 9,369 bytes 0xE600
rev2_v210_fw_1_c2.bin (Rev2 v2.10) 0x09C0 0x0202 9 8,843 bytes 0xE600

Note: The PID in the C2 header determines the USB Product ID that the FX2 enumerates with after booting. SkyWalker-1 variants all use PID 0x0203, while Rev.2 uses 0x0202.

C2 Segment Layout (All SkyWalker-1 Variants)

All SkyWalker-1 C2 files use uniform 1023-byte segments (except the last):

Segment  Address   Length   Notes
-------  -------   ------   -----
1        0x0000    1023     Contains 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 1023-byte segment size is the maximum the FX2 I2C EEPROM boot ROM reads per transaction (limited by internal buffer).


5. Format Incompatibility: C2 vs Kernel Hexline

The firmware as stored in EEPROM (C2 format) is structurally different from what the kernel expects (binary hexline format). They cannot be used interchangeably.

Property C2 (EEPROM) Hexline (Kernel FW01)
Header 8-byte C2 with VID/PID/DID None
Address encoding Big-endian 16-bit per segment Little-endian split (addr_lo, addr_hi) per record
Data chunking 1023-byte segments Typically 16-byte records
Record overhead 4 bytes per segment 5 bytes per record
Terminator 0x80xx + entry point Type 0x01 EOF record
Entry point Explicit in terminator Implicit (CPUCS at 0xE600)

However, the payload data is identical. The "flat" extracted firmware (C2 segments concatenated, headers stripped) contains the same 8051 machine code that a hexline-format FW01 would carry. The difference is purely container format.

Theoretical Conversion: C2 -> Hexline

A C2 file can be converted to the kernel's hexline format by:

  1. Strip the 8-byte C2 header
  2. For each segment: emit 16-byte hexline records with type=0x00, splitting the segment data
  3. Append an EOF record (len=0, type=0x01)

The resulting file would be the equivalent of dvb-usb-gp8psk-01.fw for that firmware version. For the v2.06 EEPROM (9,472 code bytes), this produces approximately 12,442 bytes in hexline format.


6. FW02 (BCM4500 Demodulator Firmware) Analysis

Loading Protocol

From the kernel source (gp8psk_load_bcm4500fw()), FW02 uses a custom chunk protocol sent via USB bulk endpoint:

Chunk format:
  Byte 0:     payload_length (N)
  Bytes 1-3:  header/address bytes (3 bytes)
  Bytes 4..N+3: payload data

  Total chunk size = ptr[0] + 4 = payload_length + 4
  Maximum chunk size: 64 bytes (USB control transfer limit)

Terminator: single byte 0xFF

The loading sequence:

  1. Send LOAD_BCM4500 command (0x88, wValue=1) to initiate transfer mode
  2. Iterate through chunks until 0xFF terminator
  3. Each chunk is sent via dvb_usb_generic_write() (bulk endpoint 0x01)

Relevance to SkyWalker-1

FW02 is irrelevant for SkyWalker-1. The BCM4500 demodulator firmware is burned into ROM on all Rev.2 and later hardware. The kernel driver explicitly checks:

if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM)  // 0x0201 only

On the SkyWalker-1 (PID 0x0203), command 0x88 (LOAD_BCM4500) routes to the STALL handler in the FX2 firmware -- confirmed by Ghidra disassembly of all extracted firmware versions.


7. Firmware Version Identification

Kernel dmesg Output

gp8psk: FW Version = 2.06.4 (0x20604)  Build 2007/07/13
gp8psk: usb in 149 operation failed.
gp8psk: failed to get FPGA version
gp8psk_fe: Frontend attached
gp8psk: found Genpix USB device pID = 203 (hex)

The version is read via USB command GET_FW_VERS (0x92), which returns 6 bytes: [minor, build, major, day, month, year-2000]. The FX2 firmware computes and returns this at runtime from internal constants -- the version bytes are not stored as a simple searchable pattern in the binary.

Kernel Firmware Revision Constants

From gp8psk-fe.h:

#define GP8PSK_FW_REV1    0x020604    // v2.06.4
#define GP8PSK_FW_REV2    0x020704    // v2.07.4

The kernel only knows about two firmware revisions. Our v2.10 and v2.13 firmwares are significantly newer and unknown to the kernel.

FPGA Version Failure

gp8psk: usb in 149 operation failed.
gp8psk: failed to get FPGA version

Command 0x95 (GET_FPGA_VERS, decimal 149) fails on the SkyWalker-1. This command likely targets a separate FPGA that exists only on certain hardware revisions, or the SkyWalker-1 firmware does not implement this vendor command. The driver logs the failure but continues normally.

Version Strings in Firmware

No human-readable version strings were found in the v2.06 or Rev2 v2.10 firmware binaries. The v2.13.x variants contain a single notable string:

Offset 0x1880 (all three v2.13 sub-variants):
"Tampering is detected. Attempt is logged. Warranty is voided ! \n"

Followed by bytes 01 10 aa 82 02 41 41 83 -- likely I2C register write commands related to the tampering detection/logging mechanism. This string is absent from v2.06 and v2.10 firmware, indicating Genpix added anti-tampering measures in the v2.13 firmware generation.


8. Binary Comparison: Extracted Firmware Dumps

File Sizes

File Size Format
skywalker1_eeprom_flat.bin (v2.06.4) 9,472 bytes Flat binary
sw1_v213_fw_1_flat.bin (v2.13.1) 9,322 bytes Flat binary
sw1_v213_fw_2_flat.bin (v2.13.2) 9,377 bytes Flat binary
sw1_v213_fw_3_flat.bin (v2.13.3) 9,369 bytes Flat binary
rev2_v210_fw_1_flat.bin (Rev2 v2.10.4) 8,843 bytes Flat binary

Byte-Level Similarity Matrix

Percentage of matching bytes within the shared length of each pair:

v2.06 v2.13.1 v2.13.2 v2.13.3 Rev2 v2.10
v2.06 -- 4.8% 4.3% 4.3% 6.0%
v2.13.1 -- 57.2% 59.4% 8.0%
v2.13.2 -- 83.5% 5.8%
v2.13.3 -- 5.8%
Rev2 v2.10 --

Differing Byte Counts

Pair Different Bytes Shared Length Mismatch Rate
v2.06 vs v2.13.1 8,878 9,322 95.2%
v2.06 vs Rev2 v2.10 8,312 8,843 94.0%
v2.13.1 vs Rev2 v2.10 8,133 8,843 92.0%
v2.13.1 vs v2.13.2 3,994 9,322 42.8%
v2.13.2 vs v2.13.3 1,549 9,369 16.5%

Longest Identical Run

Pair Longest Match Starting Offset
v2.06 vs v2.13.1 22 bytes 0x0055
v2.06 vs Rev2 v2.10 36 bytes 0x080C

Interpretation

The very low byte-level similarity between different major versions (v2.06 vs v2.10 vs v2.13) indicates complete recompilation with different toolchains or linker configurations. Functions are relocated to different addresses even when their logic is identical. The first byte of every flat dump already differs (the second byte of the reset vector LJMP target), confirming different code layout starting from the entry point.

Within the v2.13 family, FW2 and FW3 share 83.5% of bytes, reflecting minor hardware-specific changes (parallel bus timing, GPIO defaults, IRAM layout). FW1 differs more substantially (57-59% match) because it targets fundamentally different hardware (I2C vs parallel bus demodulator interface).


9. Other Extracted Files

FX2 Internal ROM (skywalker1_fx2_internal.bin, 8,192 bytes)

The FX2 internal ROM dump does not contain program code in a recognizable 8051 format. It appears to be the FX2's built-in boot ROM (mask ROM), which handles:

  • USB enumeration in "unconfigured" state
  • I2C EEPROM boot loading (reading C2 format images)
  • 0xA0 vendor request handling (RAM write for host firmware upload)

This ROM is identical across all Cypress CY7C68013A chips and is not Genpix-specific.

FX2 External Memory (skywalker1_fx2_external.bin, 65,536 bytes)

A 64KB dump of the FX2's full external address space. The first ~9.5KB contains the same code as skywalker1_eeprom_flat.bin; the remainder is the full 64KB memory space including RAM, SFR shadows, and unused regions.


10. Summary of Findings

  1. Firmware files dvb-usb-gp8psk-01.fw and dvb-usb-gp8psk-02.fw do not exist on this system, in linux-firmware, or in any standard distribution. They were never open-sourced.

  2. SkyWalker-1 does not need either file. The kernel driver only requests FW01 for Rev.1 Cold devices (PID 0x0200) and FW02 for Rev.1 Warm devices (PID 0x0201). The SkyWalker-1 boots from its onboard EEPROM and appears directly as a "warm" device (PID 0x0203).

  3. FW01 format would be DVB-USB binary hexline records (a compact binary encoding of Intel HEX), loaded via Cypress FX2 0xA0 vendor requests to CPUCS. Our extracted dumps are in Cypress C2 EEPROM boot format -- different container, identical payload.

  4. FW02 format is a custom Genpix chunk protocol (length byte + 3 header bytes + data, terminated by 0xFF), loaded via USB bulk transfers after a LOAD_BCM4500 command (0x88). This is only relevant for Rev.1 hardware.

  5. The currently running firmware is v2.06.4 (build 2007/07/13), matching the kernel's GP8PSK_FW_REV1 constant (0x020604). This is the original factory firmware burned into the SkyWalker-1 EEPROM.

  6. The v2.13 firmware (extracted from the Windows updater) adds anti-tampering detection and supports three different hardware sub-variants. The v2.10 Rev.2 firmware is for a different product (PID 0x0202).


Sources

  • Linux kernel 6.16.5 source: drivers/media/usb/dvb-usb/gp8psk.c, gp8psk.h
  • Linux kernel 6.16.5 source: drivers/media/dvb-frontends/gp8psk-fe.h
  • Linux kernel 6.16.5 source: drivers/media/usb/dvb-usb/dvb-usb-firmware.c
  • Linux kernel 6.16.5 source: include/linux/ihex.h
  • Firmware dumps: /home/rpm/claude/ham/satellite/genpix/skywalker-1/firmware-dump/
  • dmesg output from running SkyWalker-1 hardware
  • linux-firmware git repository (https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git)