Installing Arch Linux with Secure Boot on a Surface Pro 7 (1866)
Preface
Windows certainly has its place in the world, especially on a Surface device.
It usually just works, has a familiar user interface, and installing apps is straightforward,
the touch interface and pen are easy to use and well integrated.
Still, there’s that specific itch I sometimes get, the desire to customize my devices exactly the way I want.
Whether it’s changing the desktop design, adjusting how I interact with the system, or simply installing only what I actually need instead of dealing with a bloated OS full of ads and unwanted apps and services.
If you’re feeling frisky today, you’ve come to the right place.
Let’s try installing Arch Linux on a Surface and, by the end of this small miniseries, hopefully have a Surface running Linux that’s just as usable as Windows.
We’ll look at touch support, pen input, the detachable keyboard, battery management, and processor power profiles.
Preparation
Grab the latest Arch ISO from archlinux.org/download.
Just scroll down a bit and you’ll see a list of mirrors. Select a mirror close to your region.
As of writing, the latest ISO is archlinux-2025.10.01-x86_64.iso.
Use Rufus to create the installer USB stick.
Select the GPT partition scheme and “UEFI (non CSM)”.
Disable Secure Boot in the Surface’s firmware:
Shut down your Surface, press Volume Up and the power button.
Release the power button when the Microsoft logo appears.
This opens the Surface’s UEFI. Use TAB and arrow keys to navigate:
Select Security -> Change configuration -> None -> OK.
Now, change the Boot Configuration:
If your mouse works, drag USB-Storage to the top of the list.
If, however, your mouse is not detected, simply enable “Enable alternate boot sequence”.
Insert the USB stick, click Exit, then Restart now.
Immediately press Volume Down when restarting.
Don’t worry, we’ll fix it later.
Installing Arch
I’m a big fan of not using “archinstall” to install Arch.
So strap in, get a coffee, let’s do a manual install!
First, let’s set the keyboard layout.
Keyboard layout
List layouts
localectl list-keymaps
This will print out a list of keyboard layouts that you can choose from.
Use loadkeys to set your desired layout.
E.g for the German keyboard layout:
loadkeys de-latin1
Network connection
Now, let’s set up a network connection.
Start iwd:
iwctl
You might be wondering:
Why isn’t the command called iwd? Why do we use iwctl instead?
iwd (that stands for “iNet Wireless Daemon”) is a wireless service for Linux developed by Intel.
To interact with it, we use the client program iwctl, which acts as the interface to the daemon.
List devices
device list
In my case it is
wlan0.
Scan and connect
station wlan0 scan
station wlan0 get-networks
station wlan0 connect YOURSSID
exit
Test with
ping ping.archlinux.org
Partition the disk
For this step, we’ll use fdisk.
fdisk is an interactive command-line utility that lets us create and manage partition tables and partitions.
List disks
fdisk -l
The first line displayed after running the command should correspond to your NVMe drive.
In my case, it appears as /dev/nvme0n1.
We’ll be creating the following partitions:
| Mount point | Type | Size |
|---|---|---|
| /boot | EFI | 1 GiB |
| [SWAP] | SWAP | 8 GiB |
| / | ROOT | Remainder |
/dev/nvme0n1, make sure to replace it with the correct device name for your system.
If you’re an advanced user, you might choose to create additional partitions, for example, a separate /home partition.
However, I won’t cover that here, as the setup described above works perfectly well as is.
fdisk doesn’t apply any changes right away, it only writes them when you explicitly choose to write the partition table.
In other words: If you screw up, you can simply start over.
Start fdisk
fdisk /dev/nvme0n1
Delete all partitions by typing d.
Repeat this step until every partition has been removed.
If fdisk prompts you to remove a signature, select “Yes”.
Create partitions
For /boot do:
n -> Enter -> 1 -> Enter -> Enter -> +1G -> Enter
For SWAP do:
n -> Enter -> 2 -> Enter -> Enter -> +8G -> Enter
For /root do:
n -> Enter -> Enter -> Enter -> Enter
fdisk.
Write changes
w
And exit.
You can view the partitions you’ve just created by typing:
fdisk -l
Partition types
If you’re already accustomed to installing Arch, you’ve probably noticed something…
I haven’t set the partition types yet! Fortunately, this can be done easily through fdisk as well.
Set types with fdisk
fdisk /dev/nvme0n1
EFI
t -> 1 -> 1
Swap
t -> 2 -> 19
Linux root (x86-64)
t -> 3 -> 23
You might be wondering: What are those magic numbers? 1? 19? 23???
If you type L while in fdisk /dev/nvme0n1 (after selecting t to change a partition type), you’ll see a list of all available partition types.
1sets the partition asEFI19sets it asSWAP23sets it asLinux Root (x86-64)You can exit the partition-type list at any time by pressing Q.
archlinux-2025.10.01-x86_64.iso.
Write changes to disk
Simply type w and exit.
You can verify the new partition types by running:
fdisk -l
Format partitions
So far, all we’ve done is create the three partitions and assign their types. However, setting a partition type is not the same as formatting a partition.
The partition type is essentially a label that tells the operating system or bootloader what kind of data the partition is intended to hold (e.g., Linux filesystem, swap, EFI, etc.).
It doesn’t affect the actual contents of the partition or make it usable yet.
The partition format (or filesystem) is the process of creating a filesystem such as ext4, btrfs, or FAT32.
This prepares the partition to actually store files and directories.
In short, the type is just a descriptor, while formatting actually structures the space for data storage.
So, let’s format /boot accordingly!
Check devices
fdisk -l
p1 in nvme0n1p1.That indicates the partition number. Your drive is /dev/nvme0n1, and the partitions are numbered from 1 to 3.
If you followed the guide:
p1should be theEFI/BOOTpartitionp2is theSWAPpartitionp3is your/rootpartition
Format /boot
mkfs.fat -F 32 -n "BOOT" /dev/nvme0n1p1
mkfs stands for “make filesystem”.
It takes a partition and prepares it to store files by creating a filesystem on it.
Format and enable swap
Swap is special memory space the system can use when your RAM is full. We need to prepare the partition and then activate it:
mkswap -L "SWAP" /dev/nvme0n1p2
swapon /dev/nvme0n1p2
Format root
mkfs.btrfs -L "ROOT" /dev/nvme0n1p3
Mount filesystem
Before we can start installing the system, we need to mount the partitions so the installer can write data to them.
We use the mount command for this.
Mount root
mount /dev/nvme0n1p3 /mnt
With this command, we mount /dev/nvme0n1p3 to /mnt in the live environment, allowing us to install the new system onto that partition.
Mount EFI
mount --mkdir /dev/nvme0n1p1 /mnt/boot
This mounts the EFI System Partition (/dev/nvme0n1p1) onto /mnt/boot in the live environment.
By doing this, the installer can write boot files to the EFI partition, which will be used by the system when it starts.
genfstab later.
Install essential packages
Next, we need to install the basic packages required for our Surface to work properly.
This includes:
- base – the core system packages
- CPU microcode updates (intel-ucode) – provides hardware and security fixes for Intel CPUs
- Intel firmware (linux-firmware-intel) – necessary for hardware support
- Networking tools (iwd, NetworkManager) – for Wi-Fi and general network management
- Bluetooth (bluez, bluez-utils) – enables Bluetooth functionality
- pipewire, pipewire-pulse, wireplumber and pavucontrol - Audio subsystem
- Text editor (nano) – a simple editor for beginners (easier than Neovim)
- Secure Boot key manager (sbctl) – needed if using Secure Boot
- mkinitcpio – a script to create initramfs images, required for booting
- sudo – allows running commands with administrative privileges
Install the base system
pacstrap -K /mnt base intel-ucode linux-firmware-intel iwd networkmanager bluez bluez-utils pipewire pipewire-pulse wireplumber pavucontrol nano sbctl mkinitcpio sudo
Generate fstab
genfstab -U /mnt >> /mnt/etc/fstab
genfstab automatically generates a list of all mounted partitions and their mount options.
-Uuses UUIDs (unique identifiers) for each partition, which makes the system more robust if device names change.>> /mnt/etc/fstabappends this information to the fstab file in the new system, so it knows which partitions to mount at boot.
In short: this step tells your new system how to automatically mount your partitions.
Finally, it’s time to step into your brand-new Arch installation!
Switch to Arch using arch-chroot
arch-chroot /mnt
Congratulations! You are now inside your freshly installed Arch system and no longer on the live USB environment!
Everything you do from here affects your new system directly.
Install kernel
Next, we need to install a kernel, the core of the operating system that communicates with your hardware.
For our Surface device, we’ll use the Linux Surface project on GitHub.
This custom kernel adds:
- Full touchscreen and pen support
- Accurate battery reporting and performance modes for the processor
- Detection of the keyboard flip, automatically turning off the display when the keyboard is closed
Using this kernel ensures your Surface behaves correctly and efficiently under Linux, unlocking features that the standard kernel doesn’t fully support.
Import keys
curl -s https://raw.githubusercontent.com/linux-surface/linux-surface/master/pkg/keys/surface.asc | pacman-key --add -
Verify fingerprint
pacman-key --finger 56C464BAAC421453
Sign key
pacman-key --lsign-key 56C464BAAC421453
Edit /etc/pacman.conf
Add
[linux-surface]
Server = https://pkg.surfacelinux.com/arch/
Update and install
pacman -Syu
pacman -S linux-surface linux-surface-headers iptsd
Time, localization, hostname
Set timezone
ln -sf /usr/share/zoneinfo/Region/City /etc/localtime
hwclock --systohc
/Region and /City need to be changed to your Zone.E.g.:
/Europe/Berlin.
Generating Locales
Open the locale configuration file with:
nano /etc/locale.gen
Then, uncomment the UTF-8 locales you want to use, e.g: de_DE.UTF-8 UTF-8 and en_US.UTF-8 UTF-8.
Generate the locales with:
locale-gen
Setting the System Locale
Create the file /etc/locale.conf using nano:
nano /etc/locale.conf
Add the following lines:
LANG=en_US.UTF-8
LC_TIME=en_US.UTF-8
Optional: English System with European Date Format
If you want your system language in English but prefer the European date format (DD/MM/YY), use this instead:
LANG=en_US.UTF-8
LC_TIME=de_DE.UTF-8
Last but not least, add your keyboard layout to /etc/vconsole.conf, like so:
nano /etc/vconsole.conf
KEYMAP=de-latin1
Finally, add your preferred hostname to /etc/hostname.
I chose archsurface.
Enable services
You may find it useful to have some services run automatically at boot, e.g. time-sync, networking and bluetooth.
Enable on boot:
systemctl enable NetworkManager.service
systemctl enable iwd.service
systemctl enable bluetooth.service
systemctl enable systemd-timesyncd.service
Configure networking backend
By default, NetworkManager might not use iwd as its Wi-Fi backend. We also want iwd to use systemd-resolved for DNS resolution.
nano /etc/NetworkManager/conf.d/iwd.conf
Add:
[device]
wifi.backend=iwd
Disable wpa_supplicant:
systemctl disable wpa_supplicant
Configure iwd
mkdir -p /etc/iwd
nano /etc/iwd/main.conf
Add:
[Network]
NameResolvingService=systemd
Install boot manager
I like using systemd-boot, so… we’ll use systemd-boot. :D
systemd-boot is a simple and reliable boot manager.
We also need to tell systemd-boot where to find our kernel, initramfs, and other boot files.
Install systemd-boot
bootctl install
Get UUID
ls -l --time-style=+ /dev/disk/by-uuid/
Write down the UUID for Partition 3, the root partition.
Create bootloader entries
To do this, navigate to the directory:
cd /boot/loader/entries
and add a file called surface.conf, in it, type:
title Arch Linux
linux /vmlinuz-linux-surface
initrd /intel-ucode.img
initrd /initramfs-linux-surface.img
options root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx rw
Double-check your spelling! A common typo is writing vmlinut instead of vmlinuz…
It’s also highly recommended to create a fallback entry. This is a backup boot configuration that lets you start the system from a fallback kernel if your main kernel becomes corrupted during an update for example.
This way, you always have a safety net in case things go south.
Create a fallback entry
cp /boot/loader/entries/surface.conf /boot/loader/entries/fallback.conf
Edit the title in fallback.conf
title Arch Linux (fallback)
linux /vmlinuz-linux-surface
initrd /intel-ucode.img
initrd /initramfs-linux-surface-fallback.img
options root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx rw
Edit loader.conf
nano /boot/loader/loader.conf
Remove the “#” from:
# timeout 3
This will give you three seconds to choose the kernel to boot from.
Verify
bootctl
bootctl list
I’m using Arch (btw)
Set root password
passwd
This sets a password for the root account, the most powerful user on your system.
root after reboot.
To create a new user on a Linux system and give them administrative privileges, so you don’t have to log-in with root every time, simply follow these steps:
Create user
# Create a new user with a home directory
useradd -m username
# Set a password for the new user
passwd username
# Open the sudoers file for editing
EDITOR=nano visudo
username is a placeholder for your own username.
Give the User Sudo Privileges
Once inside the sudoers file:
- Find the section called User privilege specification (almost at the bottom of the file).
- Add the following line under it:
username ALL=(ALL) ALL
sudo to run administrative commands.
All that is left now, is to unplug your USB drive!
Exit and reboot
exit
reboot now
You are now running Arch Linux on your Surface!
… but wait… what about secure boot?
Secure Boot
Remember the thing we installed, called sbctl?
That’s right, it’s Secure Boot time!
Log in as root and do the following:
Type sbctl status.
It should look similar to this:
sbctl status
Installed: ✘ Sbctl is not installed
Setup Mode: ✘ Enabled
Secure Boot: ✘ Disabled
Create custom secure boot keys
sbctl create-keys
Created Owner UUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Creating secure boot keys...✔
Secure boot keys created!
Enroll the custom secure boot keys
sbctl enroll-keys --microsoft
Enrolling keys to EFI variables...
With vendor keys from Microsoft... ✔
Enrolled keys to the EFI variables!
--microsoft flag!
If you check sbctl status it should look something like this:
sbctl status
Installed: ✔ Sbctl is installed
Owner GUID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Setup Mode: ✔ Disabled
Secure Boot: ✘ Disabled
Verify and sign the keys
Doing sbctl verify should return:
sbctl verify
✘ /boot/EFI/BOOT/BOOTX64.EFI is not signed
✘ /boot/EFI/systemd/systemd-bootx64.efi is not signed
✘ /boot/vmlinuz-linux-surface is not signed
We now need to sign those binaries. Simple. Do the following:
sbctl sign /boot/EFI/BOOT/BOOTX64.EFI
sbctl sign /boot/EFI/systemd/systemd-bootx64.efi
sbctl sign /boot/vmlinuz-linux-surface
Running sbctl verify should look like this:
sbctl verify
✔ /boot/EFI/BOOT/BOOTX64.EFI is signed
✔ /boot/EFI/systemd/systemd-bootx64.efi is signed
✔ /boot/vmlinuz-linux-surface is signed
You’ve done it.
You’ve installed Arch, a minimal setup of packages and signed your secure boot keys. Well done!
If you ever get back into the Surface’s UEFI you’ll notice that “Secure Boot” has automatically enabled a new option that you couldn’t choose yourself before.
Don’t touch it.
Leave it as is, or you’ll have to sign your keys again.
One more thing…
After you’ve rebooted, do two things: Set up WiFi again and enable the audio services as follows:
- Login as your normal user
- Follow my guide about setting up a network connection
- If audio is not working, reinstall pipewire-pulse:
sudo pacman -S pipewire-pulse(On my system this was missing somehow after pacstrap)
systemctl --user enable pipewire pipewire-pulse wireplumber!
Cheers.
This post is part of a series. The next part covers Installing and configuring Hyprland on a Surface Pro 7.