Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
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
linux-firmware
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