Skip to content
Draft
49 changes: 49 additions & 0 deletions mkosi.profiles/surface/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Surface Profile

Builds ParticleOS for Microsoft Surface Pro and Surface Laptop devices on
standard x86-64 UEFI firmware (no custom bootloader required).

## What it adds

| Layer | Details |
|---|---|
| Kernel | Replaces the stock distro kernel with the linux-surface patched kernel (touch / Type Cover / pen / camera fixes) |
| Touch daemon | iptsd - processes IPTS touch/pen frames from the firmware |
| Firmware | SOF audio firmware, Intel WiFi firmware, Surface-specific libwacom database |
| Power | Deep sleep preference, lid-state fix, PSR disabled (prevents flicker) |
| Type Cover | udev wakeup rule so suspend/resume works with the keyboard |

## Build

```sh
# Fedora base (recommended - best Surface kernel COPR coverage)
mkosi --profile obs-repos --profile desktop --profile gnome --profile surface build

# Debian base
mkosi --distribution debian --profile desktop --profile gnome --profile surface build
```

## Installing on a Surface

1. Boot the generated disk image from USB (or write it directly to the NVMe).
2. Secure Boot: either enroll the ParticleOS certificate in the Surface UEFI,
or disable Secure Boot temporarily in **Surface UEFI -> Security -> Secure Boot**.
3. The image uses **systemd-boot** as the EFI bootloader - it registers itself
with the UEFI boot manager automatically; no manual EFI entry needed.
4. First boot runs `preset-global` to enable all default services.

## Supported models

Tested targets (linux-surface patch coverage):

- Surface Pro 7, 7+, 8, 9, 10
- Surface Laptop 3, 4, 5, 6
- Surface Go 2, 3
- Surface Pro X (ARM - not covered by this x86 profile)

## Known limitations

- **Camera**: MIPI cameras on Pro 9/10 and Laptop 5/6 are not fully supported
in mainline yet; frames may be unavailable until IPU6 support lands.
- **Secure Boot**: custom key enrollment into Surface UEFI is possible but not
automated by this profile yet.
29 changes: 29 additions & 0 deletions mkosi.profiles/surface/mkosi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Surface profile - Microsoft Surface Pro / Surface Laptop (standard UEFI x86-64)
# Activate with: mkosi --profile surface

[Content]
Packages=
iptsd
libwacom
thermald
iw
intel-media-driver
libva-intel-driver
alsa-firmware
sof-firmware
powertop

# Disable Panel Self Refresh (fixes screen flicker on many Surface models)
# Enable deep sleep where supported; fall back to s2idle
# Fix lid detection on some models
KernelCommandLine=
i915.enable_psr=0
mem_sleep_default=deep
button.lid_init_state=open
acpi_backlight=native

# DRM modules needed for Surface display pipeline
KernelInitrdModules=/drivers/gpu/drm
/drivers/hid/hid-multitouch.ko
/drivers/hid/hid-generic.ko
18 changes: 18 additions & 0 deletions mkosi.profiles/surface/mkosi.conf.d/arch/mkosi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Arch surface config - linux-surface from the linux-surface pacman repo

[Content]
Repositories=
id:linux-surface
url:https://pkg.surfacelinux.com/arch/linux-surface.repo

Packages=
linux-surface
linux-surface-headers
iptsd
libwacom
surface-control

RemovePackages=
linux
linux-headers
22 changes: 22 additions & 0 deletions mkosi.profiles/surface/mkosi.conf.d/debian/mkosi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Debian surface config - uses the linux-surface apt repo for the patched kernel

[Content]
Repositories=
id:linux-surface
url:https://pkg.surfacelinux.com/debian/linux-surface.list
Architectures:amd64
SignedBy=/usr/share/keyrings/linux-surface.gpg

Packages=
linux-image-surface
linux-headers-surface
iptsd
libwacom
firmware-iwlwifi
firmware-intel-sound

# Drop the generic kernel in favour of the surface one
RemovePackages=
linux-image-amd64
linux-image-generic
22 changes: 22 additions & 0 deletions mkosi.profiles/surface/mkosi.conf.d/fedora/mkosi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Fedora surface config - pulls in the linux-surface kernel and iptsd from COPR

[Content]
Repositories=
id:linux-surface
url:https://pkg.surfacelinux.com/fedora/linux-surface.repo

Packages=
kernel-surface
iptsd
libwacom-surface
surface-control

# The surface kernel replaces the stock kernel; remove the base one to avoid
# having two boot entries on the ESP.
RemovePackages=
kernel
kernel-core
kernel-modules
kernel-modules-core
kernel-modules-extra
9 changes: 9 additions & 0 deletions mkosi.profiles/surface/mkosi.extra/etc/iptsd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# iptsd configuration for Surface touchscreen / pen daemon
# See: https://github.com/linux-surface/iptsd

[Touch]
DisableOnStylus = false

[Stylus]
DisableTouch = false
12 changes: 12 additions & 0 deletions mkosi.profiles/surface/mkosi.extra/usr/lib/modprobe.d/surface.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Kernel module options tuned for Microsoft Surface hardware

# Reduce USB polling latency for the Type Cover keyboard/trackpad
options usbhid mousepoll=1

# Enable ACPI platform profile support (for surface-control performance modes)
options platform_profile enabled=1

# Disable PC speaker (no hardware speaker on Surface)
blacklist pcspkr
blacklist snd_pcsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Prefer S3 (deep) sleep on Surface; fall back to s2idle if unavailable
[Sleep]
SuspendState=mem standby freeze
HibernateMode=shutdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Enable wakeup from suspend via the Surface Type Cover
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="045e", ATTR{power/wakeup}=="disabled", ATTR{power/wakeup}="enabled"