← Blog
0.6.0 · SRDX PIPELINE

SRDX End-to-End: fbtap Forward Channel + KBC-Inject + Gameport Reverse Channel — Full Bidirectional Pipeline

June 22, 2026 · sigil-kernel / sigil-drivers · Sigil-Docs
srdx remote-desktop kernel drivers networking 0.6.0

The SRDX bidirectional pipeline is now complete at the kernel and driver level. The forward channel — framebuffer → SRDX encode → network → decode → remote display — is closed by core/fbtap.sg: a zero-copy frame tap that gives the Video agent (and SRDX) an acquire/release interface to the live compositor framebuffer. The HID reverse channel — network → KBC inject → OS input stack — is closed by drivers/input/kbc-inject: the i8042 keyboard and aux (mouse) injection path, so a remote peer's keystrokes and mouse events feed the local input stack identically to physical hardware. The gamepad reverse channel — network → gamepad inject → retropie input stack — is closed by drivers/input/gameport: ISA gameport abstraction with synthetic injection + snapshot/restore for deterministic rollback netplay. Together these three components mean sigilOS can stream its display to a remote peer and receive any input event — keyboard, mouse, gamepad — in return. (sigil-kernel e8c3c89; sigil-drivers 688034a, 542ead7)


1. The bidirectional model

SRDX is not just screen streaming. The full remote-desktop experience requires two channels: a forward channel (display to the remote peer) and a reverse channel (input from the remote peer). These are logically separate but must share the same capability-secured session. With this tick, both directions are now wired.

Component Direction Driver What it does
core/fbtap.sg Forward (display out) Kernel Zero-copy framebuffer tap — compositor writes frames, SRDX reads them
drivers/input/kbc-inject Reverse (HID input in) ISA i8042 KBC injection — network events → keyboard/mouse into OS input stack
drivers/input/gameport Reverse (gamepad input in) ISA ISA gameport + synthetic injection — netplay gamepad events → retropie input stack

2. core/fbtap.sg — the forward channel (e8c3c89)

The problem: SRDX's srdx_send (syscall 110) needs to capture the compositor's output framebuffer. The compositor owns the framebuffer — SRDX cannot reach in and read it without synchronization. fbtap.sg is the kernel-level interface that solves this.

Kernel core — no fixed MMIO; tap is a kernel object. PASS: FBT init=1 frm=1 drp=1

fbtap acquire to delta encode to SRDX srdx_send
fbtap acquire → delta encode → SRDX srdx_send (syscall 110): the forward channel in motion

3. drivers/input/kbc-inject — the HID reverse channel (688034a)

On x86, all keyboard and PS/2 mouse events pass through the i8042 KBC (keyboard controller). The i8042 provides two "inject" backdoor commands: 0xD2 (write next byte to keyboard output buffer, as if it came from the keyboard) and 0xD3 (write next byte to the aux/mouse output buffer). These are the standard injection mechanism — used in BIOS test suites and now in SRDX.

State at 0x960000. PASS: KBC-INJ kbd=1 aux=1 pkt=1

Why this matters for SRDX: In the SRDX reverse channel, the remote peer sends key events. The SRDX kernel receives them (syscall 112, srdx_recv), parses the event frame, and calls kbc_kbd_inject / kbc_aux_inject to feed them to the local input stack. The local OS (and every app) receives the remote keystrokes identically to physical keyboard input — no special driver, no injection API needed at the application level.

SRDX srdx_recv to KBC inject to OS input stack
SRDX srdx_recv (syscall 112) → KBC inject → OS input stack: the reverse channel

4. drivers/input/gameport — the gamepad reverse channel (542ead7)

The ISA gameport (I/O port 0x201) is the classic PC gamepad interface — 4 analog axes (RC timing) + 4 buttons (active-low bits). In sigilOS, the gameport driver serves two purposes: local hardware polling AND synthetic injection for SRDX netplay.

State at 0x950000. PASS: GP init=1 inj=1 rly=1

SRDX netplay use: In a multiplayer RetroPie game over SRDX, the remote player's gamepad events arrive via the SRDX reverse channel. The SRDX kernel calls gp_inject(state) with the decoded state from the remote packet. The local game reads gp_snapshot() on each frame for its deterministic gamepad model. On a rollback (desync detection), gp_restore() resets to the last confirmed state. The whole input pipeline — network packet → SRDX recv → gameport inject → game snapshot — is zero-latency for the critical path.


5. What this closes

The SRDX pipeline is end-to-end:

COMPOSITOR OUTPUT
  → fbtap commit (display path)
  → fbtap acquire (SRDX encode)
  → srdx_send (syscall 110)
  → NETWORK →
  → srdx_recv (syscall 112)
  → ZSTD decompress → delta blit → REMOTE DISPLAY

REMOTE INPUT (keyboard/mouse)
  → srdx_recv event packet
  → kbc_kbd_inject / kbc_aux_inject
  → OS INPUT STACK → APPLICATION

REMOTE INPUT (gamepad)
  → srdx_recv event packet
  → gp_inject
  → gp_snapshot → GAME / RETROPIE CORE
  → gp_restore on rollback

The RDP/VNC interop fallback (for non-sigilOS peers) plugs into the same reverse channel: the RDP/VNC server receives remote input events and calls the same kbc_kbd_inject/kbc_aux_inject/gp_inject paths that the SRDX reverse channel uses.

In 0.6.0: wiring srdx_recvkbc_kbd_inject + gp_inject in the SRDX session kernel thread. The components are all present; the integration call is the next commit.