Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
4e9f390
surface-arm64: add main arm64 profile (Snapdragon X Elite)
corning-croak-cable May 9, 2026
cf0ea0a
surface-arm64: add fedora arm64 distro config (upstream kernel, Qualc…
corning-croak-cable May 9, 2026
ef97121
surface-arm64: add debian arm64 distro config (unstable, upstream ker…
corning-croak-cable May 9, 2026
710c3ec
surface-arm64: add modprobe config (tpm_crb, qrtr tuning)
corning-croak-cable May 9, 2026
42489f4
surface-arm64: add qrtr-ns service for Qualcomm IPC routing
corning-croak-cable May 9, 2026
2d38648
surface-arm64: add pd-mapper service
corning-croak-cable May 9, 2026
9b104cb
surface-arm64: add firstboot Secure Boot enrollment service
corning-croak-cable May 9, 2026
6205ee8
surface-arm64: add Secure Boot enrollment script (NX Mode workaround)
corning-croak-cable May 9, 2026
f6d848a
surface-arm64: add preset enabling Qualcomm and enrollment services
corning-croak-cable May 9, 2026
2946867
surface-arm64: add sleep config (s2idle/freeze only - no S3 on Snapdr…
corning-croak-cable May 9, 2026
5fe036d
surface-arm64: add ADR for design decisions
corning-croak-cable May 9, 2026
626746f
surface-arm64: add README
corning-croak-cable May 9, 2026
bb1f34e
ci: add surface-arm64 mkosi profile validation workflow (2026/)
foil-copy-overrate May 11, 2026
2b34df1
feat(surface-arm64-audio): add LPASS/Q6DSP audio packages to mkosi pr…
foil-copy-overrate May 11, 2026
0a3441d
feat(surface-arm64-audio): add snd_soc_sc8280xp + Q6ASM modprobe options
foil-copy-overrate May 11, 2026
3e039e7
feat(surface-arm64-audio): add WirePlumber Q6DSP routing policy
foil-copy-overrate May 11, 2026
e3c686d
Delete 2026 directory
foil-copy-overrate May 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions mkosi.profiles/surface-arm64/ADR.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ADR: Surface ARM64 Snapdragon X Elite - Design Decisions

## 1. Upstream kernel (no linux-surface)
x1e80100 DTBs (romulus13/15) merged upstream since 6.12.
linux-surface provides no aarch64 packages.
Trade-off: camera (MIPI/IPU6) and full audio non-functional until upstreamed.
Source: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom

## 2. SignExpectedPcr=no
Qualcomm fTPM unavailable during initrd phase -> PCR measurement hang.
Disk encryption works without PCR binding; policy just less boot-state-tied.
Source: linux-surface/linux-surface#1590, community testing.

## 3. sbctl firstboot, no MokManager
Surface NX Mode freezes MokManager at UEFI logo.
ParticleOS UKI + systemd-boot never touches shim/MokManager.
sbctl generates keys on firstboot; PK exported for direct UEFI db enrollment.
Source: https://github.com/linux-surface/linux-surface/issues/1590

## 4. s2idle only (SuspendState=freeze)
Snapdragon X Elite PSCI/ACPI exposes only s2idle on Linux; S3 unavailable.
Trade-off: higher suspend battery drain than Windows.
39 changes: 39 additions & 0 deletions mkosi.profiles/surface-arm64/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Surface ARM64 - Snapdragon X Elite (Surface Laptop 7)

ParticleOS profile for Surface Laptop 7 (x1e80100, arm64).
Design priorities: bootable images first, TPM enrollment quirks resolved, upstream kernel only.
See ADR.md for full rationale.

## Hardware status (kernel 6.15+)

| Component | Status | Notes |
|---|---|---|
| Boot (systemd-boot + UKI) | Works | Direct UEFI, no shim |
| CPU (Oryon 12-core) | Works | Full cpufreq |
| NVMe (PCIe Gen 4) | Works | |
| Display (eDP 120Hz) | Works | Freedreno/DRM |
| WiFi (WCN785x/ath12k) | Works | Needs linux-firmware blobs |
| USB-A / USB-C | Works | USB4/TB limited |
| Suspend (s2idle) | Works | No S3; higher drain |
| TPM2 disk encryption | Works | No PCR binding (fTPM quirk) |
| Secure Boot | Manual setup | See below |
| Audio | Partial | Windows firmware blobs needed |
| Camera | Not working | IPU6/MIPI unmerged |
| Touchscreen | Not working | HID-over-SPI unmerged |

## Build

mkosi --profile obs-repos --profile desktop --profile gnome --profile surface-arm64 build

Cross-building from x86-64: requires qemu-user-static + binfmt-misc.

## Secure Boot enrollment

1. Disable Secure Boot in Surface UEFI (Volume Up + Power -> Security).
2. Boot ParticleOS. surface-sb-enroll.service runs on first boot.
3. cat /var/lib/surface-sb-enroll/ENROLL_SECURE_BOOT.md
4. Enroll ParticleOS-PK.cer in Surface UEFI.
5. Re-enable Secure Boot.

MokManager never used. Surface NX Mode freezes it.
Ref: https://github.com/linux-surface/linux-surface/issues/1590
45 changes: 45 additions & 0 deletions mkosi.profiles/surface-arm64/mkosi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Surface Laptop 7 / Snapdragon X Elite (arm64) profile
# Activate with: mkosi --profile surface-arm64
#
# TPM/Secure Boot design notes:
# - SignExpectedPcr=no: Qualcomm fTPM unavailable during initrd PCR measurements.
# Disabling avoids boot-time hang. Source: linux-surface/issues/1590
# - NX Mode quirk: Surface UEFI NX Mode breaks MokManager. Profile uses
# UKI + systemd-boot (no shim). Enrollment via sbctl + direct UEFI db.
# - Upstream kernel only - bootability over full hardware support.

[Match]
Profile=surface-arm64

[Distribution]
Architecture=arm64

[Validation]
# Inherit SecureBoot=yes from root; override PCR signing (Qualcomm fTPM quirk).
SignExpectedPcr=no

[Content]
Packages=
qrtr
pd-mapper
linux-firmware
tpm2-tools
tpm2-tss
sbctl
efivar
efitools

# Snapdragon X Elite kernel command line
# clk_ignore_unused/pd_ignore_unused prevent clock/power-domain framework from
# disabling unattached clocks during init - critical on Qualcomm bringup.
# Source: Linaro Snapdragon X Elite bring-up documentation
KernelCommandLine=
clk_ignore_unused
pd_ignore_unused

# DRM, HID, and TPM CRB modules needed in initrd
KernelInitrdModules=/drivers/gpu/drm
/drivers/hid/hid-multitouch.ko
/drivers/hid/hid-generic.ko
/drivers/tpm/tpm_crb.ko
15 changes: 15 additions & 0 deletions mkosi.profiles/surface-arm64/mkosi.conf.d/audio.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Surface Laptop 7 audio DSP additions for Snapdragon X Elite
# Extends the base surface-arm64 profile.

[Match]
Profile=surface-arm64

[Content]
# Qualcomm LPASS/Q6DSP audio stack
Packages=
alsa-utils
alsa-ucm-conf
pipewire
wireplumber
pipewire-pulseaudio
20 changes: 20 additions & 0 deletions mkosi.profiles/surface-arm64/mkosi.conf.d/debian/mkosi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Debian ARM64 for Snapdragon X Elite.
# Requires debian unstable for kernel >= 6.12 (x1e80100 DTB support).

[Match]
Distribution=debian
Architecture=arm64

[Distribution]
Release=unstable

[Content]
Packages=
linux-image-arm64
linux-headers-arm64
firmware-qcom-soc
firmware-linux-nonfree
tpm2-tools
tpm2-abrmd
sbctl
17 changes: 17 additions & 0 deletions mkosi.profiles/surface-arm64/mkosi.conf.d/fedora/mkosi.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Fedora ARM64 for Snapdragon X Elite.
# Fedora rawhide aarch64 ships x1e80100-microsoft-romulus13/15.dtb since kernel 6.12.
# Source: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus13.dts

[Match]
Distribution=fedora
Architecture=arm64

[Content]
Packages=
kernel-core
kernel-modules
kernel-modules-extra
qrtr-tools
pd-mapper
qcom-firmware
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Audio module options for Snapdragon X Elite (Surface Laptop 7)
# Supplements surface-arm64.conf.

# snd_soc_sc8280xp: Qualcomm LPASS driver family, upstream since kernel 6.11.
options snd_soc_sc8280xp auto_soc=1

# Q6ASM: Q6 Audio Stream Manager, needed for DSP firmware loading via QRTR.
options snd_soc_qcom_q6asm debug=0

# HDMI/DP audio via USB4 (Surface Laptop 7 display output)
install snd_soc_hdmi_codec /sbin/modprobe --ignore-install snd_soc_hdmi_codec && \
/sbin/modprobe snd_soc_sc8280xp_common
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Module options for Snapdragon X Elite (Surface Laptop 7)

# Force CRB interface for Qualcomm fTPM.
# X Elite fTPM registers as a CRB device; tpm_tis/tpm_tis_spi conflict with it.
# Source: TCG TPM PC Client Firmware Profile specification
blacklist tpm_tis
blacklist tpm_tis_spi
options tpm_crb force_locality=0

# No PC speaker hardware on Snapdragon
blacklist pcspkr
blacklist snd_pcsp

# Increase QRTR socket buffer for Qualcomm subsystem IPC
options qrtr recv_buf_size=131072
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later
# Surface Laptop 7 Secure Boot enrollment helper
# Source: https://github.com/Foxboron/sbctl
# Source: https://github.com/linux-surface/linux-surface/issues/1590

set -euo pipefail

INSTRUCTIONS_DIR=/var/lib/surface-sb-enroll
mkdir -p "$INSTRUCTIONS_DIR"

echo "[surface-sb-enroll] Generating sbctl Secure Boot keys..."
sbctl create-keys

for uki in /efi/EFI/Linux/*.efi /boot/EFI/Linux/*.efi; do
[ -f "$uki" ] || continue
echo "[surface-sb-enroll] Signing: $uki"
sbctl sign "$uki"
done

if [ -f /var/lib/sbctl/keys/PK/PK.pem ]; then
openssl x509 -in /var/lib/sbctl/keys/PK/PK.pem -outform DER -out "$INSTRUCTIONS_DIR/ParticleOS-PK.cer"
echo "[surface-sb-enroll] Platform Key exported: $INSTRUCTIONS_DIR/ParticleOS-PK.cer"
fi

cat > "$INSTRUCTIONS_DIR/ENROLL_SECURE_BOOT.md" << HEREDOC
# ParticleOS Secure Boot Enrollment - Surface Laptop 7

Keys generated. To enable Secure Boot:

1. Copy Platform Key to EFI partition:
cp /var/lib/surface-sb-enroll/ParticleOS-PK.cer /efi/ParticleOS-PK.cer

2. Enter Surface UEFI: hold Volume Up + Power while powering on.

3. Navigate to Security -> Secure Boot -> disable, then Reset to Setup Mode.

4. Enroll Platform Key from file (select ParticleOS-PK.cer).
OR from Linux (SB disabled): sbctl enroll-keys --microsoft

5. Re-enable Secure Boot. Firmware should show Custom Key Configuration.

Verify: bootctl status | grep -i secure && sbctl status

WHY NOT MokManager: Surface NX Mode causes MokManager to hang (black screen).
ParticleOS uses UKI + systemd-boot with no shim, so MokManager is never invoked.
Ref: https://github.com/linux-surface/linux-surface/issues/1590
HEREDOC

echo "[surface-sb-enroll] Done. Read: $INSTRUCTIONS_DIR/ENROLL_SECURE_BOOT.md"
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Snapdragon X Elite: S3 (deep) not supported. s2idle (freeze) only.
# Source: Phoronix Surface Laptop 7 Linux coverage
[Sleep]
SuspendState=freeze
SuspendMode=
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
enable qrtr-ns.service
enable pd-mapper.service
enable surface-sb-enroll.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Qualcomm Protection Domain Mapper
# Needed for WiFi (ath12k) and audio DSP firmware bring-up.
# Source: https://github.com/andersson/pd-mapper

[Unit]
Description=Qualcomm Protection Domain Mapper
After=qrtr-ns.service
Requires=qrtr-ns.service

[Service]
Type=simple
ExecStart=/usr/libexec/pd-mapper
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Qualcomm IPC Router Namespace daemon
# Required for WiFi (ath12k/WCN785x), audio DSP, modem subsystem IPC.
# Source: https://github.com/andersson/qrtr

[Unit]
Description=Qualcomm IPC Router Namespace Daemon
After=local-fs.target
Before=network.target

[Service]
Type=simple
ExecStart=/usr/bin/qrtr-ns
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
# Secure Boot enrollment helper - Surface Laptop 7 / Snapdragon X Elite
#
# Runs once on first boot. Generates sbctl keys, signs UKIs, writes
# enrollment instructions. No MokManager - Surface NX Mode firmware
# freezes when MokManager loads. UKI + systemd-boot needs no shim.
# Source: https://github.com/linux-surface/linux-surface/issues/1590

[Unit]
Description=Surface Secure Boot Key Enrollment (First Boot)
After=local-fs.target
ConditionFirstBoot=yes
ConditionPathExists=!/var/lib/sbctl/guid

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/surface/sb-enroll.sh

[Install]
WantedBy=first-boot-complete.target
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
-- WirePlumber policy for Qualcomm Q6DSP on Snapdragon X Elite
-- /usr/share/wireplumber/main.lua.d/91-surface-arm64-qcom.lua

rule = {
matches = {
{ { "node.name", "matches", "alsa_output.platform*sc8280xp*" } },
},
apply_properties = {
["audio.rate"] = 48000,
["audio.format"] = "S16LE",
["resample.quality"] = 4,
["priority.session"] = 1100,
},
}