Installation and Setup - linux-surface/linux-surface GitHub Wiki

This guide will take you through the process of installing Linux on a fresh Surface device, installing a patched kernel that will enable more functionality, then addressing device-specific quirks and issues.

Some distribution-specific instructions also exist. You may want to look at one of the following repositories:

You should also read the post-installation notes.

For Surface RT devices, see Open Surface RT instead.

Prerequisites

You will need:

  • A Surface device (of course!)
  • A USB drive to use as the install medium
  • For Surface Laptops: A spare keyboard (and mouse/USB hub if necessary so you can install Linux)

Before you start, it's also heavily recommended to update all firmware on Windows via Windows Update. It should fix various hardware-level bugs.

Installation

Warning:

  • If you are planning to use disk encryption (or have it set up already), make sure the required modules specified at this wiki page are included in your initram. I.e. make sure that these modules are loaded when the disk encryption unlocking screen appears, or else you will be unable to unlock your drive because the keyboard won't work.
    • It is critical to proceed with the note below because some devices requires some extra configuration.
    • See the "Disk Encryption" wiki only for configuring on after-installed system, you have to adapt instructions and do some extra tasks if you enable it from the installer system.
    • If you decide to enable disk encryption later, you will have to do this step if you have not done so already.

Note: Each device comes with its own set of quirks that need some tweaking. Visit the Hardware page, and look at your device's wiki page to find more instructions. You may want to have a look at those before you start your installation process (and likely also afterwards).

  1. Make a bootable USB

  2. Shrink the windows partition

    • This step can be skipped if you don't want to keep a Windows install
    • Go to Control Panel -> System and Security -> Administrative Tools -> Computer Management -> Storage -> Disk Management.
    • Right click on the Windows partition and shrink the volume as much as you'd like (a minimum of 50 GB is recommended).
  3. Disable secure boot

    • Only do this if your distribution doesn't support Secure Boot.
    • Fedora, Debian / Ubuntu and openSUSE all support it, while Arch installation media doesn't. (can enable after install)
    • If the USB doesn't boot because of verification errors, just disable it.
  4. Boot into UEFI to change the boot order to allow booting from USB. If you're leaving secure boot enabled, make sure that it allows non-MS signatures ("Microsoft & 3rd party CA")

  5. Install your distribution via a bootable USB.

    • You can use the toram boot param on Ubuntu (or copytoram=y on Arch) which will copy the resources to RAM, allowing you to disconnect the USB and plug in an external keyboard.
    • Due to EFI installation bug happen on somewhere (This confirmed that the bug happens on Ubuntu, not sure if other distribution have this similar bug, see this for more information)
      • To install on other place than local disk: if you have any ESP-flagged partitions on local disk and any connected disks, you have to disconnect that disk (unmounting is not enough) from installer's system or the another way temporarily removing ESP-flagged. Then proceed installing. After that, restore removed-ESP-flagged if you have them removed.

Surface Kernel Installation

After the previous step, you now have a bootable Linux distribution on your device, but on newer devices, a lot of features might not be working at this point. In this step you'll install the patched kernel with Surface drivers (and firmware). We're working towards upstreaming as much of the changes as possible.

Before installing the custom kernel, make sure that you have installed the DKMS version of any out-of-tree kernel module that you have installed (zfs -> zfs-dkms, nvidia -> nvidia-dkms etc.). Otherwise these modules will not work with the custom linux-surface kernel. If you do not know what DKMS/akmod or ZFS are, or do not rely on the ZFS file-system, you can (very likely) ignore this part. All drivers you need for basic operation should be included in the kernel itself and any external kernel modules can always be installed later.

There are multiple ways in which you can install and set up the linux-surface kernel:

The recommended route uses package repositories:

Debian / Ubuntu

First you need to import the keys we use to sign packages.

wget -qO - https://raw.githubusercontent.com/linux-surface/linux-surface/master/pkg/keys/surface.asc \
    | gpg --dearmor | sudo dd of=/etc/apt/trusted.gpg.d/linux-surface.gpg

After this you can add the repository configuration and update APT.

echo "deb [arch=amd64] https://pkg.surfacelinux.com/debian release main" \
	| sudo tee /etc/apt/sources.list.d/linux-surface.list
sudo apt update

If you encounter any issues reading "Error 401 Unauthorized" during the update or the installation below, please have a look at this.

Now you can install the linux-surface kernel and its dependencies.

sudo apt install linux-image-surface linux-headers-surface libwacom-surface iptsd

