Skip to content

Instantly share code, notes, and snippets.

@shimeoki
Last active April 16, 2024 21:16
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • 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) with encrypted partitions (BitLocker and LUKS) and UEFI/Secure Boot

My Windows 11 + Arch Linux dual-boot installation

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

Warning!

All actions are at your own risk!

Table of Contents

Hardware

HUAWEI MateBook D 15 BoM-WFQ9

  • AMD Ryzen 5 5500U
  • 16GB DDR4
  • 512GB SSD

Warning!

Sound from speakers or wired headphones under Linux doesn't work on this laptop. Bluetooth headphones will, however. Windows works fine.

Pre-installation

Required:

  • PC or laptop with stable power supply
  • Ventoy flash drive with Windows 11 and Arch Linux .iso files
  • Internet (Wi-Fi)
  • Free time

Disabling Secure Boot

Simply go into your UEFI and disable Secure Boot. Otherwise you won't be able to boot from the flash drive. We'll enable it after installation.
In my case, I have to press F2 after turning on my laptop to get into InsydeH2O.

Cleaning NVMe drive

Documentation: Memory cell clearing - ArchWiki

Boot from your flash drive, select your Arch Linux .iso file and boot it in normal mode.

If you see the "Perform MOK Management" window, simply select "Enroll key from disk" and select the appropriate key. You can read more here.

Check drives

nvme list

In my case I have /dev/nvme0. I'll use this name in future commands.

Check the available formatting methods

nvme id-ctrl /dev/nvme0 -H | grep "Format \|Crypto Erase\|Sanitize"

In my case I have [1:1] : 0x1 Block Erase Sanitize Operation Supported. Crypto Erase Sanitize or Overwrite Erase Sanitize are not available for me.

Perform a block erase

Warning!

This operation will erase all information on the drive.

nvme sanitize /dev/nvme0 -a 0x02

Check completion

nvme sanitize-log /dev/nvme0
Sanitize Progress                      (SPROG) :  65535
Sanitize Status                        (SSTAT) :  0x101

In my case it took 5-10 seconds, but ArchWiki says that it can take for 2-3 hours. When you'll see Sanitize Status ... 0x101 you're ready to proceed.

Verify cleaning

dd if=/dev/nvme0n1 bs=8192 status=progress | hexdump
0000000 0000 0000 0000 0000 0000 0000 0000 0000
*
...

If you see only zeros, you can press Ctrl+C and you are done. If not, repeat the steps above.

Partition the disk

Documentation: fdisk - ArchWiki

Check current partitions

fdisk -l /dev/nvme0n1

As we have cleaned the drive, there should be nothing left.

Proceed with fdisk

fdisk /dev/nvme0n1
> g    # Create new GPT.
> n    # Create new partition.

       # Then skip until `Last sector,...` and enter:

> +1G  # Size 1G for our EFI system partition.

You can check the current partitioning with p.

Create MSR partition

Repeat steps above for 16M partition.

Create root partitions

I won't add a swap partition and will split my drive 50%/50%.

# Math time.
476.94 * 1024 = 488386.56 (total MB on drive)
488386.56 - 1016 = 487370.56 (remaining MB on drive)
487370.56 / 2 = 243685.28 (splitted partitions in MB)
243685.28 / 1024 = 237.97... (splitted partitions in GB)

So I'm going to divide by 238G.
Repeat the steps in Proceed with fdisk, but specify the size of the partitions. One will be Windows root and the other will be Arch Linux root. Create the first partition and for the second partition enter the last sector on the drive instead of the size.

Change partition types

> t
> 1   # Select the first partition.
> 1   # Change type to ESP (EFI System Partition).
> t
> 2   # Select the second partition.
> 10  # Change type to MSR partition.
> t
> 3   # Select the third partition.
> 11  # Change type to Windows Basic Data.

Last partition for Linux root can be left untouched.

Write changes and check

> w
fdisk -l /dev/nvme0n1

Format ESP

mkfs.fat -F 32 /dev/nvme0n1p1

This is not necessary, but I did it anyway.

Windows 11 installation and configuration

Install Windows 11 from .iso file

Select your Windows 11 .iso file and boot it in normal mode.

If you want to get less bloatware, select Time and currency format: English (World) on the first screen. If you try to do this, you will get an OOBEREGION error later. Just skip it.

Just do a normal install, choose custom partitioning and select the third partition. Don't do anything else on this screen, because we've done everything we need to do in Partition the disk.

Install browser

