Running Stock FreeBSD on Windows Subsystem for Linux 2

Friday 09:45 - 10:35

Title: Running Stock FreeBSD on Windows Subsystem for Linux 2

Abstract:

This talk demonstrates running unmodified FreeBSD on Microsoft's Windows Subsystem for Linux version 2 (WSL2). While WSL2 is historically Linux-centric, its underlying VM architecture is built on the Host Compute Service (HCS), which is BSD-friendly. I demonstrate a "stock-only" approach that requires zero kernel modifications. I'll explore how the early-boot "silent console" issue was solved and the high-performance interactive terminal leveraging FreeBSD's excellent hvsock implementation. Finally, I'll discuss the ongoing work to bridge FreeBSD with the Guest Networking Service (GNS). Attendees will learn FreeBSD's architectural maturity and its adaptability to modern Windows virtualization infrastructure

Full Description:

WSL2 Integration Components - The Big Picture:

To make FreeBSD work in WSL2, six core integration points must be addressed:

  1. Virtualization Layer: How the VM is orchestrated and managed

  2. Guest Handshake Protocol: The startup communication WSL2 expects from guests

  3. Boot Console: Getting visibility into early kernel boot messages

  4. Interactive Terminal: The high-performance console users actually interact with

  5. Guest Networking: Network configuration and connectivity to the host/internet

  6. File System Integration: Host filesystem integration using 9P protocol

Each of these components presents unique challenges. Linux WSL2 distributions handle them through custom kernels, specialized init (mini_init) systems, and mounting userland separately. My approach was different: make stock FreeBSD work by building minimal userland bridges.

Component 1: Virtualization Layer – FreeBSD & HCS Seamless integration

WSL2 does not use traditional Hyper-V management interfaces; it orchestrates "Utility VMs" through the Host Compute Service (HCS) API. HCS provides a generic VM lifecycle and resource description mechanism. This talk breaks down how I followed FreeBSD specific approach to orchestrate the guest directly through HCS APIs.

The key discovery: By leveraging HCS's native support for full disk images, I bypass the host-provided Linux kernel and specialized initrd (mini_init) entirely. This proves that the unmodified FreeBSD base system is robust enough to handle this environment without patches or custom builds. The virtualization layer doesn't impose Linux-only restrictions—it just needed the right configuration.

Component 2: FreeBSD Handshake with WSL2

When WSL2 launches a VM, it expects a specific handshake sequence over Hyper-V Sockets (hvsock). Linux guests used custom Microsoft developed mini_init to handle this. For FreeBSD, I developed hvinit—a small utility that runs on userspace to handle this startup protocol. It listens on the expected hvsock port, receives initialization messages containing system status and process parameters, and sends back the acknowledgments WSL2 requires. Without this handshake, WSL2 won't complete VM startup.

Component 3: Boot Console challenge

A significant early hurdle: Linux guests typically use virtio-console for early-boot messages, but FreeBSD lacks virtio-console support during early boot. This caused the system to appear completely hung with no output.

I solved this by configuring HCS to route FreeBSD's early boot through Serial I/O instead. FreeBSD has robust serial console support, so this immediately gave visibility into the complete boot sequence—kernel messages, rc scripts, everything. This demonstrates FreeBSD's flexibility: the same boot process that works on physical hardware adapts cleanly to virtualization with serial console without modification.

Component 4: Interactive Terminal - The FreeBSD hvsock Console

WSL2's actual high-performance console is entirely different from boot console—it's implemented over Hyper-V Sockets (hvsock), not virtio or serial. This is where FreeBSD's excellent hvsock implementation shines.

I developed hvbridge to connect FreeBSD's standard PTY system to WSL2's hvsock-based console expectations. It runs in userland and creates a pseudo-terminal using forkpty(), spawns /bin/sh, then implements a bidirectional relay using select() to forward data between the PTY master and the hvsock file descriptors WSL2 provides for stdin/stdout/stderr.

The result: a responsive, low-latency terminal experience identical to Linux WSL2 instances. What's notable here is FreeBSD's clean separation between terminal handling and I/O transport. The same PTY infrastructure that works everywhere else works here.

Component 5: Guest Networking Service - The Current Frontier

WSL2 manages network configuration via the Host Compute Network (HCN) API. I'm currently researching implementing the Guest Networking Service (GNS) expected by WSL2 for FreeBSD—a userland daemon that negotiates network state with the Windows host. I will discuss this architecture as well.

Component 6: Host File System Integration

WSL2 also uses the Plan9 filesystem protocol (9P) to expose Windows directories inside the guest, which remains future work for FreeBSD integration.

Source Code: https://github.com/BalajeS/WSL-For-FreeBSD

Demo: https://x.com/balajesankar/status/1970585411153207715?s=20