Important: Support for iptsd only goes back to the latest LTS release at the time of writing (Debian 11 and Ubuntu 22.04). If you are using an older release, and the above command fails, then please remove iptsd from it. You will still be able to use basic singletouch through the kernel driver, but multitouch and the stylus will not work.

After that you can install our secureboot key. This will import the key that the linux-surface kernel is signed with into your bootloader, so that the kernel is bootable without disabling secureboot.

sudo apt install linux-surface-secureboot-mok

This package will print instructions to the terminal. In case you missed those: It will ask you to reboot. Then, upon reboot, a blue menu (MokManager) should pop up, asking you whether you want to enroll the key. Confirm with ok/yes and when asked for a password enter surface. Note that MokManager expects a QWERTY keyboard layout, you may need to adjust your input accordingly. In case you missed the menu or accidentally chose the wrong options, you can uninstall (fully) and then reinstall the package and reboot to trigger the menu again.

Note that this will only work if your Debian derivative supports secure boot out-of-the-box. If if not, please consult the wiki of your distribution and set up secure boot for distro/stock kernels first. You also want to skip installing the package for now and only install it after you have set this up.

The linux-surface kernel will be installed alongside the default kernel provided by the distribution. This way you have a backup kernel you can use if something goes wrong. The bootloader will pick up the kernel by default, but you should update its configuration to make sure it was recognized.

sudo update-grub

Finally, reboot your system and you should boot into the linux-surface kernel. Please make sure you are actually using the right kernel by checking if the output of uname -a contains the string surface. If it doesn't contain that string, you are still using the default kernel and need to configure your bootloader.

Arch

First you need to import the keys we use to sign packages.

curl -s https://raw.githubusercontent.com/linux-surface/linux-surface/master/pkg/keys/surface.asc \
    | sudo pacman-key --add -

It is recommended to check and verify the fingerprint of the key.

sudo pacman-key --finger 56C464BAAC421453

Finally, you must locally sign the imported key.

sudo pacman-key --lsign-key 56C464BAAC421453

You can now add the repository by adding the following to the end of /etc/pacman.conf

[linux-surface]
Server = https://pkg.surfacelinux.com/arch/

After doing that you need to refresh the repository metadata, then you can install the linux-surface kernel and its dependencies.

NOTE: libwacom-surface is packaged through the AUR, so you need to install it from there.

sudo pacman -Syu
sudo pacman -S linux-surface linux-surface-headers iptsd

For some models (Surface Pro 4, 5, and 6, Book 1 and 2, Laptop 1 and 2) you need to install an additional firmware package for WiFi (if you have not done so yet) via:

sudo pacman -S linux-firmware-marvell

If you have already set up secureboot for Arch via SHIM, you can simply install our secureboot key (if not, please set up secureboot for stock/distro kernels first). This will import the key that the linux-surface kernel is signed with into your bootloader, so that the kernel is bootable without disabling secureboot. This package will print instructions to the terminal.

sudo pacman -S linux-surface-secureboot-mok

In case you missed those: It will ask you to reboot. Then, upon reboot, a blue menu should pop up, asking you whether you want to enroll the key. Confirm with ok/yes and when asked for a password enter surface. In case you missed the menu or accidentally chose the wrong options, you can uninstall (fully) and then reinstall the package and reboot to trigger the menu again.

NOTE: Arch by default is not set up for secureboot at all! It neither includes a signed bootloader, nor does it include a shim-loader that was signed by Microsoft. You can get some of these through the AUR, but you will definitely need to generate your own keys and add them to shim. Only run the above command if/once all of this has been done!

For more information on secure boot, take a look at the Arch Wiki or our page about secure boot.

The linux-surface kernel will be installed alongside the default kernel provided by the distribution. This way you have a backup kernel you can use if something goes wrong. GRUB will pick up the kernel by default, but you should update its configuration to make sure it was recognized. If you are not using GRUB, you might need to edit your bootloader configuration.

sudo grub-mkconfig -o /boot/grub/grub.cfg

Finally, reboot your system and you should boot into the linux-surface kernel. Please make sure you are actually using the right kernel by checking if the output of uname -a contains the string surface. If it doesn't contain that string, you are still using the default kernel and need to configure your bootloader.

Fedora

You can add the repository through DNF.

sudo dnf config-manager \
    --add-repo=https://pkg.surfacelinux.com/fedora/linux-surface.repo

After doing that, you can install the linux-surface kernel and its dependencies.

sudo dnf install --allowerasing kernel-surface iptsd libwacom-surface

