---
title: "Installing Arch Linux with Secure Boot on a Surface Pro 7 (1866)"
description: "How to install Arch Linux with Secure Boot on a Microsoft Surface Pro 7, including touch support, pen input, keyboard, battery management, and power profiles."
url: "https://knng.de/blog/arch-surface/"
published: "2025-11-02"
updated: "2026-05-17"
series: "Arch Linux and Hyprland on a Surface Pro 7"
---

# 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](https://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](https://rufus.ie/en/) 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
```bash
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:
```bash
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:
```bash
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
```bash
device list
```
> **Info:** Remember what your WiFi card is called.  
> In my case it is `wlan0`.

#### Scan and connect
```bash
station wlan0 scan
station wlan0 get-networks
station wlan0 connect YOURSSID
exit
```

Test with
```bash
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
```bash
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
```bash
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!

```bash
w
```
And `exit`.  

You can view the partitions you've just created by typing:
```bash
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`
```bash
fdisk /dev/nvme0n1
```

#### EFI  
```bash
t -> 1 -> 1
```
#### Swap  
```bash
t -> 2 -> 19
```
#### Linux root (x86-64)  
```bash
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:
```bash
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
```bash
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`
```bash
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:
```bash
mkswap -L "SWAP" /dev/nvme0n1p2
swapon /dev/nvme0n1p2
```

#### Format root
```bash
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
```bash
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
```bash
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
```bash
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
```bash
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`
```bash
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](https://github.com/linux-surface/linux-surface) 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
```bash
curl -s https://raw.githubusercontent.com/linux-surface/linux-surface/master/pkg/keys/surface.asc | pacman-key --add -
```

#### Verify fingerprint
```bash
pacman-key --finger 56C464BAAC421453
```

#### Sign key
```bash
pacman-key --lsign-key 56C464BAAC421453
```

#### Edit `/etc/pacman.conf`  
Add
```
[linux-surface]
Server = https://pkg.surfacelinux.com/arch/
```

#### Update and install
```bash
pacman -Syu
pacman -S linux-surface linux-surface-headers iptsd
```

---

### Time, localization, hostname

#### Set timezone
```bash
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:
```bash
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:
```bash
locale-gen
```

#### Setting the System Locale

Create the file `/etc/locale.conf` using nano:

```bash
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:
```bash
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.

```bash
nano /etc/NetworkManager/conf.d/iwd.conf
```
Add:
```
[device]
wifi.backend=iwd
```

#### Disable wpa_supplicant:
```bash
systemctl disable wpa_supplicant
```

---

### 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
```bash
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
```bash
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:
```bash
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:** Key and value can be separated by spaces or a tab, e.g. `title   Arch 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
```bash
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
```bash
nano /boot/loader/loader.conf
```
Remove the "#" from:
```
# timeout 3
```

This will give you three seconds to choose the kernel to boot from.

#### Verify
```bash
bootctl
bootctl list
```

---

## I'm using Arch (btw)

### Set root password
```bash
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
```bash
# 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
```bash
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:
```bash
sbctl status
Installed:   ✘ Sbctl is not installed
Setup Mode:  ✘ Enabled
Secure Boot: ✘ Disabled
```
### Create custom secure boot keys
```bash
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

```bash
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:

```bash
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:

```bash
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:

```bash
sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI
sbctl sign -s /boot/EFI/systemd/systemd-bootx64.efi
sbctl sign -s /boot/vmlinuz-linux-surface
```

> **Warning:** Don't skip the `-s`!  
> It saves the files to sbctl's database, so its pacman hook re-signs them after updates.  
> Without it, the first kernel update leaves you with a system that won't boot.

Running `sbctl verify` should look like this:

```bash
sbctl verify
✔ /boot/EFI/BOOT/BOOTX64.EFI is signed
✔ /boot/EFI/systemd/systemd-bootx64.efi is signed
✔ /boot/vmlinuz-linux-surface is signed
```

### Reboot and check
```bash
reboot
```

After the reboot, log in as `root` again and check:
```bash
sbctl status
```

`Secure Boot` should now show as enabled, and the red bar on the boot screen is gone.

---

## 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
- Connect to your WiFi with `nmtui`, NetworkManager is in charge now, not the live USB's `iwctl`
- **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.*

