Files
appsandbox/tools/linux/agent/Makefile
T
James Stringer 2309cec029 Add Linux VM support with GPU-PV
Ubuntu 26.04 LTS guest end-to-end:

- cidata-driven autoinstall pipeline (subiquity user-data + nested
  cloud-init bootcmd) in disk_util.c. Static NAT IP, ssh-via-vsock
  marker, serial-debug kernel cmdline injected into ESP grub.cfg by
  iso-patch.exe. Five separate firstboot pipeline fixes get the VM
  to GDM unattended on Hyper-V Gen 2.

- Linux guest stack under tools/linux/:
    - appsandbox-agent  (vsock :1 control + clipboard helper spawn)
    - appsandbox-audio  (snd-aloop -> vsock :4)
    - appsandbox-display (KMS framebuffer capture -> vsock :2)
    - appsandbox-input  (uinput injection <- vsock :3)
    - appsandbox-clipboard (XCB selection bridge <-> vsock :5/:6)
  Helper binaries staged via release/resources/linux/.

- asb_drm DRM module: virtual single-CRTC display sink the host
  captures over vsock. Platform-bus, DRIVER_GEM/MODESET/ATOMIC/RENDER,
  linear shmem framebuffers. asb-evict-simpledrm.service unbinds the
  EFI simple-framebuffer before display-manager so mutter binds
  asb_drm as the sole DRM card.

- dxgkrnl vendored byte-identical from microsoft/WSL2-Linux-Kernel
  linux-msft-wsl-6.18.y with our DKMS/out-of-tree shim (dxgkrnl_compat.h
  + Kbuild + dkms.conf). Autoinstall late-commands dkms-builds against
  every /target/lib/modules/<kver> so kernel-version drift between ISO
  and post-update reboot still leaves a working .ko.

- wsl-mesa custom build (Mesa 25.3 + d3d12 gallium + microsoft-
  experimental dzn Vulkan). Installs to /opt/wsl-mesa parallel to
  Ubuntu's stock Mesa. Prebuilt tarball for ubuntu-26.04-amd64
  shipped under tools/linux/wsl-mesa/prebuilt/ (21 MB).

- Per-VM GPU acceleration policy:
    - /etc/systemd/user-environment-generators/50-appsandbox-gpu
      emits GALLIUM_DRIVER=d3d12 + LD_LIBRARY_PATH + VK_DRIVER_FILES
      into the user@1000 systemd-user environment when /dev/dxg and
      /opt/wsl-mesa are present. Inherited by every app-*.scope a
      .desktop launch creates.
    - /etc/systemd/user/org.gnome.Shell@.service.d/no-gpu.conf
      UnsetEnvironment= strips these for the compositor — mutter
      stays on llvmpipe so asb_drm scanout works (the d3d12 pipe has
      no GBM compatibility with asb_drm).
    - /usr/local/bin/appsandbox-gpu wrapper for terminal-launched
      opt-in GPU acceleration (probes /dev/dxg; no-op on no-GPU VMs).

- Host changes:
    - vm_display_idd.c, vm_clipboard.c, vm_agent.c, vm_ssh_proxy.c,
      asb_display.c: hcs_service_guid(os_type, port) so the same code
      paths reach the per-OS service identifiers (HV_GUID for Windows,
      vsock template for Linux).
    - asb_core.c: linux_create_thread builds an empty VHDX, cidata
      ISO with extras (agent ELFs, dxgkrnl src, asb_drm src, wsl-mesa
      tarball, wsl-deps libs), and boots the desktop ISO + cidata.
    - hcs_vm.c: HostLxssLib Plan9 share appended for Linux VMs;
      VideoMonitor + ComPorts retained for serial debug.
    - gpu_enum.c/h: gpu_append_lxsslib_share helper.
    - vm_clipboard.c file-drop support (CF_HDROP / x-special/gnome-
      copied-files round-trip).
    - vm_display_idd.c: 32-bit S32_LE PCM audio path matches the
      Linux daemon's snd-aloop capture format.