If you plan on installing/building any kernel modules, you will also need to install the kernel-surface-devel package.

After that, you can install our secureboot key. This will import the key that the linux-surface kernel is signed with into your bootloader, so that the kernel is bootable without disabling secureboot. This package will print instructions to the terminal.

sudo dnf install surface-secureboot

In case you missed those: It will ask you to reboot. Then, upon reboot, a blue menu should pop up, asking you whether you want to enroll the key. Confirm with ok/yes and when asked for a password enter surface. In case you missed the menu or accidentally chose the wrong options, you can uninstall (fully) and then reinstall the package and reboot to trigger the menu again.

The linux-surface kernel will be installed alongside the default kernel provided by the distribution. This way you have a backup kernel you can use if something goes wrong. GRUB will pick up the kernel by default, you don't need to update the bootloader.

However, if the default kernel has a higher version than the surface kernel it will override the surface kernel and get booted by default. You can use a systemd path unit to fix this. We've included such a unit in the kernel-surface-default-watchdog package. The service should be enabled by default. To manually enable it, simply run

sudo systemctl enable --now linux-surface-default-watchdog.path

This will monitor /boot for any changes made by upgrades and set the default kernel for booting to the linux-surface kernel in that event.

To make sure the linux-surface kernel is booted the next time you reboot, run:

sudo linux-surface-default-watchdog.sh

Finally, reboot your system and you should boot into the linux-surface kernel. Please make sure you are actually using the right kernel by checking if the output of uname -a contains the string surface. If it doesn't contain that string, you are still using the default kernel.

Fedora Silverblue

Since you don't have DNF in Fedora Silverblue, you need to add the repository manually.

sudo wget -O /etc/yum.repos.d/linux-surface.repo \
    https://pkg.surfacelinux.com/fedora/linux-surface.repo

rpm-ostree, the package manager that is used by Silverblue is a bit different from normal DNF. It requires a package called kernel or kernel-core to be present, but it's not possible to pull this package from a remote repo automatically, you need to download the rpm and install it from disk.

However, this can be solved with an ugly and dirty hack: You can build a kernel dummy package, with a version number that's so high that it will always override the default kernel package. This dummy package then pulls in the kernel-surface package from our Fedora package repository.

We already prepared a dummy package for you to use.