After installing Windows, don't forget to install your preferred browser. In my case, I'm going to install Firefox. Just go to Microsoft Edge, skip everything, install and continue.

Activate your system

Microsoft Activation Scripts

Run Powershell as administrator:

irm https://massgrave.dev/get | iex
> 1  # Permanent HWID activation.
> 0
> 0

Clean your system with winutil

Run Powershell as administrator:

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

Powershell will ask you to install Chocolatey. Accept and continue. Select 'Tweaks', select the profile you want and tick 'Remove Microsoft Edge' and click 'Run Tweaks'. You can now close everything.

Set up BitLocker

In Search, find "Manage BitLocker" and follow the steps to encrypt used disk space.
You'll need a flash drive to store the recovery key file. Wait for the system to encrypt the entire system partition.

The system will prompt you for your BitLocker recovery key when you restart, so don't lose it!

Disable fast startup and hibernation

Documentation: ArchWiki.

Go to "Control panel" => Change "View by:" to "Large icons" => "Power options" => "Choose what the power button does" => "Change settings that are currently unavailable" => Remove ticks on "Turn on fast startup" and "Hibernate" => "Save changes".

Change Windows time to UTC

Documentation: ArchWiki.

You have two ways:

  1. Execute regedit and find HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation\RealTimeIsUniversal. Add DWORD value with hexadecimal value 1.
  2. Simply type reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\TimeZoneInformation" /v RealTimeIsUniversal /d 1 /t REG_DWORD /f in Command Prompt as administrator.

After restarting, change the time zone and region to yours in Settings.

Connect Bluetooth devices

If you plan to use a Bluetooth headphones (as in my case), pair it now and check the sound. We'll need it later.

Arch Linux installation and configuration

Set up LUKS on a partition

Documentation: LUKS on a partition - ArchWiki.

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

fdisk -l /dev/nvme0n1

In my case /dev/nvme0n1p5 is Linux Filesystem because 4th partition is now Windows Recovery Environment.

cryptsetup -y -v luksFormat /dev/nvme0n1p5
> YES

Then enter your passphrase twice.

Open LUKS partition

cryptsetup luksOpen /dev/nvme0n1p5 root
mount /dev/mapper/root /mnt

You can check encryption with:

cryptsetup luksDump /dev/nvme0n1p5

Create filesystem

mkfs.ext4 /dev/mapper/root

Check the mapping works as intended

umount /mnt
cryptsetup luksClose root
cryptsetup luksOpen /dev/nvme0n1p5 root
mount /dev/mapper/root /mnt

Mount ESP

mount --mkdir /dev/nvme0n1p1 /mnt/boot

Continue with normal installation

Documentation: Installation guide - ArchWiki

Connect to the internet

ip link                       # Check network interface.
rfkill                        # "unblocked"
iwctl
device list                   # In my case I have "wlan0".
station wlan0 scan
station wlan0 get-networks    # Find your SSID.
station wlan0 connect <ssid>
> ...                         # Enter passphrase.
exit

Check connection:

ping archlinux.org            # Ctrl+C to cancel.

Install essential packages

pacstrap /mnt base base-devel linux linux-firmware sudo nano networkmanager

Generate fstab

genfstab -U /mnt >> /mnt/etc/fstab
nano /mnt/etc/fstab

Change root

arch-chroot /mnt

Change timezone

ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime  # Enter your "Region/City".
hwclock --systohc

Generate locales

nano /etc/locale.gen

Uncomment the required locales, save and exit.

locale-gen
nano /etc/locale.conf
LANG=en_US.UTF-8

Save and exit.

Set hostname

nano /etc/hostname
BOM-WFQ9

Set root password

passwd

Configure mkinitcpio

Open current mkinitcpio:

nano /etc/mkinitcpio.conf

Change HOOKS line to:

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

and MODULES line to:

MODULES=(amdgpu)

Only if you have an AMD GPU.

Regenerate:

mkinitcpio -p linux

Install microcode

pacman -S amd-ucode  # intel-ucode for Intel

Install boot loader

Check UEFI variables:

ls /sys/firmware/efi/efivars

I'll use systemd-boot.

bootctl install

I had bad timing and caught a bug:

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

To fix it, just downgrade 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

Create Arch Linux boot entry

nano /boot/loader/entries/arch.conf
title Arch Linux
linux /vmlinuz-linux
initrd /amd-ucode.img
initrd /initramfs-linux.img
options rd.luks.name=<luks-partition-uuid>=root root=/dev/mapper/root