- iso-patch.c gains a patch_ubuntu_esp_grub_for_debug pass that
  rewrites /EFI/ubuntu/grub.cfg via the FAT32 ESP, plus a qcow2->
  vhdx converter with a RFC 1951 DEFLATE inflater for compressed
  cluster handling.

- wsl-deps: Microsoft's libd3d12.so / libd3d12core.so / libdxcore.so
  fetched on demand from the public NuGet feed
  pkgs.dev.azure.com/shine-oss/wsl (no auth). Staged at
  /opt/appsandbox/wsl-deps on the guest and put on /etc/ld.so.conf.d
  rather than /usr/lib/wsl/lib (which is overlaid by the agent's
  9P mount).

UI: web/{app.js,index.html} expose Linux VM creation + GPU selection,
distribution dropdown for cached Ubuntu ISOs, and the ISO picker for
custom images.
2026-05-19 20:21:43 -04:00

81 lines
2.7 KiB
Makefile

# App Sandbox Linux guest daemons — builds the in-VM binaries that match
# the wire protocol the Windows host stack expects. See
# docs/linux-idd-implementation-plan.md for architecture.
CC ?= gcc
CFLAGS ?= -O2 -Wall -Wextra -pthread -D_GNU_SOURCE
LDFLAGS ?=
PREFIX ?= /usr/local
DESTDIR ?=
BINDIR := $(PREFIX)/bin
SYSTEMDDIR := /etc/systemd/system
USERUNITDIR := /etc/systemd/user
# Daemons get added here as each phase lands.
BINS := appsandbox-agent appsandbox-display appsandbox-input appsandbox-audio appsandbox-clipboard
SYSTEM_UNITS := systemd/appsandbox-agent.service \
systemd/appsandbox-display.service \
systemd/appsandbox-input.service \
systemd/appsandbox-audio.service
# No clipboard systemd unit — the agent owns the clipboard helper's
# lifecycle (spawn_clipboard_helper in appsandbox-agent.c). Same
# pattern as the Windows agent which spawns clipboard.exe /
# clipboard-reader.exe.
USER_UNITS :=
all: $(BINS)
appsandbox-agent: appsandbox-agent.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
# Display daemon needs libdrm for drmModeGetFB2 + drmPrimeHandleToFD.
appsandbox-display: appsandbox-display.c
$(CC) $(CFLAGS) $(shell pkg-config --cflags libdrm) -o $@ $< \
$(LDFLAGS) $(shell pkg-config --libs libdrm)
appsandbox-input: appsandbox-input.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
# Audio daemon uses libasound to talk to the kernel snd-aloop driver.
appsandbox-audio: appsandbox-audio.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -lasound
# Clipboard daemon: XCB (with XFIXES) for X11 selection ownership,
# libc iconv for text format conversion. libpng would be added when
# we wire the DIB ↔ PNG path; today CF_DIB → image/bmp is header-munge.
appsandbox-clipboard: appsandbox-clipboard.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) -lxcb -lxcb-xfixes
install: $(BINS)
install -d $(DESTDIR)$(BINDIR)
install -m 0755 $(BINS) $(DESTDIR)$(BINDIR)/
install -d $(DESTDIR)$(SYSTEMDDIR)
for u in $(SYSTEM_UNITS); do \
install -m 0644 $$u $(DESTDIR)$(SYSTEMDDIR)/; \
done
@if [ -n "$(USER_UNITS)" ]; then \
install -d $(DESTDIR)$(USERUNITDIR); \
for u in $(USER_UNITS); do \
install -m 0644 $$u $(DESTDIR)$(USERUNITDIR)/; \
done; \
fi
# Convenience: install + enable all units in one shot. Requires root.
enable: install
systemctl daemon-reload
systemctl enable --now appsandbox-agent.service
systemctl enable --now appsandbox-display.service
systemctl enable --now appsandbox-input.service
disable:
-systemctl disable --now appsandbox-input.service
-systemctl disable --now appsandbox-display.service
-systemctl disable --now appsandbox-agent.service
clean:
rm -f $(BINS)
.PHONY: all install enable disable clean