wget https://github.com/linux-surface/linux-surface/releases/download/silverblue-20201215-1/kernel-20201215-1.x86_64.rpm
rpm-ostree override replace ./*.rpm \
	--remove kernel-core \
	--remove kernel-modules \
	--remove kernel-modules-extra \
        --remove libwacom \
        --remove libwacom-data \
	--install kernel-surface \
	--install iptsd \
        --install libwacom-surface \
        --install libwacom-surface-data

After that, you can install our secureboot key. This will import the key that the linux-surface kernel is signed with into your bootloader, so that the kernel is bootable without disabling secureboot. This package will print instructions to the terminal, so please install it on its own, not as part of a bigger batch of packages.

rpm-ostree install surface-secureboot

Finally, reboot your system and you should boot into the linux-surface kernel. Please make sure you are actually using the right kernel by checking if the output of uname -a contains the string surface. If it doesn't contain that string, you are still using the default kernel.

OpenSUSE Tumbleweed

This kernel maintained by @Taivas Jumala is under testing. If you encountered openSUSE dedicated package issues, you are welcomed to add a commont in this page.

Open Build Service (OSC) is set to automatically build this kernel package every time upstream (kernel-source) make any changes to keep up updates. However, the "linux-surface"" part of code is in patches.addons(You can read this from line:385 to learn how our patches are added), normal updates should work fine, just be carefull to do a kernel update when there is a new "Announcements and updates" because I may not apply those changes to our kernel that quickly. So it is highly recommended to subscribe that issue.

There are three ways to install kernel:

Method 1.openSUSE Software——kernel-default

In distribution choose openSUSE Tumbleweed→Show commnity packages→find home:TaivasJumala:Surface1 Click Install, then downloaed run kernel-default.ymp.

Method 2.Use zypper

Add repo by URL:

sudo zypper addrepo https://download.opensuse.org/repositories/home:/TaivasJumala:/Surface/openSUSE_Tumbleweed/home:TaivasJumala:Surface.repo

Install the package:

sudo zypper install -r 'Linux Surface (openSUSE_Tumbleweed)' kernel-default

Method 3. Use OPI (OBS Package Install)

You can check its Github Repo to learn how to use it, here we'll just quickly go through:

Install opi:

sudo zypper install opi

Install kernel-default:

opi kernel-default

It will ask you to pick a number to decide which package you want install, chose the name that exactly matched, which should be 1. Then pick number before home:TaivasJumala:Surface !.

After installing, it will ask you wether to keep the repo, keep it for future updating. It's ok if you missed it, you can add it back use install method 2.

After install you may need to visit yast to config grub to ensure that you will use the new kernel, espacially when you set time out time in 0 and didn't change default boot kernel. It's recommended to NOT to uninstall the original kernel for safty, in case of an emergency situation you can still got a fine proper kernel.

Secure boot is supported for openSUSE, on your first reboot you will need to Enroll MOK and enter your root password.

Unlike other distros listed above, because I have some difficulties to build them on OBS, iptsd and libwacom packages are missed in my repo. (Help wanted, mail me.) However, unlike Linux kernel will take a long time to build, you can build them from source quite fast.

People in China mainland may have network issue with OBS's server which you should deal it your own.

Post-Installation

Congratulations! You now have a Surface device running Linux.

After you've completed the installation process described above, there are a few things you may want to consider:

  • You should subscribe to Announcements and updates
  • You should install CPU microcode firmware for the latest CPU updates.
    • Debian/Ubuntu: intel-microcode or amd64-microcode
    • Arch: intel-ucode or amd-ucode
  • You should also install linux-firmware if you have not done so yet. Each device may need some additional firmware packages (depending on the distribution), please have a look at the device specific page for that.
  • Wireless problems caused by mwifiex should be significantly reduced in recent kernels. If you're still having problems with wifi randomly failing, consider opening a new issue and check mwifiex related sections in the mean time:
  • If you have issues with lower quality audio, you likely need to adjust your PulseAudio config: in /etc/pulse/daemon.conf set speex-float-5.
  • You may want to look at the additional Utilities and Packages.
    • Install libwacom-surface for better stylus and touch support e.g. in Gnome
    • If using a Surface Book 2:
      • surface-dtx-daemon, allowing you to better control the clipboard detachment system
      • surface-control, allowing control of the dGPU
  • Camera support is still a work in progress. Some devices (specifically Surface Book and Book 2, Pro 4, 5, and 6, as well as the Go and Go 2) require you to build and install libcamera for that to work. See Camera Support for details.

Setting your clock to localtime to fix dual-boot time skew

Windows stores the hardware clock as localtime, whereas Linux and other OS-es typically use UTC. When dual-booting this can cause the time to skew. The easiest way to fix this is by configuring Linux to use localtime:

sudo timedatectl set-local-rtc 1
sudo hwclock --systohc --localtime

Touch controls

The touchscreen on older surface devices is called Intel Precise Touch & Stylus, or short IPTS. Newer devices call it Intel Touch Host Controller, or short ITHC. All Intel-based devices from Surface Pro 4 upwards use IPTS or ITHC, except for the Surface Go lineup.

To calibrate your touchscreen, you can follow this guide: https://github.com/linux-surface/iptsd/wiki/Calibrating-iptsd

If you want to use touchscreen gestures (touch scroll, pinch zoom etc), you'll need to know a few things:

  • You should make sure that you are running a Wayland desktop session, instead of an X11 / Xorg session. Wayland has native support for touch inputs, while Xorg essentially emulates a mouse pointer when you touch the screen. You can select the session type at your system's login screen.
  • It is important, that your applications run on Wayland as well. If your desktop runs on Wayland, but the applications use the XWayland compatibility layer, the X11 protocol becomes the limiting factor again. To check whether an application runs on X11 or Wayland, run xkill in a terminal window and then click on the window of the application. If it closes, the app runs on X11, if nothing happens it runs on Wayland.
  • Any gesture functionality is dependent on the software you are running. This includes both, the application (e.g. Firefox) and the desktop environment (e.g. GNOME). The driver can only provide a set of input coordinates to the applications. By default, the system will behave as if you've clicked at the point of a single touch, or mouse-button dragged when you single-finger drag.

Firefox

Firefox supports touch inputs by default if it runs on Wayland. If you are running a Wayland session, add MOZ_ENABLE_WAYLAND=1 to /etc/environment (some distros do this by default). If you are running an X11 session, you can use MOZ_USE_XINPUT2=1 instead. To improve the zoom behaviour you can enable apz.allow_zoom in about:config.

Visual Studio Code

Visual Studio Code uses the command-line switch --touch-events. One way to enable this is by editing /usr/share/applications/code.desktop and adding the switch to the Exec lines.

This might also work for other Electron-based applications.