Skip to content

Latest commit

 

History

History
554 lines (444 loc) · 24.9 KB

File metadata and controls

554 lines (444 loc) · 24.9 KB

Windows Subsystem for Linux (WSL) Architecture Tutorial

A comprehensive guide to understanding WSL's architecture, networking, file sharing, terminal usage, and VS Code integration.


Table of Contents

  1. WSL Architecture Overview
  2. Networking Between Host and Linux
  3. File Sharing Between Windows and Linux
  4. Effective Terminal Usage
  5. VS Code Remote Architecture

WSL Architecture Overview

WSL 1 vs WSL 2

WSL has two versions with fundamentally different architectures:

WSL 1 Architecture

┌─────────────────────────────────────────────┐
│              Windows NT Kernel              │
├─────────────────────────────────────────────┤
│     Linux System Call Translation Layer     │
│        (lxss.sys / lxcore.sys)              │
├─────────────────────────────────────────────┤
│           Linux User Space                  │
│    (Ubuntu, Debian, etc. distributions)     │
└─────────────────────────────────────────────┘
  • Translation Layer: Linux system calls are translated to Windows NT kernel calls in real-time
  • No real Linux kernel: Uses a compatibility layer
  • Pros: Fast file system access to Windows files
  • Cons: Incomplete syscall support, slower Linux operations

WSL 2 Architecture

┌─────────────────────────────────────────────────────────┐
│                    Windows Host                         │
├─────────────────────────────────────────────────────────┤
│              Hyper-V Hypervisor                         │
├────────────────────────┬────────────────────────────────┤
│    Windows NT Kernel   │   Lightweight Utility VM       │
│                        │  ┌──────────────────────────┐  │
│                        │  │   Real Linux Kernel      │  │
│                        │  ├──────────────────────────┤  │
│                        │  │   Linux User Space       │  │
│                        │  │   (ext4 filesystem)      │  │
│                        │  └──────────────────────────┘  │
└────────────────────────┴────────────────────────────────┘
  • Real Linux Kernel: Runs an actual Linux kernel in a lightweight VM
  • Hyper-V: Uses virtualization (but highly optimized)
  • Pros: Full syscall compatibility, faster Linux file operations
  • Cons: Slower cross-filesystem access

Key Components

Component Description
wsl.exe Main CLI tool to manage WSL
wslhost.exe Handles communication between Windows and WSL
init WSL's init system (manages services in the VM)
9P Protocol Server Enables file sharing between Windows and Linux

Networking Between Host and Linux

WSL 2 Network Architecture

WSL 2 runs in a VM with its own virtual network adapter, creating a NAT (Network Address Translation) setup:

┌─────────────────────────────────────────────────────────────┐
│                      Physical Network                        │
│                    (Your Router/Internet)                    │
└───────────────────────────┬─────────────────────────────────┘
                            │
┌───────────────────────────▼─────────────────────────────────┐
│                   Windows Host                               │
│           IP: 192.168.1.x (from your router)                │
│  ┌─────────────────────────────────────────────────────┐    │
│  │              Virtual NAT Network                     │    │
│  │              (vEthernet WSL)                         │    │
│  │              Subnet: 172.x.x.x                       │    │
│  │  ┌───────────────────────────────────────────────┐  │    │
│  │  │              WSL 2 VM                          │  │    │
│  │  │          IP: 172.x.x.x (dynamic)              │  │    │
│  │  │                                                │  │    │
│  │  │   eth0 ◄──── Virtual Network Adapter          │  │    │
│  │  └───────────────────────────────────────────────┘  │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

IP Address Behavior

# Get WSL's IP address (from inside WSL)
ip addr show eth0 | grep inet

# Get Windows host IP (from inside WSL)
cat /etc/resolv.conf | grep nameserver

# The nameserver IP is your Windows host IP

Accessing Services

From Windows → WSL

# WSL services on localhost are automatically forwarded
# A server running on WSL port 3000 is accessible at:
# http://localhost:3000 (from Windows browser)

