Menu
Linux on Microsoft Surface 2

Install guide

Step by step: rollback, kernel build, Wi-Fi, Bluetooth, cameras, GPU and clocks.

The full sequence has not been repeated on a second, clean device. This describes how the working tablet was built, so expect to adapt it. You do this at your own risk.

You need a Linux computer, an ARM cross compiler, a USB keyboard, a USB drive and the Surface 2. All files are in the archive on the project page.

0. Prepare to roll back

Do this before changing anything.

  1. Create a bootable recovery USB drive.
  2. Back up the whole boot partition.
  3. Test every kernel and device tree with a one-time boot that restores the previous settings by itself. Only then make it permanent.

1. Unlock the boot

The Surface 2 only boots signed code until Secure Boot is bypassed. This step is not our work and is covered by the Open Surface RT guides:

Our tablet boots boot.efi from /boot/firmware, reads cmdline.txt, and takes the device tree from the dtb= parameter.

2. Base system

We used Raspbian 12 Bookworm armhf with GNOME 50. Other 32-bit ARM distributions should work, but the services in the archive assume this layout.

3. Build the kernel

sudo apt install gcc-arm-linux-gnueabihf bison flex libssl-dev bc
git clone https://github.com/Open-Surface-RT/grate-linux
cd grate-linux
git checkout ba70522fd65244fae81d48838119cd77e39d7140
patch -p1 < ../linux-on-surface-2-kit-1.0.0/kernel/kernel-avp5.diff
cp ../linux-on-surface-2-kit-1.0.0/kernel/config-avp5 .config
export ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
make olddefconfig
make -j"$(nproc)" zImage dtbs modules

The config sets -surface-avp5 in the kernel name, and the Wi-Fi service checks for it.

4. Wi-Fi and Bluetooth

Get the firmware using the guide, then patch mwifiex and build the modules:

cd drivers/net/wireless/marvell/mwifiex
patch -p1 < .../kit/wifi/0001-wifi-mwifiex-sdio-fix-reset-deadlock-and-hard-reset-.patch
patch -p1 < .../kit/wifi/0002-wifi-mwifiex-support-SD8797-14.62-firmware-Windows-B.patch
cd -
make -j"$(nproc)" M=drivers/net/wireless/marvell/mwifiex modules

Compile camera/dts/surface-avp-safe-cameras-vi-mclk-bthsuart.dts with dtc. There UART-D uses nvidia,tegra30-hsuart.

On the tablet, place the files and enable the services. Distribution files stay unchanged: firmware and modules are mounted over them, so disabling the service undoes everything at once.

sudo install -d /opt/surface-bt /etc/surface-bt
sudo cp out/sd8797-fp62win7-btuart.bin /opt/surface-bt/fw-win7.bin
sudo cp mwifiex.ko /opt/surface-bt/mwifiex-win7.ko
sudo cp mwifiex_sdio.ko /opt/surface-bt/mwifiex_sdio-win7.ko
cd /opt/surface-bt
sudo sh -c 'sha256sum fw-win7.bin mwifiex-win7.ko mwifiex_sdio-win7.ko > SHA256SUMS'
sudo install -m 755 .../kit/bluetooth/overlay.sh /opt/surface-bt/
sudo install -m 644 .../kit/bluetooth/surface-bt-*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable surface-bt-overlay.service surface-bt-attach.service
sudo touch /etc/surface-bt/enabled

Turn Wi-Fi power saving off with tools/surface-wifi-ps.sh, as the firmware can hang with it on.

Check after a reboot:

dmesg | grep 'driver_version'   # 14.62.17.p215
hciconfig -a                    # hci0 UP RUNNING
iw dev mlan0 link

5. Cameras

make -C /path/to/kernel M=$PWD/modules/tegra-video modules
make -C /path/to/kernel M=$PWD/modules/sensors modules
  1. Add cma=384M to cmdline.txt. Lower values starve the stream of memory.
  2. Load tegra-video with mc_api=1.
  3. Apply camera/libcamera/*.patch to libcamera and install camera/libcamera-configuration.yaml.
  4. Module settings are in camera/surface-camera.conf.

Check:

cam -l
cam -c 1 --capture=10

6. GPU, video and clocks

  • Apply gpu/patches in order onto Mesa 22.2.4 with the Grate driver.
  • modules/surface-v4l2 and modules/avp provide hardware decoding and need the NVIDIA files.
  • modules/dvfs controls clocks. surface-emc needs a table from your own device.

Start clock changes only after boot, with a guard that disables them after a failed start. Never lower VDD_CORE below 1100 mV at EMC 792 MHz.

Lessons from practice

  • Do not read FUSE registers through /dev/mem while their clock is off: the bus hangs.
  • Do not run perf record -a on this kernel: the tablet hangs.
  • Do not enable C7 cpuidle without a way to cut power: the tablet stops responding.
  • Back up before every firmware or device tree change, and keep a working boot option at hand.

Rolling back Wi-Fi and Bluetooth

sudo rm /etc/surface-bt/enabled
sudo systemctl disable surface-bt-overlay.service surface-bt-attach.service
sudo reboot