I recommend finding the UUID with lsblk -f and taking a picture. You need the UUID of the crypto_LUKS partition, not the root!

You can now restart.

Configuration

Do this after booting to a fresh operating system.

Set up network

systemctl enable NetworkManager.service
systemctl start NetworkManager.service
systemctl disable systemd-resolved.service
nmcli device wifi connect <ssid> password <wifi-password>

Add user

useradd -m -G wheel <username>

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

EDITOR=nano visudo
# Uncomment this line:
%wheel ALL=(ALL) ALL

Install desktop environment

I'll use GNOME:

pacman -S gnome
systemctl enable gdm.service

Install TLP

Only for laptops.

pacman -S tlp
systemctl enable tlp.service

Enabling Secure Boot

Documentation: ArchWiki, comment on Reddit and sbctl wiki.

Do it as root, otherwise you'll have to use sudo.

pacman -S sbctl
sbctl status
# Installed: sbctl is not installed
# Setup Mode: Enabled
# Secure Boot: Disabled
# Vendor Keys: none
sbctl create-keys
sbctl enroll-keys -m
sbctl status
# Installed: sbctl is installed
# Owner GUID: ...
# Setup Mode: Disabled
# Secure Boot: Disabled
# Vendor Keys: microsoft
sbctl verify
# A lot of lines, but we only need to sign 6 files.
sbctl sign -s /boot/vmlinuz-linux
sbctl sign -s /boot/EFI/Boot/bootx64.efi
sbctl sign -s /boot/EFI/systemd/systemd-bootx64.efi
sbctl sign -s /EFI/Microsoft/Boot/bootmgfw.efi
sbctl sign -s /EFI/Microsoft/Boot/bootmgr.efi
sbctl sign -s /EFI/Microsoft/Boot/memtest.efi

Verify:

sbctl list-files
# They should be listed.
pacman -S linux
# Ensure that the string "Signing EFI binaries..." appears.

Reboot, and before booting into Windows or Arch Linux, enable Secure Boot in UEFI. Make sure that Windows and Arch Linux boot correctly. In the Arch Linux console you can check sbctl status. You should see Secure Boot: Enabled.

Bluetooth dual-boot configuration

Configure audio

I recommend doing all commands as root.

pacman -S pipewire
pacman -S pipewire-pulse
# Replace conflicting packages
pacman -S bluez
systemctl enable bluetooth.service
systemctl start bluetooth.service

Sync keys

I only connect one Bluetooth 5.0 device. Actions may be different.

Documentation: Dual boot pairing - ArchWiki

Since we have paired the Bluetooth device with Windows, we should get the pairing key from Windows and replace the current key in Arch Linux with it.
Download PsExec and extract it to a folder of your choice. Run Powershell or Command Prompt as an administrator and run regedit:

.\PsExec64.exe -s -i regedit.exe

In the regedit window, search for HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys and select the required Bluetooth adapter. RMB on the key and export it as a .reg file in to a location of your choice. Then go to that file, open it with Notepad and take a picture of the hex key.
Boot into Arch Linux and follow the steps below:

  1. As root run:
cd /var/lib/bluetooth
  1. Get your <bt-adapter-mac-address> with dir and run cd <bt-adapter-mac-address> (you can enter first symbol and press Tab).
  2. Check desired device with dir and run cd <device-mac-address.
  3. Edit info file:
nano info
  1. Swap Key=... with your key from Windows. For example: hex:69,27,6d,20,67,6f,6e,6e,61,20,6b,6d,73 is 69276D20676F6E6E61206B6D73.
  2. Save, exit and restart Bluetooth and audio services:
systemctl restart bluetooth.service
systemctl --user restart wireplumber pipewire pipewire-pulse
  1. Profit.

Ending

Thank you for reading this far! I'm fairly new to Linux, so I've probably made a mistake somewhere. I'd be grateful if you could report any errors in this text.

@enkvadrat
Copy link

I believe you now need to use cryptsetup open instead of cryptsetup luksOpen

@shimeoki
Copy link
Author

I believe you now need to use cryptsetup open instead of cryptsetup luksOpen

cryptsetup-open manual page:

For backward compatibility there are open command aliases:
...
luksOpen: open --type luks

so, luksOpen is just a backwards compatibility alias for the default cryptsetup open action, and i don't think it will be deprecated anytime soon. but it's still a good point to include all possible commands and not prefer legacy variants, thank you. i plan to revise this gist in the near future, as this installation was literally my first experience with linux, so i'll be making many changes of this kind

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