From WSL → Windows

# Get the Windows host IP
WIN_HOST=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')

# Access Windows service (e.g., SQL Server on port 1433)
curl http://$WIN_HOST:1433

From External Network → WSL

# Port forwarding required (run in PowerShell as Admin)
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=$(wsl hostname -I)

WSL 2 Mirrored Networking Mode (Windows 11 22H2+)

Enable in %USERPROFILE%\.wslconfig:

[wsl2]
networkingMode=mirrored

With mirrored mode:

  • WSL shares the same IP as Windows
  • No NAT translation needed
  • Localhost works seamlessly in both directions
  • IPv6 support included

File Sharing Between Windows and Linux

Architecture of the 9P Protocol File Server

┌─────────────────────────────────────────────────────────────┐
│                        Windows                               │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                 9P Protocol Server                   │    │
│  │              (Running in Windows)                    │    │
│  │    Exposes: C:\, D:\, etc. as /mnt/c, /mnt/d        │    │
│  └──────────────────────────┬──────────────────────────┘    │
│                             │ 9P Protocol                    │
│  ┌──────────────────────────▼──────────────────────────┐    │
│  │                    WSL 2 VM                          │    │
│  │  ┌────────────────────────────────────────────────┐ │    │
│  │  │              9P Client (in kernel)              │ │    │
│  │  │         Mounts Windows drives at /mnt/*        │ │    │
│  │  └────────────────────────────────────────────────┘ │    │
│  │  ┌────────────────────────────────────────────────┐ │    │
│  │  │              Native ext4 Filesystem            │ │    │
│  │  │              (Linux home, /usr, etc.)          │ │    │
│  │  └────────────────────────────────────────────────┘ │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

File System Paths

Location Windows Path Linux Path
Windows C: drive C:\Users\you /mnt/c/Users/you
Windows D: drive D:\Projects /mnt/d/Projects
WSL Linux home \\wsl$\Ubuntu\home\you ~ or /home/you
WSL root \\wsl$\Ubuntu\ /

Performance Considerations

Performance Comparison (relative speeds):

Linux files from Linux:     ████████████████████ 100%
Windows files from Windows: ████████████████████ 100%
Linux files from Windows:   ████████████░░░░░░░░  60%
Windows files from Linux:   ████████░░░░░░░░░░░░  40%  ← Slowest!

Best Practices:

  • Store project files in the Linux filesystem (~/projects/)
  • Clone git repos inside WSL, not in /mnt/c/
  • Use Windows filesystem only for files that need Windows apps

Mounting Options

Configure in /etc/wsl.conf:

[automount]
enabled = true
root = /mnt/
options = "metadata,umask=22,fmask=11"
mountFsTab = true

[interop]
enabled = true
appendWindowsPath = true

Effective Terminal Usage

Essential WSL Commands

# List installed distributions
wsl --list --verbose
wsl -l -v

# Set default distribution
wsl --set-default Ubuntu

# Start specific distribution
wsl -d Ubuntu

# Run a single command
wsl ls -la /home

# Shutdown all WSL instances
wsl --shutdown

# Terminate specific distribution
wsl --terminate Ubuntu

# Export/Import distributions
wsl --export Ubuntu ubuntu-backup.tar
wsl --import Ubuntu-Copy C:\WSL\Ubuntu-Copy ubuntu-backup.tar

# Update WSL
wsl --update

# Check WSL version
wsl --version

Windows Terminal Integration

Windows Terminal automatically detects WSL distributions. Configure in settings.json:

{
    "profiles": {
        "list": [
            {
                "name": "Ubuntu",
                "source": "Windows.Terminal.Wsl",
                "startingDirectory": "//wsl$/Ubuntu/home/username",
                "colorScheme": "One Half Dark",
                "fontFace": "CaskaydiaCove Nerd Font"
            }
        ]
    }
}

Interoperability Commands

# Run Windows commands from Linux
explorer.exe .                    # Open current folder in Explorer
notepad.exe myfile.txt           # Open file in Notepad
cmd.exe /c dir                   # Run CMD command
powershell.exe Get-Process       # Run PowerShell command

# Pipe between Windows and Linux
cat /etc/passwd | clip.exe       # Copy to Windows clipboard
powershell.exe Get-Date | grep 2024  # Pipe Windows output to Linux

# Open files with default Windows app
wslview document.pdf             # Requires wslu package

Environment Configuration

~/.bashrc or ~/.zshrc:

# Useful aliases
alias explorer='explorer.exe .'
alias clip='clip.exe'
alias open='wslview'

# Access Windows environment variables
export WIN_HOME=$(wslpath "$(cmd.exe /c 'echo %USERPROFILE%' 2>/dev/null | tr -d '\r')")

# Add Windows paths selectively (instead of all)
export PATH="$PATH:/mnt/c/Program Files/Microsoft VS Code/bin"

SSH Agent Sharing

Share Windows SSH agent with WSL using npiperelay:

# In ~/.bashrc
export SSH_AUTH_SOCK=$HOME/.ssh/agent.sock
ss -a | grep -q $SSH_AUTH_SOCK
if [ $? -ne 0 ]; then
    rm -f $SSH_AUTH_SOCK
    setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork &
fi

VS Code Remote Architecture

How VS Code Remote - WSL Works

VS Code uses a client-server architecture for WSL development:

┌─────────────────────────────────────────────────────────────────────────┐
│                           Windows Host                                   │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │                    VS Code Desktop (Client)                        │  │
│  │  ┌─────────────────┐  ┌─────────────────┐  ┌──────────────────┐   │  │
│  │  │   UI Renderer   │  │  Extension Host │  │  Terminal Client │   │  │
│  │  │   (Electron)    │  │   (Windows)     │  │                  │   │  │
│  │  └────────┬────────┘  └────────┬────────┘  └────────┬─────────┘   │  │
│  │           │                    │                    │             │  │
│  └───────────┼────────────────────┼────────────────────┼─────────────┘  │
│              │         WebSocket / stdin/stdout        │                │
│              │         Communication Channel           │                │
│  ┌───────────▼────────────────────▼────────────────────▼─────────────┐  │
│  │                         WSL 2 VM                                   │  │
│  │  ┌─────────────────────────────────────────────────────────────┐  │  │
│  │  │                   VS Code Server                             │  │  │
│  │  │           (~/.vscode-server/bin/<commit-id>/)               │  │  │
│  │  │  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐  │  │  │
│  │  │  │  Extension Host │  │  File Watcher   │  │  Language   │  │  │  │
│  │  │  │  (Linux exts)   │  │  (Linux FS)     │  │  Servers    │  │  │  │
│  │  │  └─────────────────┘  └─────────────────┘  └─────────────┘  │  │  │
│  │  │  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐  │  │  │
│  │  │  │  Terminal       │  │  Debugger       │  │  Git        │  │  │  │
│  │  │  │  (bash/zsh)     │  │  (gdb/lldb)     │  │  (native)   │  │  │  │
│  │  │  └─────────────────┘  └─────────────────┘  └─────────────┘  │  │  │
│  │  └─────────────────────────────────────────────────────────────┘  │  │
│  │                                                                    │  │
│  │           Project Files: /home/user/projects/myapp                │  │
│  └────────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────┘

Component Breakdown

1. VS Code Client (Windows)

  • UI Renderer: Electron-based GUI running on Windows
  • Local Extension Host: Runs UI-only extensions (themes, keymaps)
  • Communication Layer: WebSocket connection to VS Code Server

2. VS Code Server (WSL)

  • Location: ~/.vscode-server/bin/<version>/
  • Remote Extension Host: Runs workspace extensions (Python, ESLint, etc.)
  • File System Access: Direct ext4 access (fast!)
  • Process Management: Debuggers, terminals, tasks run natively

Extension Architecture

Extensions are split based on where they need to run:

┌─────────────────────────────────────────────────────────────┐
│                    Extension Types                           │
├─────────────────────────────┬───────────────────────────────┤
│     UI Extensions           │    Workspace Extensions        │
│     (Run on Windows)        │    (Run in WSL)               │
├─────────────────────────────┼───────────────────────────────┤
│ • Themes                    │ • Language Servers            │
│ • Icon packs                │ • Linters (ESLint, Pylint)    │
│ • Keymaps                   │ • Formatters (Prettier)       │
│ • UI customizations         │ • Debuggers                   │
│                             │ • Git extensions              │
│                             │ • Build tools                 │
└─────────────────────────────┴───────────────────────────────┘

Opening Projects in WSL

# From Windows Terminal/PowerShell
code --remote wsl+Ubuntu /home/user/project

# From inside WSL terminal
cd ~/project
code .

# Opening specific file
code --remote wsl+Ubuntu /home/user/project/main.py

VS Code Settings for WSL

User settings.json:

{
    "remote.WSL.fileWatcher.polling": false,
    "remote.WSL.debug": false,
    
    "terminal.integrated.defaultProfile.linux": "bash",
    "terminal.integrated.profiles.linux": {
        "bash": {
            "path": "/bin/bash",
            "icon": "terminal-bash"
        },
        "zsh": {
            "path": "/usr/bin/zsh"
        }
    },

    "files.watcherExclude": {
        "**/node_modules/**": true,
        "**/.git/objects/**": true
    }
}

Performance Optimization

  1. Store projects in Linux filesystem

    # Good ✓
    ~/projects/myapp
    
    # Bad ✗ (slow!)
    /mnt/c/Users/you/projects/myapp
  2. Exclude heavy folders from file watching

    {
        "files.watcherExclude": {
            "**/node_modules/**": true,
            "**/vendor/**": true,
            "**/.git/objects/**": true,
            "**/dist/**": true
        }
    }
  3. Install extensions in WSL

    • Click "Install in WSL" when prompted
    • Check installed location: Extensions sidebar shows "WSL: Ubuntu" tag

Debugging Architecture

┌──────────────────────────────────────────────────────────────┐
│                     VS Code Client                            │
│  ┌──────────────────────────────────────────────────────┐    │
│  │              Debug Adapter Protocol (DAP)             │    │
│  │                     Client                            │    │
│  └────────────────────────┬─────────────────────────────┘    │
│                           │ JSON-RPC over WebSocket          │
├───────────────────────────┼──────────────────────────────────┤
│                     WSL 2 VM                                  │
│  ┌────────────────────────▼─────────────────────────────┐    │
│  │                  Debug Adapter                        │    │
│  │          (e.g., debugpy, node-debug2)                │    │
│  └────────────────────────┬─────────────────────────────┘    │
│                           │                                   │
│  ┌────────────────────────▼─────────────────────────────┐    │
│  │               Target Application                      │    │
│  │        (Python script, Node.js app, etc.)            │    │
│  └──────────────────────────────────────────────────────┘    │
└──────────────────────────────────────────────────────────────┘

launch.json example:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File",
            "type": "debugpy",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        }
    ]
}

Quick Reference

Common Tasks Cheat Sheet

Task Command
Enter WSL wsl
Enter specific distro wsl -d Ubuntu
Run single command wsl ls -la
Open folder in VS Code code . (from WSL)
Shutdown WSL wsl --shutdown
Check WSL status wsl -l -v
Access Windows files cd /mnt/c/Users/
Access WSL files from Windows \\wsl$\Ubuntu\home\
Open Explorer here explorer.exe .
Copy to clipboard `cat file

Troubleshooting

# Reset WSL networking
wsl --shutdown
# Then restart WSL

# Check WSL version
wsl --version

# Verify WSL 2 is being used
wsl -l -v
# Should show VERSION 2

# View WSL logs
dmesg | tail -50

# Check mounted drives
mount | grep drvfs

Additional Resources