mirror of
https://github.com/jamesstringer90/appsandbox.git
synced 2026-10-22 02:52:49 -05:00
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.
121 lines
4.9 KiB
Markdown
121 lines
4.9 KiB
Markdown
# tools/linux — Linux-side build of AppSandbox guest components
|
|
|
|
Everything in this tree compiles on a Linux box and produces artifacts that
|
|
the Windows AppSandbox host needs in order to stage a Linux VM. The
|
|
components:
|
|
|
|
| Subdir | What it builds | Where it ends up in the guest |
|
|
|--------------|-----------------------------------------|------------------------------------------------------------|
|
|
| `agent/` | 5 userspace daemons (ELF) | `/usr/local/bin/appsandbox-{agent,audio,clipboard,display,input}` |
|
|
| `dxgkrnl/` | Hyper-V GPU paravirt kernel module | `/lib/modules/<kver>/updates/dxgkrnl.ko` (or DKMS) |
|
|
| `asb_drm/` | Stub DRM driver for KMS capture | `/lib/modules/<kver>/updates/asb_drm.ko` (or DKMS) |
|
|
| `wsl-mesa/` | (optional) Mesa with d3d12 + dzn | tarball extracted to `/opt/wsl-mesa/` |
|
|
|
|
`wsl-deps/` (Microsoft's proprietary `libd3d12.so` etc.) is **not** built
|
|
here — it's fetched by the Windows host from Microsoft's public NuGet feed
|
|
into `C:\ProgramData\AppSandbox\wsl-deps\`. See `tools/wsl-deps/README.md`.
|
|
|
|
## Build
|
|
|
|
Prereqs (Ubuntu 26.04+; package names may differ on other distros):
|
|
|
|
```bash
|
|
sudo apt-get install -y \
|
|
build-essential dkms zstd \
|
|
linux-headers-$(uname -r) \
|
|
libdrm-dev libasound2-dev libxcb1-dev libxcb-xfixes0-dev
|
|
```
|
|
|
|
Then from this directory:
|
|
|
|
```bash
|
|
make
|
|
```
|
|
|
|
That builds the 5 daemons, both kernel modules against your running kernel,
|
|
and installs them under `tools/linux/dist/`:
|
|
|
|
```
|
|
tools/linux/dist/
|
|
├── appsandbox-agent ← strip'd ELF
|
|
├── appsandbox-audio
|
|
├── appsandbox-clipboard
|
|
├── appsandbox-display
|
|
├── appsandbox-input
|
|
└── modules/
|
|
└── <uname-r>/
|
|
├── dxgkrnl.ko
|
|
└── asb_drm.ko
|
|
```
|
|
|
|
`dist/` is gitignored — it's only valid on this machine for this kernel.
|
|
|
|
Other targets:
|
|
|
|
| Target | What it does |
|
|
|-----------------|-----------------------------------------------------------|
|
|
| `make compile` | builds in place but doesn't copy to `dist/` |
|
|
| `make agents` | builds only the userspace daemons |
|
|
| `make modules` | builds only the kernel modules |
|
|
| `make clean` | removes `*.o`, `*.ko`, daemon ELFs from source dirs |
|
|
| `make distclean`| `clean` + removes `dist/` |
|
|
|
|
## Transfer to the Windows host
|
|
|
|
This step is **manual on purpose** — there's no assumption of network
|
|
connectivity between your Linux build box and the Windows machine that
|
|
runs AppSandbox.
|
|
|
|
After a successful build, get `dist/`'s contents over to your Windows host
|
|
and place them at:
|
|
|
|
```
|
|
<appsandbox-repo>\release\resources\linux\
|
|
```
|
|
|
|
The simplest approach is a tarball:
|
|
|
|
```bash
|
|
tar -C dist -czf ~/asb-linux.tar.gz .
|
|
```
|
|
|
|
Then transfer `asb-linux.tar.gz` to the Windows host by whatever means you
|
|
normally use to move files between these two systems (USB stick, shared
|
|
filesystem, file-share VM, scp, manual upload — whatever works for your
|
|
setup). On the Windows side, in your appsandbox checkout:
|
|
|
|
```cmd
|
|
mkdir release\resources\linux
|
|
tar xzf C:\path\to\asb-linux.tar.gz -C release\resources\linux\
|
|
```
|
|
|
|
`tar.exe` ships with Windows 10+; if it isn't on your PATH the Git for
|
|
Windows / 7-Zip / WinRAR equivalents all handle `.tar.gz` fine.
|
|
|
|
## How the staged files reach a running VM
|
|
|
|
1. `release/resources/linux/` is a committed staging dir on the Windows
|
|
side — same model as the existing `release/resources/appsandbox-*.exe`
|
|
files used for Windows guests.
|
|
2. `AppSandbox.vcxproj`'s PostBuildEvent xcopies `release/resources/` into
|
|
`bin/<cfg>/resources/` next to `AppSandbox.exe` and `AppSandboxCore.dll`.
|
|
That happens on every build, so a rebuild after copying the new files
|
|
makes them runtime-visible.
|
|
3. When you create a Linux VM, `disk_util.c::iso_create_resources_ubuntu`
|
|
builds a `cidata.iso` with `user-data` (autoinstall) + an `extras/` tree
|
|
that includes everything from `<exe_dir>/resources/linux/`.
|
|
4. On first boot of the VM, autoinstall mounts the cidata ISO, copies
|
|
`extras/` into `/opt/appsandbox/`, then runs `setup.sh` via
|
|
`curtin in-target`. `setup.sh` installs the agent ELFs into
|
|
`/usr/local/bin/`, the kernel modules into `/lib/modules/<kver>/updates/`,
|
|
wires up systemd units, and enables them.
|
|
|
|
## Kernel module version skew
|
|
|
|
Kernel modules built here only load against an **identical** kernel version
|
|
in the guest (`uname -r` must match exactly). If the guest is on a different
|
|
kernel from your build machine, `setup.sh` automatically falls back to the
|
|
DKMS build path — it copies the source from `extras/dxgkrnl/src/` to
|
|
`/usr/src/dxgkrnl-<ver>/` and runs `dkms install`. DKMS handles future
|
|
kernel upgrades automatically. The committed `.ko` is just a fast path.
|