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.

Info
Turning off Secure Boot will put a big red bar across the top of your Surface’s boot screen.
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.

Info
If you are using a wired LAN connection, you should be fine. No configuration required.

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
Info
Remember what your WiFi card is called.
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
Warning
This configuration only applies to the live image environment and won’t persist once the installation is complete and you’ve rebooted.

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
Info
I’ll be using the name of my drive from this point on, so whenever you see /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

Info
The last partition will be selected automatically by fdisk.

Write changes

Warning
This is a destructive action and erases all data!
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.

  • 1 sets the partition as EFI
  • 19 sets it as SWAP
  • 23 sets it as Linux Root (x86-64) You can exit the partition-type list at any time by pressing Q.
Info
Make sure these numbers are still correct if you’re not using 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
Info
Notice the 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:

  • p1 should be the EFI/BOOT partition
  • p2 is the SWAP partition
  • p3 is your /root partition

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.

Info
SWAP will be auto-detected by 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
Info
These packages cover essential system functionality, hardware support, networking, and basic management tools.

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.

  • -U uses UUIDs (unique identifiers) for each partition, which makes the system more robust if device names change.
  • >> /mnt/etc/fstab appends 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
Info
/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
Info
These files don’t exist until you’ve saved them.

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
Info
This next part needs to be done carefully. Make sure you double-check the UUID when you write it down!

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
Info
Use a tab after each descriptor, i.e. titleArch Linux

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.

Warning
Without a root password, you won’t be able to log in as 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
Info
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
Info
Now, your new user can use 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!
Warning
Do not omit the --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
Info
Setup mode is disabled now. Do not reboot yet!

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)
Warning
Remember to enable the user services: 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.