Just got this Surface 3 as a hand-me-down. And I wanted to breathe some new life into it.
Plus it’d be cool to have a small x86 computer to run around with. Who knows I may use it as a dedicated radio demodulator or something else fun.
There’s actually a lot of support for these computers. Honestly I had no idea. The Linux Surface Project on github addresses most of the problems you’d run into with installing linux on a Surface.
I had a problem though. Support for the Surface 3 hasn’t really kept up with the rest of the line. And some of the recommended fixes for problems I ran into didn’t work or, at most, partially worked.
I’ve worked with this computer for the last couple of days and have finally got it to a point where I’m happy. Bluetooth and the cameras still don’t work (but to be honest I wasn’t going to use them). Most importantly to me however, the touchscreen controller isn’t crashing any more and the backlight controls finally work and are playing well with gnome.
If you’ve run into the same issues that I have and haven’t been able to find a fix yet. I hope this helps! :)
List of Fixes
List of all fixes that worked on my surface 3
DEVICE INFO: Kernel 6.8.1 Arch; GNOME 45.5; Surface 3; 2GB Ram
General Surface Drivers and Support
libwacom-surface
driver can be installed through the AUR.
Even though it’s not needed, I did install the marvel firmware for the wifi.
Broken Drivers
Touchscreen
Problem: Touchscreen controller randomly dies.
Fix: Added intel_idle.max_cstate=1 i915.enable_dc=0 intel_iommu=off iommu=off
to kernel settings.
Backlight
Problem: Backlight controls do not work.
Fix: Rebuild kernel with two drivers (pwm and i2c) switching places.
This causes the drivers to load in a different order. It’s more of a hack than anything.
Step by step
This is exactly what I did to install arch with gnome and get the touchscreen and backlight to work.
Install Arch
https://wiki.archlinux.org/title/Installation_guide Follow this guide for the initial setup before you get to the chroot part.
Preface
I do recommend changing the font in the live environment
># setfont ter-132b
And mount boot efi disk to /boot
and not /boot/efi
After Chroot
Once you’re in root partition
Set timezone
># ln -sf /usr/share/zoneinfo/<Region>/<City> /etc/localtime
Update hardware clock
># hwclock --systohc
Generate locales
edit /etc/locale.gen
and uncomment en_US.UTF-8 UTF-8
and other needed UTF-8 locales
># locale-gen
/etc/locale.conf
---------------------------------------
LANG=en_us.UTF-8
Set terminal font
># pacman -S terminus-font
/etc/vconsole.conf
---------------------------------------
FONT=ter-132b
Set hostname
/etc/hostname
---------------------------------------
<yourhostname>
Install text editors for later
># pacman -S vi vim
Set root password
># passwd
Install linux-surface project
These commands are subject to change. I will write out everything that I did so that maybe you can find where something went wrong
># curl -s https://raw.githubusercontent.com/linux-surface/linux-surface/master/pkg/keys/surface.asc | sudo pacman-key --add -
># pacman-key --finger 56C464BAAC421453
># pacman-key --lsign-key 56C464BAAC421453
Add repository to the end of pacman.conf
/etc/pacman.conf
---------------------------------------
[linux-surface]
Server = https://pkg.surfacelinux.com/arch/
Install main packages for linux-surface
># pacman -Syu linux-surface linux-surface-headers iptsd
Install additional packages we will need later
># pacman -S linux-firmware-marvell intel-ucode sudo networkmanager
This is everything for linux-surface
for now, but we’ll get back to it later.
Install grub
># pacman -S grub efibootmgr
># grub-mkconfig -o /boot/grub/grub.cfg
Create update-grub script
/usr/sbin/update-grub
---------------------------------------
#!/bin/sh
set -e
exec grub-mkconfig -o /boot/grub/grub.cfg "$@"
># chown root:root /usr/sbin/update-grub
># chmod 755 /usr/sbin/update-grub
Install into /boot
># grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB
Update grub config
Change line GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet"
/etc/default/grub
---------------------------------------
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet intel_idle.max_cstate=1 i915.enable_dc=0 intel_iommu=off iommu=off"
The setting: intel_idle.max_cstate=1 i915.enable_dc=0 intel_iommu=off iommu=off
, along with the wacom driver (that we will install later) will fix the issue of the touchscreen controller randomly dying some time after boot.
># update-grub
Create user
># useradd -m -g users -G wheel,video <username>
Set new user password
># password <username>
Enable sudo for new user
># visudo
This will open the sudoers file
Uncomment either:
%wheel ALL=(ALL:ALL) ALL
For sudo access for the wheel group
%wheel ALL=(ALL:ALL) NOPASSWD: ALL
Same thing without a password
Done with Arch install
># exit
># reboot
Login as user
Setup NetworkManager
>$ systemctl enable NetworkManager
>$ systemctl start NetworkManager
>$ nmcli device wifi connect <SSID> password <password>
Install gnome
>$ sudo pacman -S gnome
>$ systemctl enable gdm.service
>$ reboot
Install yay
>$ sudo pacman -S git base-devel
>$ git clone https://aur.archlinux.org/yay-bin.git
>$ cd yay-bin/
>$ makepkg -si
Install libwacom-surface
>$ yay -S libwacom-surface
Install onscreen keyboard panel button
>$ sudo pacman -S firefox gnome-browser-connector
Open firefox and go to https://extensions.gnome.org/
Install the browser extension
Search for Enhanced OSK
and install
In the preferences for Enhanced OSK
enable “Show Panel Indicator”
Disable login screen
On boot
Go to Settings > Users > Automatic Login : Enable
Out of suspend
>$ gsettings set org.gnome.desktop.screensaver lock-enabled false
Rebuild the Kernel
This is the only way that I have found to make the backlight controller work. There is a forum post discussing this issue. But the gist is you have two competing drivers and the wrong one is loaded first. To fix this we have to recompile the kernel.
Config settings that have worked for people in kernel version 5.6.13
CONFIG_PWM=y
CONFIG_PWM_CRC=y
CONFIG_I2C_DESIGNWARE_PLATFORM=y
CONFIG_I2C_DESIGNWARE_PCI=m
CONFIG_INTEL_SOC_PMIC=y
CONFIG_DRM_I915=m
For arch-6.8.1 the only ones we need to change are CONFIG_PWM_CRC
and CONFIG_I2C_DESIGNWARE_PCI
and the build took me around 5 hours to complete.
Alright so lets get into it
>$ git clone https://github.com/linux-surface/linux-surface.git
>$ cd linux-surface/pkg/arch/kernel/
Get checksum of default config
>$ sha256sum config
Keep this output for a bit later
Edit kernel configuration
config
---------------------------------------
CONFIG_PWM_CRC=y
...
CONFIG_I2C_DESIGNWARE_PCI=m
Now you have to resign the config file
>$ sha256sum config
Take the output of that command and place it into PKGBUILD
PKGBUILD
---------------------------------------
sha256sums=('SKIP'
'<checksum>'
...)
Replace old config checksum with the new one.
It should be the second one in the list right after 'SKIP'
But use the old checksum we got from earlier to confirm.
Replace checksum and save PKGBUILD
Build kernel
>$ PKGEXT=".pkg.tar" MAKEFLAGS="-j8" makepkg -s --skippgpcheck
Install new kernel package
>$ sudo pacman -U linux-surface-*.pkg.tar
>$ sudo update-grub
>$ reboot
And that’s it. That is everything I’ve done to make gnome arch working on my surface 3.
References & Resources
https://wiki.archlinux.org/title/Installation_guide
https://github.com/linux-surface/linux-surface/wiki/Installation-and-Setup#arch
https://github.com/linux-surface/linux-surface/wiki/Surface-3
https://github.com/linux-surface/linux-surface/tree/master/pkg/arch