These are my notes for getting Arch Linux ARM booting on the Microsoft Surface Pro 11. The kernel tree can be found here.
Note
Efforts to upstream a kernel patch set are now underway: https://lore.kernel.org/all/20250714173554.14223-1-daleyo@gmail.com/
Also see Issue #12.
Warning
The test model is a Surface Pro 11, OLED version, Wi-Fi only (no 5G), with X1E SoC. If you have a different model (e.g. LCD screen, 5G, X1P CPU) then you're on your own.
| Feature | Working? | Notes |
|---|---|---|
| NVMe | ✅ | |
| Graphics | ✅ | 3D acceleration for X1E SoCs only; X1P support is on its way from upstream12. |
| Backlight | ✅ | Can be adjusted via /sys/class/backlight/dp_aux_backlight/brightness |
| USB3 | Partially | USB-C ports are working, but Surface Dock connector is presumably not. |
| USB4/Thunderbolt | ❌ | No external display output when using official USB4 dock. |
| USB-C display output | ✅ | Working as of 6.15-rc6 (for DP alt mode). |
| Wi-Fi | ✅ | Working with a kernel hack to disable rfkill. |
| Bluetooth | ✅ | Requires some udev rules to set up a valid MAC address, see Debian wiki. |
| Audio | Partially | Speakers working but can sound distorted; care needed with volume controls. Microphone "working" but too distorted to be usable. |
| Touchscreen | ❌ | |
| Pen | ❌ | |
| Flex Keyboard | ✅ | Only when attached to the Surface Pro; not sure about Bluetooth yet. |
| Suspend/resume | Partially | Lid switch seems to be working when Flex Keyboard covers screen. Resume from sleep can cause machine to hang or produce a black screen. |
| Cameras (and status LEDs) | ❌ |
A disk image suitable for dd'ing to a USB flash drive is available in the Releases section.
This disk image should be enough to get you to a vanilla Arch Linux ARM prompt. Details here.
- Username/password: alarm/alarm
- Root password: root
- For Wi-Fi,
iwdandiware installed;iwdis enabled by default. Runiwctlto connect to Wi-Fi; follow the instructions foriwctlin the Arch Linux Wiki. - Alternatively you can use a USB Ethernet adaptor to get the Surface connected to your network. Plug it in before booting; it should pick up an address via DHCP.
- After connecting to the Internet, run
sudo sp11-grab-fwand then reboot. This will try to fetch and install proprietary firmware blobs from the WOA-Project QRD repository (see below). sshdis running as normal with the generic Arch Linux ARM rootfs.
Warning
Without installing the firmware, many hardware components will be broken!
Installation to the internal NVMe drive is possible but not for the faint of heart. Don't attempt it unless you know what you're doing!
No detailed instructions for now, but you're basically going to need to do something like:
- Shrink your Windows partition. Do NOT delete it.
- Add and format an ext4 partition in the free space.
- Mount it and copy in the entire contents of the USB drive's Linux root partition.
- Mount your ESP under the new partition and chroot into the target.
- Install GRUB, pointing it at the ESP mount point. Hopefully it'll pick up the correct root partition UUID and add a UEFI boot entry.
The image is generated by a (very crude) script called build.sh. The script only runs on AArch64 Linux machines for now. It will probably break if you try to run it.
The script performs the following:
- Downloads and patches kernel source.
- Builds the kernel, modules and DTBs.
- Downloads the generic AArch64 Arch Linux ARM root filesystem tarball.
- Creates a 6GB disk image and partitions it into a 512MB FAT32 EFI partition and a 5.5GB ext4 root partition.
- Mounts the partitions and extracts the root filesystem.
- Installs our kernel and DTBs into
/boot. - Chroots into the rootfs, updates
pacman, removes the stock kernel and installs firmware and GRUB packages. - Edits
/etc/mkinitcpio.confso that the initramfs contains essential kernel modules for booting (enough to get us USB and the Surface keyboard for debugging). - Edits
/etc/default/grubto include some essential kernel command line arguments. - Creates the initramfs, installs GRUB into
/mnt/efiand generates the GRUB config. - Patches the GRUB config scripts so that they add a
devicetreeline that loads our Surface Pro 11 device tree.
The kernel is based on mainline as of v6.17.
-
drm/msm/dp: work around bogus maximum link rate:
For some reason the DPCD (DisplayPort Configuration Data) contains a zero where a maximum link rate is expected, causing the panel to fail to probe. This patch is an ugly hack which simply hardcodes it to what it should be.
Some kind of device tree-based override mechanism is probably needed to fix this cleanly, in the same way EDIDs can be overridden3.
-
arm64: dts: qcom: add support for Surface Pro 11
This patch introduces a device tree for the Surface Pro 11. It's nowhere near complete, but it's enough to get started.
-
firmware: qcom: scm: allow QSEECOM on Surface Pro 11
Minor patch to whitelist the Surface Pro 11 and enable access to EFI variables through the QSEECOM driver (useful for setting up bootloaders etc).
-
platform/surface: aggregator_registry: Add Surface Pro 11
This patch enables the Surface Aggregator driver, which gets the Flex Keyboard working. It may be possible to remove this patch and add the SAM into the device tree instead.
-
wifi: ath12k: Add support for disabling rfkill via devicetree and arm64: dts: qcom: x1e80100-denali: Disable rfkill for wifi0
Without this, Wi-Fi will be hard-blocked by rfkill. It looks like rfkill is supposed to be disabled according to the ath12k feature flags in the Surface Pro 11's DSDT (grep it for
f634f534-6147-11ec-90d6-0242ac120003, the UUID of the WCN7850). A patch to read these feature flags via ACPI seems to be making its way upstream, however since ACPI isn't being used here we add a device tree flag that lets us disable it.
The device tree is mostly based on the Surface Laptop 7 and Qualcomm CRD device trees as they share many similarities.
The values for the regulators in the apps_rsc section were found by scraping the DSDT dump and looking for the sections that contain PMICVREGVOTE.
Help is definitely needed reviewing and completing this device tree.
Firmware blobs that cannot be distributed here are needed from the stock Windows installation to get certain devices working.
Two scripts are included for firmware extraction:
sp11-grab-fw.shis installed into/usr/local/sbin/sp11-grab-fw. Runsp11-grab-fwfrom Arch Linux, and it will try download firmware from GitHub. Alternatively, installdislocker-gitfrom the AUR, then pass the--winoption to mount your Windows partition and automatically copy the firmware files into the right place. Note that it will disable the aDSP firmware by appending.disabledto the destination file name if it detects that you have booted from USB.sp11-grab-fw.batis included on the disk image's FAT partition which you can run from Windows. This will collect all the firmware into afirmwarefolder on the root of the flash drive. From Linux, you can then mount the EFI partition and copy the firmware to your system (e.g.mount /dev/sda1 /mnt/efi; cp -r /mnt/efi/firmware/* /lib/firmware/). However, see the note below about aDSP.
| Device | Source (Windows) | Destination (Linux) |
|---|---|---|
| GPU | C:\Windows\System32\qcdxkmsuc8380.mbn |
/lib/firmware/qcom/x1e80100/microsoft/qcdxkmsuc8380.mbn |
| aDSP* | C:\Windows\System32\DriverStore\FileRepository\surfacepro_ext_adsp8380.inf_arm64_1067fbcaa7f43f02\adsp_dtbs.elf |
/lib/firmware/qcom/x1e80100/microsoft/Denali/adsp_dtb.mbn |
| aDSP | C:\Windows\System32\DriverStore\FileRepository\surfacepro_ext_adsp8380.inf_arm64_1067fbcaa7f43f02\qcadsp8380.mbn |
/lib/firmware/qcom/x1e80100/microsoft/Denali/qcadsp8380.mbn |
| cDSP | C:\Windows\System32\DriverStore\FileRepository\qcsubsys_ext_cdsp8380.inf_arm64_9ed31fd1359980a9\cdsp_dtbs.elf |
/lib/firmware/qcom/x1e80100/microsoft/Denali/cdsp_dtb.mbn |
| cDSP | C:\Windows\System32\DriverStore\FileRepository\qcsubsys_ext_cdsp8380.inf_arm64_9ed31fd1359980a9\qccdsp8380.mbn |
/lib/firmware/qcom/x1e80100/microsoft/Denali/qccdsp8380.mbn |
Warning
Having the aDSP firmware installed seems to cause USB disconnect/boot failure late on in boot, so it should not be used when booting from USB.
Many thanks to those who helped with my questions on #aarch64-laptops!
Additional thanks to @JeromeDeBretagne for assistance with upstream submission and patch contributions.