Skip to content

Instantly share code, notes, and snippets.

@shimeoki
Last active April 10, 2025 20:29
Show Gist options
  • Save shimeoki/7f85a5af72bbd6bd0f7f6d685f01cd06 to your computer and use it in GitHub Desktop.
Save shimeoki/7f85a5af72bbd6bd0f7f6d685f01cd06 to your computer and use it in GitHub Desktop.
Windows 11 + Arch Linux dual-boot (systemd-boot) installation guide with encrypted partitions (BitLocker and LUKS respectively) and Secure Boot (UEFI)

My Windows 11 + Arch Linux dual-boot installation

Caution

All actions are at your own risk! This has been tested by me, but does not guarantee your success.

Read everything at least once before actually following the guide. If something goes wrong, stop immediately. Consider starting from the beginning.

About the guide

This gist was very helpful to me and I wanted to write my own version with a dual-boot setup.

  • Full title: Windows 11 + Arch Linux dual-boot (systemd-boot) installation guide with encrypted partitions (BitLocker and LUKS respectively) and Secure Boot (UEFI)
  • Version: 2.1.3

The previous version (let's call it as v1.1.0 or just v1) was written by me a long time ago. I wanted to follow my own guide to check it's integrity and validity, and rewrite it along the way.

Note

It's not recommended to follow v1, but if you want to, you can check this version - the first 3 revisions of the gist.

This guide is more like a list of actions, and does not go into detail about the installation (although it does explain some things in general). If you want to read more, I leave reference links throughout the guide, and there are resources at the end.

If you have any problems or questions, feel free to write a comment.

Description

This setup:

  • Set on a laptop
  • Has Arch Linux installed
    • With the LUKS encrypted container
    • With the zen-kernel
  • Has Windows 11 installed
    • With the BitLocker encryption
  • Uses systemd-boot
    • Boot partition is not encrypted
  • Uses ext4 as Linux file system
  • Has no swap file
  • Does not configure the TPM module

Tip

Skip to the parts you need in the Table of Contents, but keep in mind that everything is done with these goals in mind.

Table of Contents

Prerequisites

Required

  • The device you want to install on
  • The device you want to read the guide from
  • Flash drive with at least 8 GB of memory
  • Internet connection
  • Phone with a camera

Hardware

Warning

Check your device for any operating system compatibility issues. It could be anything, but usually drivers.

In my case, I'm using a "HUAWEI MateBook D 15 BoM-WFQ9" laptop. At one point, the speakers didn't work under Linux (Windows was fine), and only Bluetooth headphones worked. Everything is fine now.

If possible, it's better to check for these problems beforehand, as this dual-boot setup is not so quick to deploy.

Important

My laptop has an AMD APU (CPU with integrated graphics), NVMe and everything else hardware specific. I will warn you in the sections where it is important not to just copy and paste.

Software

First, you need to get the .iso files of Arch Linux and Windows 11.

  • The preferred method of downloading Arch .iso is using a BitTorrent client. Arch Linux downloads.
  • The Windows image can be created using the Media Creation Tool or downloaded directly. Windows 11 downloads.

In my case both images together in size are about 6 GB, so an 8+ GB flash drive is recommended.

Second, you need to create a bootable USB flash drive.

Warning

Backup your data on the USB before that!

I use Ventoy. Just download the program, extract, open Ventoy2Disk and proceed to install Ventoy on the drive.

Note

Ventoy can create MBR or GPT disks as you wish. It is hidden in the "Option" menu at the top. Documentation has a dedicated page on this topic.

Previously, I used MBR, and now GPT - everything is fine in both cases.

I also recommend that you enable "Secure Boot Support" (should be enabled by default, just in case).

After installation, just copy the images to the root of the flash drive.

Pre-installation

Quick guide for the CLI

Shell

  1. To autocomplete the name of a directory, a file or a command, press Tab.
  2. To enter previous commands, press down arrow key multiple times.
  3. Ctrl + L - clear terminal.
  4. Ctrl + C - cancel the current command.
  5. Ctrl + U (at least in zsh) - cut everything before the cursor.

Shell environment variables

export VAR=value
# make an environment variable

echo "$VAR"
# print this variable to the console
# you can use "$VAR" anywhere to shorten commands
# you can omit the double quotes, but it's safer to do so

# example:
export PART_LUKS=/dev/nvme0n1p5
cryptsetup -v luksFormat "$PART_LUKS"

nano

In nano you can move the cursor with the arrow keys and enter text like in Windows Notepad. No "Insert mode" like in Vi or Vim.

There are other keybinds at the bottom. The most important are:

  • Ctrl + S - save
  • Ctrl + X - exit
  • Ctrl + F - search

less

Very useful terminal pager.

Binds:

  • j / arrow down - down
  • k / arrow up - up
  • q - quit

To view the output of the command in less, do the following:

<command> | less

Battery capacity

To check the battery capacity, you can run

cat /sys/class/power_supply/"$BAT"/capacity

where $BAT is the battery directory. Usually it's BAT0, but but in my case it was BAT1.

Secure Boot

Disable it before installation.

Some UEFIs have a tendency to turn it back on periodically, so I recommend checking it every time you reboot.

In my case (InsydeH20 UEFI) I have to press F2 on boot to start the "Setup Utility". "Secure Boot" is in the "Security Settings" category, but this varies from UEFI to UEFI.

Preparing the disk

At this point you need to boot from the Arch Linux image to access the shell.

My systemd-boot from the previous installation doesn't allow me to use other bootable devices except configured boot entries, so I just disabled my both entries as bootable.

Warning

While I was booting the flash drive, I ran into this problem. It is a Ventoy bug with the Arch image, so be careful.

I tried to use the old version of Ventoy (1.0.94) with the normal boot mode and the screen appeared. On the new version (1.0.99) the iso works in normal mode, but someone in the comments said that it's still broken.

In any case, make sure you have the latest versions of everything, or boot in grub2 mode (I haven't tested this).

Erasing

Warning

You will have to erase your data on the device to continue. Backup anything you might need.

My laptop has an NVMe drive, so I will use nvme-cli.

Check the drive name

nvme list

Important

If you are using only one drive, it will most likely be shown as /dev/nvme0 or /dev/nvme0xx. Do not use the /dev/nvme0xx syntax for the variable, only /dev/nvme0.

  1. /dev/nvme0 - drive (device) name
  2. /dev/nvme0xx - disk name (will be needed later)
export DRIVE=/dev/nvme0

You can choose not to use the variable.

Check available formatting methods

nvme id-ctrl "$DRIVE" -H | grep -E 'Format |Crypto Erase|Sanitize'

Note

v1 command:

nvme id-ctrl "$DRIVE" -H | grep "Format \|Crypto Erase\|Sanitize"

It works, but incorrectly. It doesn't show all the entries.

If you have the

[1:1] : 0x1 Block Erase Sanitize Operation Supported

you can proceed with this operation.

Perform a block erase

Warning

All data will be erased.

nvme sanitize "$DRIVE" -a start-block-erase
# or
nvme sanitize "$DRIVE" -a 0x02

Check completion

nvme sanitize-log "$DRIVE"
# you can spam this command

If the command prints

Sanitize Progress                      (SPROG) :  65535
Sanitize Status                        (SSTAT) :  0x101

you are good to go. "Sanitize Status" should be equal to 0x101.

Warning

As ArchWiki says, it can take a long time (2-3 hours), but in my case it took about 5-10 seconds. Still, be prepared.

Verify the erase

export DISK="$DRIVE"n1
# it is probably n1, but still check
dd if="$DISK" bs=8192 status=progress | hexdump
# this command prints the contents of the drive bytes into the console

I recommend waiting for this command to run for about 30 seconds, and if all you see is

0000000 0000 0000 0000 0000 0000 0000 0000 0000
*

that's a successful sanitize.

You can cancel the command and continue.

Partitioning

Note

Documentation: fdisk - ArchWiki

# as a remainder:
# DISK=/dev/nvme0n1

fdisk -l "$DISK"

If the disk is present and is empty, we can proceed:

fdisk "$DISK"

You can type

m

to view help.

Note

Any changes you make in this program will not take effect until you save them manually with w. You are free to experiment as you wish.

The plan

My partitioning scheme:

  1. EFI system partition (ESP): 1G (less is not recommended, but possible)
  2. MSR partition: 16M (required for Windows)
  3. Windows root partition: ?G
  4. Linux root partition: ?G

Important points:

  1. I won't use the swap partition.
  2. I will only use one partition per system. No separate one for "home".
  3. You can split the root partitions however you like. My choice is 50/50.
  4. When enabling BitLocker, Windows will automatically create the "Windows Recovery Environment" partition. You can also do this manually, but I haven't tested this.

Create new table

g
# create a new empty GPT partition table

Create the partitions

Primary flow:

n       # create new partition
        # skip until "Last sector", defaults are ok
        
        # make sure that you can select one of 128 partitions,
        # otherwise you forgot to create the GPT.
        # don't ask me how I know that
        
+<size> # use your needed sizes for the partitions

I will use the sizes in cursive from the plan as <size>.

All partitions will be of type "Linux". We will configure them later.

Tip

For the last partition, don't use the +<size> syntax, but just use the second number in the "Last sector" line.

You can check the current partitions with

p

Change the partition types

# ESP
t
1   # first partition
1   # type to "EFI System"
# MSR
t
2   # second partition
10  # type to "Microsoft reserved"
# Windows root
t
3   # third partition
11  # type to "Windows basic data"
# Linux root (optional, default value is also fine)
t
4   # fourth partition
23  # type to "Linux root (x86-64)"

Tip

You can list all types with

L

to view with less.

Save and check

w # save and quit fdisk
fdisk -l "$DISK" 

The disklabel type should be GPT and all partitions should be of the required types.

Formatting

I'm doing it just in case for the ESP, it's not necessary.

mkfs.fat -F 32 /dev/nvme0n1p1

The other partitions will be formatted later:

  1. Windows partitions will be formatted by the Windows installer.
  2. Linux partitions will be formatted after the Windows installation because of the LUKS encryption container.

Reboot

reboot
# or
poweroff # and boot manually

Windows 11

Tip

I recommend to install Windows first and Linux second.

Installation

After rebooting, select your Windows 11 .iso file and boot it in normal mode.

Less bloatware

Important

On the first screen select "English (World)" under "Time and currency format".

You will get an OOBEREGION error later. It skips the region selection and the Microsoft account creation/authorization.

If you get an "infinite" (it just takes a few minutes) loading wheel after rebooting - you got it.

Hopefully it hasn't been patched yet.

Normal installation

Warning

I don't encourage piracy, so everything in this guide is for educational purposes only.

Next steps:

  1. "I don't have a product key".
  2. In my case I select "Windows 11 Pro" and click "Next".
  3. Read and accept the terms to continue.

Tip

If your mouse or touchpad doesn't work, you can use:

  • Alt + underlined key
  • The spacebar
  • The Tab key
  • Shift + Tab
  • The arrow keys

Select the partition

Most important part:

  1. Select "Custom: Install Windows only (advanced)"
  2. Select your Windows root partition and click "Next"

You should now see all your defined partitions. The Linux root partition will have 0.0 MB of "Free space" because Windows doesn't work with this type of partition.

In my case I need the third partition. In fact, I can't select any other partitions because their types are incompatible with the installation.

Proceed with the normal installation

After a few reboots, you'll be greeted by a white screen with the Windows 11 logo.

And if you did the trick from the Less bloatware chapter, you will be greeted by the spinning wheel. Wait for a bit, it's "intended" behaviour.

After the OOBEREGION error, click 'Skip'.

Don't connect to the network

I recommend clicking on "I don't have internet" after setting up the layouts. The installation will be faster (as I believe) this way.

You can also click "Continue with limited setup" to skip the Microsoft login.

Tip

Sometimes this won't show, so you have to do this manually.

Press Shift + F10 to open a command prompt and run:

OOBE\BYPASSNRO

This will reboot the system, and then you will be able to continue with limited setup.

Credit: https://github.com/kaubu

Normal installation once again

Nothing unusual here. User, password, security questions and privacy checks. You can turn these off if you want.

Configuration

After a successful installation, we can configure it on the spot to avoid multiple reboots.

Drivers

Connect to the internet and use Windows Update to install the latest updates. The sound didn't work in my case without them.

Important

I got the 0x80248007 error a couple of times. It's OK, it'll fix itself later. Just don't install failed updates.

Activation

I will use Microsoft Activation Scripts.

Run PowerShell as an administrator. The easiest way to do this is to find PowerShell in the Start menu (press the Windows/Super key) and run it as an administrator.

irm "https://get.activated.win" | iex

Then follow the on-screen instructions. Just typing 1, any key after activation and 0 to exit is fine.

winutil

In the same PowerShell instance we can run winutil.

irm "https://christitus.com/win" | iex

Tip

In the "Install" section I usually install Firefox and 7-Zip: click corresponding checkboxes and "Install/Upgrade Selected". Wait until "Installation Done" at the top.

Go to "Tweaks".

I select all the "Essential Tweaks" except "Set Hibernation as default" and "Run Disk Cleanup". Also select these "Advanced Tweaks":

  • Disable Microsoft Copilot
  • Set Display for Performance
  • Set Time to UTC (Dual Boot)
  • Remove Microsoft Edge
  • Remove OneDrive

Caution

Don't remove Microsoft Edge without a new browser!

Then "Run Tweaks" at the bottom.

You can select all the preferences you need after the "Tweaks finished".

Tip

In the "Config" I select the following:

  • HyperV Virtualization
  • Disable Search Box Web Suggestions in Registry

It's a very good program itself, so I suggest you check out the features and documentation.

At this point, you are finished with this script. Close the PowerShell instance (not the script window).

Fast startup and hibernation

Note

Documentation: Dual boot with Windows - ArchWiki.

You need to disable this. From the ArchWiki (sourced from superuser website):

Data loss can occur if Windows hibernates and you dual boot into another OS and make changes to files on a filesystem (such as NTFS) that can be read and written to by Windows and Linux, and that has been mounted by Windows. Similarly, data loss can occur if Linux hibernates, and you dual boot into another OS etc.

Tip

winutil already does this, so you can skip it if you have done the necessary tweaks in the previous chapter.

To do this manually:

  1. Go to "Control Panel" (Windows search)
  2. Change "View by:" to "Large icons"
  3. Go to "Power Options"
  4. Click "Choose what the power button does"
  5. Click "Change settings that are currently unavailable"
  6. Untick "Turn on fast startup" and "Hibernate"
  7. Click "Save changes"

In my case I didn't even have these ticks, because the hibernation is disabled with winutil in the registry. You can check this with

powercfg /availablesleepstates

in PowerShell.

Tip

In the "Choose what the power button does" screen you can also change the behaviour of "When I press the power button", which is useful.

Time to UTC

Note

Documentation: System time - ArchWiki

ArchWiki:

If multiple operating systems are installed on a machine, they will all derive the current time from the same hardware clock: it is recommended to set it to UTC to avoid conflicts across systems.

Tip

winutil does this too.

However, the manual way:

First, you can do it with just one command:

reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f

Secondly, you can edit the registry manually:

  1. Open regedit
  2. HKEY_LOCAL_MACHINE
  3. SYSTEM
  4. CurrentControlSet
  5. Control
  6. TimeZoneInformation
    1. If RealTimeIsUniversal is present, it should be a REG_DWORD with data equal to 0x00000001 (1).
    2. If not, create this file by yourself with the right mouse button (RMB).

Bluetooth on Windows

Note

Documentation: Dual boot pairing - ArchWiki

It is important, because:

To pair devices on dual boot setups you need to change the pairing keys on your Linux install so that they are consistent with what Windows or macOS is using.

In total, you will need to boot the system two or three times:

  1. Pair in Windows, reboot, pair in Arch and change Arch keys to the Windows keys.
  2. Pair in Windows, reboot, pair in Arch, reboot and change Windows keys to the Arch keys.

The second method is used if the device only supports one pairing at a time. For example, my GK61XS wireless keyboard: it maps one key (as a pairing slot) to one device.

Anyway, here is the way to manually extract the keys from Windows.

Download PsExec and extract it to a folder of your choice.

Copy the path of the folder in the explorer and cd into it:

cd C:\Users\d\Downloads\PSTools

Run PSExec:

.\PsExec64.exe -s -i regedit.exe
# read and agree to the terms

Note

No, you can't just run regedit without PsExec. "The registry key containing the link keys may only be accessed by the SYSTEM account, which cannot be logged into." , and PsExec does this with the -s flag.

In the regedit window, search for:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys

Select the required Bluetooth adapter. It will probably be the only one.

All paired devices will be placed in the adapter folder.

Pair the required device and export the key:

  1. RMB on the adapter key (folder).
  2. Export to a folder of your choice.

Tip

I prefer to name it appropriately and move it to the flash drive. I have created a bluetooth folder for this purpose.

You can pair the next device (if necessary) and do the same. Just make sure you update the registry: open the "Keys" entry and the adapter folder again.

It's not as convenient (if you sync more than 2 devices), but it's possible to distinguish multiple devices if you save the registry file on each iteration.

Or you can just export the hex of the keys with the MAC addresses one at a time, that works as well.

These keys will be necessary later.

BitLocker

In Search, find "Manage BitLocker" and follow the steps to encrypt used disk space:

  1. "Turn on BitLocker"
  2. Skip until the recovery key back up
  3. Save the key to the flash drive (e.g. make the bitlocker folder)
  4. "Encrypt used disk space only ..."
  5. "New encryption mode ..."
  6. You can decide to not select "Run BitLocker system check". Otherwise you will have to reboot.
  7. Wait until the "BitLocker Encrypting" changes to "BitLocker on"

Warning

Store the key in a place where you can read it externally. Flash drive, another computer, etc..

Every time you update systemd-boot (whether it's the first time, a manual update, or a pacman hook - it doesn't matter), BitLocker will ask you for the encryption key.

For this reason, I decided to only update the boot loader manually from time to time, and keep the BitLocker key on my flash drive. Less safe, but it is what it is.

Thanks to https://github.com/Delta18-Git for heads up.

Turn off

After that, you are basically done with Windows. Reboot the device or turn it off and take a break.

Arch Linux

Boot from the flash drive

Important

By this point, Windows should have re-enabled the drive on the device as bootable, so manually disable it to boot from the flash drive.

LUKS on a partition

Note

Documentation: LUKS on a partition - ArchWiki.

Once the Arch Linux installation media is booted again, we are ready to proceed with the installation of the second operating system. This time we need to setup the encrypted root.

Basically, you are changing the type of the Linux root partition to the crypto container, and then only this container will have the Linux root partition, which you will see as /.

To create the container you have to format the partition with cryptsetup. After that, the system knows nothing about the internals of the container.

To get access to the container, you need to open it. As it should be, each open is followed by a close, so you'll have to do that too if you don't want access anymore.

After opening and mapping (assigning the root in the container), you can continue with the installation as normal.

Create the LUKS container

At this point, Windows should have created the Windows Recovery Environment partition. You can check this with:

export DISK=/dev/nvme0n1

fdisk -l "$DISK"

Windows should have allocated some space for the "Windows Recovery Environment" by shrinking it's own root partition.

In my case /dev/nvme0n1p5 is now Linux root (x86-64) because the4th partition is now Windows Recovery Environment.

export PART_LUKS="$DISK"p5

Then you need to create a new LUKS container. The defaults are OK and you can just enable the verbose output.

cryptsetup -v luksFormat "$PART_LUKS"

Note

You can find default options and other options right here.

Then type

YES

and enter your passphrase twice.

You can change the passphrase (or create multiple passphrases) later, but it's a good idea to choose a strong password from the start.

Also, don't forget or lose the passphrase!

Important

Immediately after formatting, you can save the headers. You'll need this to be able to decrypt the drive in case of corruption or simple loss of the passphrase.

In the guide I did this near the end, when I remembered how to manually mount a USB drive.

The actions are as follows:

cryptsetup luksDump "$PART_LUKS"
# check header presence

mount --mkdir /dev/sda1 /usb
# check if /dev/sda1 is your usb device. not ventoy partition

mkdir /usb/luks
# will get an error without that

export HEADER_BACKUP=/usb/luks/header.img
cryptsetup luksHeaderBackup "$PART_LUKS" --header-backup-file "$HEADER_BACKUP"

umount /usb

rm -rf /usb
# be careful

Even if you want to do it manually with the GUI later, don't forget to do it. It's important.

Open LUKS partition

Next, create a LUKS partition in the container.

export LINUX_ROOT=root # select preferred name for the root partition name
cryptsetup open "$PART_LUKS" "$LINUX_ROOT"

Note

v1 way:

cryptsetup luksOpen "$PART_LUKS" "$LINUX_ROOT"

It's the old syntax of the command. Remains for the compatibility. Thanks to https://github.com/enkvadrat for heads up.

Create filesystem

I will use Ext4:

export MAPPED_ROOT=/dev/mapper/"$LINUX_ROOT"

mkfs.ext4 "$MAPPED_ROOT"

# same as
mkfs.ext4 /dev/mapper/root
# it that's more clear

Mount root

export ROOT_MOUNT=/mnt

mount "$MAPPED_ROOT" "$ROOT_MOUNT"

Check the mapping works as intended

Note

Not a necessary step, but it's better to check.

umount "$ROOT_MOUNT"
cryptsetup close "$LINUX_ROOT"
cryptsetup open "$PART_LUKS" "$LINUX_ROOT"
mount "$MAPPED_ROOT" "$ROOT_MOUNT"

Tip

You can check the partitions at any time with lsblk or lsblk -f.

Mount ESP

export PART_ESP="$DISK"p1

mount --mkdir "$PART_ESP" "$ROOT_MOUNT"/boot

# same as
mount --mkdir /dev/nvme0n1p1 /mnt/boot

Continue with the normal installation

Note

Documentation: Installation guide - ArchWiki

Connect to the internet

ip link                       # check network interfaces
rfkill                        # should be "unblocked"
iwctl
device list                   # in my case I have "wlan0"
station wlan0 scan
station wlan0 get-networks    # find the ssid of your network
station wlan0 connect <ssid>
> ...                         # enter the passphrase for the network
exit

Check the connection:

ping archlinux.org            # ctrl + c to cancel

Install essential packages

Warning

  1. I am installing an AMD microcode package. If you have an Intel CPU, install the intel-ucode package instead!
  2. Also, I am installing linux-zen kernel. If you want to use the default kernel, consider installing linux. Next time I will refer to the kernel as <kernel>.
pacstrap -K "$ROOT_MOUNT" base base-devel linux-zen linux-firmware amd-ucode sudo networkmanager cryptsetup nano man-db man-pages sbctl

Package list, separated by newlines:

base
base-devel
linux-zen
linux-firmware
amd-ucode
sudo
networkmanager
cryptsetup
nano
man-db
man-pages
sbctl

You can use the following:

export KERNEL=linux-zen
export MICROCODE=amd-ucode

Generate fstab

export FSTAB="$ROOT_MOUNT"/etc/fstab
genfstab -U "$ROOT_MOUNT" >> "$FSTAB"

# same as
genfstab -U /mnt >> /mnt/etc/fstab

Check the result:

nano "$FSTAB"

If your MAPPED_ROOT (/dev/mapper/root) is present, as well as the boot mount, everything is OK.

Change root

arch-chroot "$ROOT_MOUNT"

Change timezone

export REGION=Europe
export CITY=Moscow
# set your region and city

ln -sf /usr/share/zoneinfo/"$REGION"/"$CITY" /etc/localtime
# set time zone

hwclock --systohc
# set hardware clock to utc

Generate locales

nano /etc/locale.gen

Uncomment the required locales, save and exit.

# in my case
en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8

Generate uncommented locales:

locale-gen

Set main locale:

nano /etc/locale.conf

Set main language:

# the file only has this one line:
LANG=en_US.UTF-8

Save and exit.

Set hostname

nano /etc/hostname
arch # set as you wish

Set root password

passwd

Configure mkinitcpio

Open current default config:

nano /etc/mkinitcpio.conf

Warning

If you have an AMD GPU (or APU), set the MODULES line to:

MODULES=(amdgpu)

I still get an AMD SECUREDISPLAY error on boot, but it's harmless.

Change the HOOKS line to:

HOOKS=(base systemd keyboard autodetect microcode modconf kms sd-vconsole block sd-encrypt filesystems fsck)

Create /etc/vconsole.conf:

nano /etc/vconsole.conf
# file contents
FONT=Lat2-Terminus16
FONT_MAP=8859-2

Note

You can select any font you want from /usr/share/kbd/consolefonts. Enter the file name without the file extension as FONT.

Regenerate:

mkinitcpio -p "$KERNEL"

Install boot loader

Check UEFI variables:

ls /sys/firmware/efi/efivars

If you see a long list of variables - you are ready to go.

Install systemd-boot:

bootctl install

Note

Last time I had bad timing and caught a bug:

Failed to get device path for 259:1: Bad file descriptor

To fix this, I downgraded systemd:

pacman -U https://archive.archlinux.org/packages/s/systemd/systemd-254.1-1-x86_64.pkg.tar.zst

Configure boot loader

nano /boot/loader/loader.conf
timeout 5
console-mode auto
editor no

Note

On other console-mode values (for example, max) the resolution will be stretched.

Create boot entries

With this command

blkid

you can get all the UUIDs of all the partitions in the GPT.

Find the PART_LUKS entry with TYPE=crypto_LUKS and take a picture of that UUID. You need the UUID, not the PARTUUID.

You will need to use this when editing the entries:

nano /boot/loader/entries/arch.conf

Common form of the file:

title Arch Linux
linux /vmlinuz-<kernel>
initrd /<microcode>.img
initrd /initramfs-<kernel>.img
options rd.luks.name=<luks-part-uuid>=root root=<mapped-root>

Example of the default kernel entry:

title Arch Linux
linux /vmlinuz-linux
initrd /amd-ucode.img
initrd /initramfs-linux.img
options rd.luks.name=<uuid>=root root=/dev/mapper/root

My entries are as follows:

# arch.conf
title Arch Linux (Zen)
linux /vmlinuz-linux-zen
initrd /amd-ucode.img
initrd /initramfs-linux-zen.img
options rd.luks.name=<luks-part-uuid>=root root=/dev/mapper/root
# arch-fallback.conf
title Arch Linux Fallback (Zen)
linux /vmlinuz-linux-zen
initrd /amd-ucode.img
initrd /initramfs-linux-zen-fallback.img
options rd.luks.name=<luks-part-uuid>=root root=/dev/mapper/root

Important

Don't forget to make the "Fallback" entry! It's the same as main entry (you can cp this file), but with different initramfs image.

Reboot

exit           # exit chroot
umount -R /mnt # ummount just in case
reboot         # or poweroff and boot manually

Eject the flash drive and boot up the device. You don't need it right now.

At the bootI enabled both devices in the UEFI.

You can now restart.

Note

If you get stuck on the load (the system does not prompt you for the passphrase), you probably entered the LUKS partition UUID incorrectly.

Insert the flash drive, go into UEFI and deselect all devices as bootable except the USB flash drive.

Launch the Arch installation medium. Open the LUKS container with cryptsetup open. Mount the mapped root and ESP, change the root into the /mnt:

mount /dev/mapper/root /mnt
mount /dev/nvme0n1p1 /mnt/boot
arch-chroot /mnt

Then correct the boot entries with the correct UUID from the blkid. Reboot and check.

Configuration

After booting, select your main Arch entry and enter your password to get to the login screen.

If everything is OK, the system will prompt you for the LUKS partition passphrase. Enter it.

Login as root with your password from passwd.

Network

# you can use the variables
# but it is probably faster to not do so

systemctl enable NetworkManager.service
systemctl start NetworkManager.service
# enable networkmanager

systemctl disable systemd-resolved.service
systemctl stop systemd-resolved.service
# disable other systemd network service
# just in case

nmcli device wifi connect <ssid> password <wifi-password>
# connect to the wifi

ping archlinux.org
# check connection

Add user

useradd -m -G wheel <username>
# dont' forget to add the password:
passwd <username>

Tip

If you get an error that the "wheel" or "users" group doesn't exist, just add it with groupadd <groupname>.

EDITOR=nano visudo
# Uncomment to allow members of group wheel to execute any command
%wheel ALL=(ALL) ALL

Save and exit.

Secure Boot

Note

Documentation: ArchWiki, comment on Reddit and sbctl wiki.

sbctl status
# expected output 1
Installed:   sbctl is not installed
Setup Mode:  Enabled
Secure Boot: Disabled
Vendor Keys: none

Caution

Before continuing, read carefully the ArchWiki page. It's a dangerous operation for some vendors, and can "brick" your device.

Create and enroll the keys:

sbctl create-keys
sbctl enroll-keys -m
sbctl status
# expected output 2
Installed:   sbctl is installed
Owner GUID:  ...
Setup Mode:  Disabled
Secure Boot: Disabled
Vendor Keys: microsoft
sbctl verify
# a long list of files to verify

Note

You can verify all the files (manually or with a script/command), but we don't need them all. In my scenario, only the 6 files below are needed.

export SIGN="sbctl sign -s"
export MS_EFI=/boot/EFI/Microsoft/Boot/

"$SIGN" /boot/vmlinuz-"$KERNEL"
# kernel

# example:
# sbctl sign -s /boot/vmlinuz-linux

# other files:

"$SIGN" /boot/EFI/Boot/bootx64.efi
"$SIGN" /boot/EFI/systemd/systemd-bootx64.efi
# systemd-boot

"$SIGN" "$MS_EFI"bootmgfw.efi
"$SIGN" "$MS_EFI"bootmgr.efi
"$SIGN" "$MS_EFI"memtest.efi
# windows

Verify:

sbctl list-files
# signed files should be here
pacman -S "$KERNEL"
# force package manager to update the kernel
# "pacman -Syu" doesn't necessarily work

# ensure that the strings
# "Running post hook: [sbctl]"
# and
# "Signing EFI binaries..."
# appear

Reboot, and before booting into Windows or Arch Linux, enable Secure Boot in UEFI. It enabled itself automatically in my case.

Make sure that Windows and Arch Linux boot correctly.

In the Arch Linux console you can type sbctl status once again. You should see Secure Boot: Enabled.

Bluetooth on Arch

Important

Check the Windows chapter on this topic before proceeding.

Install bluez and enable the service:

pacman -S bluez bluez-utils
systemctl enable bluetooth.service
systemctl start bluetooth.service

Warning

If you haven't installed the package and enabled the service, you won't have a /var/lib/bluetooth folder!

Connect the devices

bluetoothctl

scan on

pair <device-mac-address>
# for every needed device

devices Paired
# to check

Mount the USB

I stored the Bluetooth keys on my USB flash drive, so I have mounted the flash drive to access them:

mount --mkdir /dev/sda1 /usb
# after all operations do
# umount /usb
# rm -rf /usb

Sync keys

cd /var/lib/bluetooth

Then, cd into the needed controller. Probably, it's the only one.

For every device you need to do the following:

Go into the device folder and edit info file:

nano info

Swap

[LinkKey]
Key=...

with your key from Windows.

For example:

hex:69,27,6d,20,67,6f,6e,6e,61,20,6b,6d,73
# becomes
Key=69276D20676F6E6E61206B6D73

Save the file and do the same for the rest of the devices.

Restart the Bluetooth service:

systemctl restart bluetooth.service

Note

You are probably doing this to connect audio devices. If so, install the audio packages:

# i use pipewire
pacman -S wireplumber pipewire pipewire-pulse

And restart these services after restarting the bluetooth service:

systemctl --user restart wireplumber pipewire pipewire-pulse

Everything else

You are free to use your own configuration. In my case, I use my dotfiles:

chezmoi init shimeoki
chezmoi apply

Caution

Don't apply these dotfiles before checking the "Installation" in the README. It's probably broken.

Resources

This is a list of all the links I have mentioned in this guide. They are listed in the order they are mentioned in the text.

  1. https://gist.github.com/orhun/02102b3af3acfdaf9a5a2164bea7c3d6
  2. https://archlinux.org/download/
  3. https://www.microsoft.com/en-us/software-download/windows11/
  4. https://www.ventoy.net/en/index.html
  5. https://www.ventoy.net/en/doc_mbr_vs_gpt.html
  6. https://en.wikipedia.org/wiki/Insyde_Software#InsydeH2O_UEFI_BIOS
  7. ventoy/Ventoy#2825
  8. https://github.com/linux-nvme/nvme-cli
  9. https://wiki.archlinux.org/title/Solid_state_drive/Memory_cell_clearing#NVMe_drive
  10. https://wiki.archlinux.org/title/Solid_state_drive/Memory_cell_clearing#Sanitize_command
  11. https://wiki.archlinux.org/title/fdisk
  12. https://github.com/massgravel/Microsoft-Activation-Scripts
  13. https://github.com/ChrisTitusTech/winutil
  14. https://wiki.archlinux.org/title/Dual_boot_with_Windows#Windows_settings
  15. https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows
  16. https://wiki.archlinux.org/title/Bluetooth#Dual_boot_pairing
  17. https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/local-accounts#system
  18. https://wiki.archlinux.org/title/dm-crypt/Encrypting_an_entire_system#LUKS_on_a_partition
  19. https://wiki.archlinux.org/title/Dm-crypt/Device_encryption#Encryption_options_for_LUKS_mode
  20. https://wiki.archlinux.org/title/installation_guide
  21. https://bugs.archlinux.org/task/79619
  22. https://wiki.archlinux.org/title/Unified_Extensible_Firmware_Interface/Secure_Boot
  23. https://www.reddit.com/r/archlinux/comments/ug9pu0/comment/i72v541
  24. https://github.com/Foxboron/sbctl/wiki/Linux-Windows-Dual-Boot-with-Windows-Bitlocker
  25. https://github.com/shimeoki/dotfiles

Also, if you found my text strange, that could be because of the DeepL Write assistance. Link: https://www.deepl.com/en/write

@shimeoki
Copy link
Author

Hey, were you able to resolve sound issues? I have HUAWEI MateBook D 15 BoDE-WXX9, so I will very likely have them too, which is quite discouraging.

good news! sound works now. probably recently some drivers were added on the kernel level.

for all people who are still experiencing these issues, here is my setup:

  • arch with linux-zen kernel (6.13.3-zen1-1-zen)
  • pipewire with all optional packages from archwiki (pipewire-alsa/audio/jack/pulse/session-manager, wireplumber, etc.)
  • pipewire.service, pipewire-pulse.service and wireplumber.service active systemd user units

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment