I've had a Surface Book with an i7 processor since November 2016. I liked the idea of a laptop with detachable tablet, the touchscreen and that it comes with a pressure sensitive pen. It makes for a neat, if slightly expensive, machine. It has a fatal flaw though: Windows 10. I tried to like Windows, I really did, but it's just so. darned. slow. File access is inexcusably slow, especially for a device equipped with lightning fast NVMe storage. In real world usage it proved 4 to 10 times slower than Linux running on the same machine... off a USB 3 attached SSD. This relegated the Surface Book to a role of a secondary machine for me, while my primary was a cheap i5 laptop with inexpensive m2 SATA3 SSD storage (and yes, there is a huge maximum performance difference to the NVMe storage, not to mention the processor speed).
To cut a long story short, I wanted to unleash the true potential of the Surface Book using Kubuntu Linux. The end goal is having a dual boot Windows and Linux laptop with the Linux side sporting encrypted storage (because of GDPR requirements) and working keyboard, touchpad, WiFi, card reader and touch screen at the very least. I'm glad to say, mission accomplished! I'm writing this article using Kubuntu on my Surface Book. Now, this is a comprehensive How To of what I did. I am writing this mainly for me to remember all the small details and in hope I can help some of you out there. Most, if not all, of what I am writing here also applies to Surface Pro 2 and above, Surface Book 2 (2018) and Surface Laptop.
Before you begin...
Your journey will be fraught with peril. So make sure you have backed up everything you have on your laptop. Failure is an option and the only thing standing between that and disaster is a good, tested backup.
Test that backup. No, really, I insist.
Disable BitLocker (for now)
Now that you're sure you have a working backup, you need to disable BitLocker. This is a temporary measure and a necessary one because we are going to be changing the hard drive and boot layout which throws BitLocker into a tantrum. The first time I tried installing Linux on this laptop this caught me out and I spent several grueling hours trying to recover the laptop (the automated recovery of the BitLocker encryption did NOT work properly, for reasons unknown).
Here is how to do it.
- In the search bar type “Manage BitLocker” and click on the result that comes from the Control Panel.
- You are now in the BitLocker Control Panel applet. Next to your hard drive there is a “Turn off BitLocker” link. Click on it. DO NOT click on the “Suspend BitLocker encryption”, it does something entirely different.
- Now Windows tells you that it's decrypting the drive which will take a few hours (in my case it took about 45'). This message also appears in the Notification center (far right icon on your bottom toolbar which opens the right-hand slider thing). When that message disappears your drive is decrypted. Until that time you must not reboot, shut down or let your computer sleep. Don't worry, I'll keep you busy.
Create a Windows installation USB key
While you're waiting for the BitLocker decryption you can spend your time productively by creating Windows installation media. This is your last resort. If all else fails miserably and you're left with a wiped laptop you can use this media to reinstall Windows (and then install the Surface Book drivers from Microsoft's site). Since Surface devices have no optical media you'll have to use a USB key of at least 8GB size.
Here's the short version of the instructions:
- Download the Windows Media Creation Tools from the Download Windows page.
- Run it when it's done downloading.
- Select “Create installation media (USB flash drive, DVD, or ISO file) for another PC”. Click on Next.
- The language, edition and architecture can be changed but it's recommended that you simply select “Use the recommended options for this PC”. Click on Next.
- Insert your USB flash drive into the laptop's USB port. Remember that the contents of this USB drive will be forever deleted.
- Select “USB flash drive”. Click on Next.
- Select the USB flash drive you inserted to the laptop. Click on Next.
This will take a while. The tool downloads a copy of the Windows installation media and writes it to the USB flash drive, making it bootable in the process. I recommend testing that this flash drive boots right before the “Boot into the live Kubuntu environment” step. Not all USB flash drives are bootable and there's no way to tell in advance. Been there...
Don't reboot just yet. We have more work to do.
Create a Kubuntu installation USB key
After the previous step is done and while you're still waiting for the BitLocker decryption to complete let's create the Linux installation USB flash drive. This is a different USB flash drive than the previous one! Again, it needs to be at least 8GB in size.
- Download the latest Kubuntu ISO file. Choose the 64-bit version.
- Download UNetbootin. This tool lets us create bootable USB flash drives from Linux ISO images.
- If the USB flash drive you created for Windows is still plugged in, remove it now.
- Insert your USB flash drive into the laptop. This will be your Linux installation media.
- Run UNetbootin. It will show you the UAC prompt, asking for elevated privileges. This is normal. Accept it.
- Select the “Diskimage” option and use the triple dots to select the Kubuntu ISO you donwloaded in the first step.
- Make sure the Type is set to “USB drive”.
- From the Drive drop-down select your USB flash drive.
- Click on OK.
After a while the Kubuntu installation media will be written to the USB flash drive which is now bootable. Don't reboot just yet. We have some more work to do still.
Free up some space and resize your partitions
We need some space to install Linux. The minimum is roughly 20GB for Linux itself, 1 GB for its boot partition and as much memory you have (e.g. 16GB) for the Linux swap. That's 37GB minimum. I recommend 64GB or more if you are going to be doing any serious work on Linux. I use 196GB but do note that I have a device with 512GB storage. Unfortunately, you have to commit to a number now, you cannot (easily) change it later.
Before we repartition the drive, let's make sure there's no garbage left behind and that the free space is contiguous. First, let's remove unnecessary files:
- Open Windows Explorer (Key shortcut: WIN+E)
- Right click on your hard drive and click on Properties.
- Select the General tab and click on the Disk Cleanup button.
- Click on the “Clean up system files” button. You will get a UAC prompt. Select Yes.
- Select all items.
- Click on the “OK” button.
Depending on how long ago you cleaned up your machine this might take a while.
If you are really low on space, e.g. you have the 128GB model, you might want to also remove System Restore and Shadow Copies files. These don't appear to make a dent in the free space reported by Windows but they do take up disk space and can prevent shrinking the main volume in a later step.
- Open Windows Explorer (Key shortcut: WIN+E)
- Right click on “This PC” and click on Properties.
- Click on Disk Cleanup button.
- Click on the “Clean up system files” button. You will get a UAC prompt. Select Yes.
- Select the More Options tab.
- Under “System Restore and Shadow Copies” click the “Clean up” button.
- Click on the Delete button.
If you are still low on space follow the instructions on the article I linked above to uninstall unused applications and games, enable OneDrive files on demand, disable hibernation (an easy up to 16GB gain) or even compress the Windows installation. The latter takes a while and does degrade the already not-that-great filesystem performance of Windows.
The next step is to defragment (defrag) your storage. Before you freak out, no, defragging an SSD storage is not your grandpa's defrag with its copious read / write cycles. It uses a feature of the SSD controller called TRIM, it's super fast and it improves the health of the storage by telling the controller which blocks are meant to be contiguous. You should only do this after all other disk operations (decrypting BitLocker or compressing the Windows installation) are done. Also note that Windows does defragment SSDs automatically once a month but we can trigger it manually to make sure partitioning will be easier:
- Enter “defrag” the search bar and select the “Defragment and Optimize drives” option.
- Select your storage (C:).
- Click on the Optimize button.
Yup, it only takes a few seconds. Now moving on to creating space for Linux (paritioning):
- Enter “disk management” in the search bar and select the “Disk Management” result.
- Right click on the Windows partition (it's the largest one) and click on “Shrink Volume”.
- The only editable field tells Windows how much free space to create in MB. Remember when you decided how many GB of free space you need at the beginning of this section? Multiply by 1024 to get the number in MB. For example, 64GB is 65536 MB. If you cannot enter a number that high go back and free up more space, especially restore points and shadow copies, run defrag again and retry.
- Click on Shrink and let Windows do its thing.
- DO NOT CREATE ANY PARTITIONS IN THE FREE SPACE. We MUST do that from the live Kubuntu environment.
At this point you have free space for Linux, no ongoing length operations are in progress and we are ready to boot into the live Kubuntu environment. Only first we need to tell the Surface Book that it's OK to do so.
Enable boot from USB
By default, Surface Book will not boot from a USB flash drive for security reasons: if someone has physical access to your machine they cannot boot into a custom operating system to steal your information or otherwise subvert your laptop. We need to temporarily lift this restriction by enabling USB boot. Once we're done installing Linux we can revert that change. While you are at it, set a strong password for the UEFI firmware and store it somewhere securely: it will be impossible to change any device options, including boot from USB, without your password. This is an easy and efficient way to increase the physical security of your laptop, especially if you are travelling abroad.
- Completely shut down Windows: Start menu, power icon on the left, Shut Down.
- When your laptop has shut down, hold down the volume-up button on your laptop and at the same time, press and release the power button. Keep holding the volume-up button down until you see the Surface logo.
- Once in the UEFI menu (what many people, erroneously, still call the “BIOS menu / screen”) tap on Advanced Options. Make sure that “Enable Boot from USB devices” is set to On.
- If you have configured a boot order, set “Enable alternate boot sequence” to On.
- When you are done tap on Exit Setup and then Yes.
- The Surface Book reboots into Windows. Shut it down again.
Boot into the live Kubuntu environment
- Completely shut down Windows: Start menu, power icon on the left, Shut Down.
- When your laptop has shut down, hold down the volume-down button on your laptop and at the same time, press and release the power button. Keep holding the volume-down button until you see the Kubuntu boot menu. It's tiny.
- Stop holding the volume down button. Press ENTER to boot Kubuntu.
- Once it boots up select Try Kubuntu. Yes, it's tiny. We'll fix it in a minute.
- Click on the lower left icon (K menu) and type Displays, then ENTER.
- Scroll down the window and change the resolution to 2500 x 1600.
- Scroll all the way down and select Scale Display.
- Set the scaling to 1.5
- Click on OK then OK again.
- Click on the K menu, Leave, Logout
- Log back in (it's an empty password, just press ENTER).
- Ah, much better now, isn't it? :)
Prepare the disk encryption
Eveything is covered in this Ask Ubuntu answer. This section is just an adaptation to Surface Book.
First, we will need to create two new physical partitions. One partition is our encrypted volume. We'll use LVM (Logical Volume Management) to create logical volumes for the system root volume and the swap in it. The other partition will be an unencrypted ext4 partition holding the /boot directory where boot-time files (kernel, initial RAM disk, grub configuration) go. These are used to set up the base system so we have the chance to decrypt our encrypted partition. That's why it can't be encrypted: you need to boot into a kernel and initial RAM disk to decrypt the other volumes! The size of the /boot partition must be at least 200MB. I recommend using 1GB so that you have enough space for a couple of older kernels you forgot to remove with apt autoremove.
- Click on the K menu, type “partition” and press ENTER to open KDE Partition Manager. I assume that your storage device is /dev/nvme0n1.
- You should normally see some free space between /dev/nvme0n1p3 (an NTFS partition holding Windows) and /dev/nvme0n1p4 (a locked NTFS partition containing the Windows Rescue system files). In this space create a new partition of type “ext4”, size 1GB (1024 MB) and mount point /boot Hereon I will call this volume /dev/nvme0n1p5.
- In the rest of the free space create a new partition of type “physical volume for encryption”. This is not formatted or mounted anywhere. Hereon I will call this volume /dev/nvme0n1p6.
- Apply these changes. It only takes a moment.
At this point we have an unformatted partition which we need to turn into encrypted volumes for our system. Time to work in the command line. Click the K menu, type konsole (with a K in front, it's not a typo) and press ENTER. This opens a terminal window. Enter the following (the stuff in bold type is what probably needs to be modified, see above).
sudo cryptsetup luksFormat --hash=sha512 --key-size=512 --cipher=aes-xts-plain64 --verify-passphrase /dev/nvme0n1p6
# At this point it will ask you for a password. WRITE IT DOWN. Without it you will not be able to decrypt (unlock) your Linux partition!
sudo cryptsetup luksOpen /dev/nvme0n1p6 CryptDisk
sudo pvcreate /dev/mapper/CryptDisk
sudo vgcreate vg0 /dev/mapper/CryptDisk
# Change the swap size (16G) to be equal your memory size if you want to hibernate (suspend to disk)
sudo lvcreate -n swap -L 16G vg0
# The rest of the partition is allocated to the Linux root volume
sudo lvcreate -n root -l +100%FREE vg0
Go to the next step WITHOUT REBOOTING. If you reboot you will have to remove the encrypted partition and start over.
Install Linux and fix the disk encryption on the installed system
Click on the “Install Kubuntu” icon on your desktop to start the installer.
In the “Installation type” step choose “Something else” option. The partition management page appears. Here you will have to make the following assignments:
- /dev/nvme0n1p5 mount to /boot and check the format box (make it blue)
- /dev/vg0/swap use as swap
- /dev/vg0/root mount to / (root) and check the format box (make it blue)
- /dev/nvme0n1p1 mount to /boot/efi and DO NOT check the format box (leave it grey). Now, /dev/nvme0n1p1 is the small fat32 partition with the “efi” flag. This is where the laptop (both Windows and Linux!) stores the EFI executable which is used to boot the respective operating system. Essentially this is the first step to loading GRUB2, the Linux boot manager. That's why Linux needs to have access to it: otherwise it will do something stupid when installing the boot manager!
Finally, look at the bottom of the window. Change the “Device for boot loader installation” to /dev/nvme0n1.
Continue installing. At the end DO NOT CLICK ON THE REBOOT BUTTON. Click on “Continue trying Kubuntu” instead. At this point Kubuntu has finished installing but it has NOT set up the full disk encryption on the installed system. If you were to reboot now you'd end up with an unusable system. We will fix this right now.
Click the K menu, type konsole (with a K in front, it's not a typo) and press ENTER. This opens a terminal window.
First we will find out what's the UUID of our encrypted partition. Enter the following to the terminal window:
sudo blkid | grep LUKS
This replies with a line like this:
/dev/nvme0n1p6: UUID="01234567-89ab-cdef-0123-456789abcdef" TYPE="crypto_LUKS" PARTUUID="abcdef98-7654-3210-f0e1-d2c3b4a56789"
Note down the UUID, i.e. the part I put in bold in the line above. Your UUID will definitely be different than my example :)
In the next step we are going to mount the installed system under /mnt, chroot into it (essentially, run as though we were booted into it) and create the missing file for full disk encryption, /etc/crypttab. Finally, we're going to update the initial RAM disk and reinstall GRUB2 to make sure the encrypted setup can be found at boot time, letting us decrypt the disk. Ready? Enter the following (the stuff in bold type is what probably needs to be modified, see this and the previous section).
mount /dev/vg0/root /mnt
mount /dev/nvme0n1p5 /mnt/boot
mount --bind /dev /mnt/dev
mount --bind /run/lvm /mnt/run/lvm
mount /dev/nvme0n1p1 /mnt/boot/efi
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t devpts devpts /dev/pts
Now you are sitting in front of an editor. Enter the following:
CryptDisk UUID=0997545b-d508-48d4-ad85-e9d2a178cfb9 none luks,discard
Note the bold part. This is the UUID of your encrypted partition as we found it earlier. It's the stuff I told you to note down.
Now hit CTRL-X and press Y to save the file.
Finally, we are going to create the initial RAM disk afresh and reinstall GRUB2:
update-initramfs -k all -c
That's it. Now you can close the Konsole window and reboot.
If all went well you will see a boot screen with tiny text. The first option is Kubuntu, the last option is Windows. If you let it sit there for 10 seconds it boots into Kubuntu. A few seconds later it will display a text box and as you to unlock /dev/nvme0n1p6. Enter the disk encryption password you had set up before installing Kubuntu. It will tell you it's unlocked and proceed to boot. Yay!
Fix HiDPI in KDE
My God, everything is tiny! That's because Surface Book has a HiDPI a.k.a. Retina a.k.a. high-resolution monitor. KDE is unaware for various reasons and we are going to fix that. It's a multi-step solution.
First click on the K menu, type Displays and press ENTER.
Scroll the window all the way down and click on “Scale display”.
Drag the Scale slider to 2 and click on OK.
Click OK again.
Click the K menu, leave, Logout.
Log back in. It's still not quite right: the text is bigger but the icons are tiny and the spaces between controls are all messed up. We're gonna fix this in a minute.
Click on the K menu, type Konsole and press ENTER to open a console.
Go all the way to the bottom and type the following:
# Fix KDE HiDPI. see https://www.reddit.com/r/kde/comments/85rz91/icons_in_the_desktop_context_menu_dont_respec$
# It is possible that it currently does nothing at all.
# KDE HiDPI fix on X server
# This line tells Qt, the graphics framework used by KDE, to forcibly use the scaling factor for rendering everything
# The following two lines fix GTK3 applications, such as Firefox.
# This first line tells GDK3 to use a 2.0 scale factor
# The previous line alone would cause the fonts to be huge. This line applies a reverse factor (1/2.0 = 0.5) to
# restore the fonts back to their natural size.
Press CTRL-X and then Y to save the file.
Log out and log back in for the changes to take effect.
Fix HiDPI in the console
Kubuntu, like any other Linux distribution, also has a text only console. In fact it has five of them. You can access them from the graphical environment by pressing CTRL-ALT-F2 through CTRL-ALT-F6. When in the text only console you can move to other consoles with ALT-F2 through ALT-F6. You can return to the graphical environment by pressing ALT-F1.
The text in these consoles is tiny because they are not HiDPI aware. We can work around that by selecting a larger size font.
From a terminal (e.g. Konsole) run
sudo dpkg-reconfigure console-setup
In the screens which appear select “UTF-8” encoding, “Guess optimal character set”, “Terminus” font, and “16x32 (framebuffer only)” font size. This changes the font to a twice-big size which fits our twice-big (HiDPI) display just fine. Nice!
Fix HiDPI in the boot loader (grub2)
Remember how the boot loader appeared tiny? Yeah, it was no fun for me either.
The first thing we can do to fix that is to tell GRUB2 to use a different screen resolution. Open Konsole and run
Find the line
and change it to
Press CTRL-X and Y to save the file. Then run
to apply the settings. Granted, the screen resolution you get is ugly and looks like something from 20 years ago but at least the text is legible.
On top of that, I decided to make the boot loader look marginally better. The way to do this is by installing a different GRUB2 theme, such as Breeze. It has a better, graphical display of the boot options. Thus booting your laptop doesn't look like a hacking scene from Mr. Robot. Just follow its instructions to install it.
Install the custom kernel for Surface devices
By now you have figure out that there's a ton of Surface Book hardware which doesn't work at all under Kubuntu, especially touch, detach and the SD card reader. All of these require special support from kernel drivers which simply are not bundled with Kubuntu for various reasons.
Fear not, Jake Day has made a decent and easy to use solution! Seriously, people, send this man some money (I already did). He deserves it.
Without further ado, open Konsole:
git clone https://github.com/jakeday/linux-surface.git
sudo bash setup.sh
It will ask you a few questions. Answer them to your liking. I chose Yes to all except hibernation. When it's done reboot and log in. Try touching stuff on your screen. MAGIC!
The stylus also works but it needs to be paired by Bluetooth first. Click the Bluetooth icon in the toolbar at the bottom of the screen and then click the “+” button to add a new device. Hold down your pen's button (at the top of the pen) for at least 7 seconds to set it to pairing mode. It will appear on the list. Click on it to add it. Now try pointing stuff on your screen with the pen. MAGIC AGAIN! I mean, try this in Krita or any other drawing program. It's pressure sensitive and everything!
As a side note, the pen seems to be behaving erratically in the kernel version I am using right now (4.17.3-3). If that happens to you try to reset the pen and touch through the following commands in Konsole:
This is a known bug and it's being worked on.
As a side note, please remember that you are using a custom kernel. It does not auto-update like the rest of the system. You will need to monitor Jake's repository and run setup.sh again when a new version comes out. Small price to pay for having almost all bells and whistles of the Surface Book working.
Furthermore note that not everything works. Most notably the cameras do not work. According to the README in the repository Jake has tried, the patch was unreliable and he has temporarily disabled it. The other thing that doesn't work on Surface Book 1 but works on Surface Book 2 is the discrete graphics (nVidia GPU). If you were planning on running modern games with high performance 3D graphics on Linux, tough. Then again, with 1GB of video RAM you'd be hard pressed to run such games on the Surface Book 1 so it's not a big loss. Moreover, by not using discrete graphics you get really good battery life (in the area of 8 hours of real world usage) so it's not such a big loss.
Finally, detach won't work if you have not fully shut down Windows. Don't try it yet, it won't work. More on that a bit later.
Remember that we disabled BitLocker on Windows? Not so great from a security perspective. Reboot into Windows and re-enable it now. It's the same instructions as disabling it with the difference that the link now reads “Turn BitLocker on”. You will have to wait a few minutes to hours for the drive to be re-encrypted before rebooting to Linux. Technically you don't have to but it kinda beats the purpose of security not waiting for the encryption to complete. Right?
Make sure that the tablet part can detach (Surface Book only, obviously)
The top part of the Surface Book is the actual computer. The bottom part contains not just the keyboard and trackpad but also the discrete graphics (nVidia) and the USB devices (USB3 hub, SD card reader). When you use Windows it puts a lock on the GPU. This tells the Intel firmware in the tablet part to not allow detaching the tablet part. The only way to remove that lock is to fulyl shutdown, not restart, Windows.
Now here's the catch. You'd think that if you go to Windows menu, power icon, shutdown this would do the trick. Wrong! Windows 10 comes with a feature called "Fast startup" and it's enabled by default. Whenever you tell Windows to shut down it actually hibernates. On the plus side, it means that the next boot into Windows after you have shut down your laptop will be faster. On the other hand, the drivers never truly shut down, the lock to the GPU is not removed and you cannot detach the tablet from the keyboard part on Linux unless Windows was installing updates before it shut down. That's how I figured out what's going on: after shutting down Windows while installing updates I was suddenly able to detach the tablet under Linux. This happens because shutting down Windows when it installs updates really shuts down the system, since the drivers are being upgraded and will have to be reloaded the next time you start your computer. Argh! The way to fix that permanently is disabling fast startup on Windows:
- Right click the Start menu (Windows icon) and click on Power Options.
- Click the “Choose what the power buttons do” link.
- Click the “Change settings that are currently unavailable” link and accept the UAC prompt.
- Uncheck the “Turn on fast startup (recommended)”.
- Click on Save Changes.
- Now you can shut down Windows and then power your laptop back on to boot in Linux.
It's worth noting that the slow down booting into Windows from disabling Fast Startup are not that bad on the Surface Book. The whole thing boots into the session in under 25 seconds as opposed to about 5 seconds with Fast Startup enabled. Loading the session, i.e. services and everything running on your toolbar, takes much longer than that. So it is not a deal breaker in real world usage.
Moreover, there are some issues with the tablet mode. If I detach the tablet part it immediately thinks I have pressed the power button and asks me to shut down Linux. No amount of telling it not to works. This is a known bug and the only workarounds is to either configure KDE not to do anything when the power button is pressed or attach the tablet on the keyboard part with the screen facing out (“tablet with big battery” configuration).
Also, I have yet to make the accelerometer work on Linux, meaning that the tablet screen does not rotate when I rotate the tablet. I rarely use the Surface Book as a tablet so it's not a big deal for me (I can still manually rotate the screen from KDE's “Displays” system settings module) so I was disinclined to spend time finding a solution.
Connecting external, non-HiDPI, displays
Things are tricky because Linux does not support (gracefully) having a different HiDPI setting per display.
If you just want to present to an external screen or projector with LibreOffice Impress there is nothing you need to do. Impress will render your presentation just fine on the external display.
If you want to work on the external screen or present using a web application such as Office 365 you need to undo the HiDPI fixes, log out and then log back in (and accept the fact that your laptop screen displays everything tiny). This means that first you need to run the KDE Displays system settings module and set Scale Screen back to 1. Then you need to edit the ~/.profile file and comment out (place a # in front of) the lines you added in the “Fix HiDPI in KDE” section of this article. Finally log out, log back in and both screens will have reverted to low DPI mode. If you only need to work on the external monitor, e.g. when using an external display, keyboard and mouse, you can use the WIN-P keyboard shortcut until the display output is only shown on the external display.
Do note that this is not a problem with the Surface Book per se but the way HiDPI support works in Linux. In theory you should be able to edit the .profile file and replace QT_AUTO_SCREEN_SCALE_FACTOR with QT_SCREEN_SCALE_FACTORS to have different scale factors per screen. Or you could use none of that and use xrdb to set the DPI per screen.
That said, my use case is either using the laptop standalone or connecting it to a HiDPI screen at home. As for presentations, I've found that an iPad Pro with an Apple Pencil is the ideal platform for creating and delivering a presentation. Therefore I had no reason to pursue external monitor connections any further. You can say that I gave up some cash to preserve my sanity.