A fresh installation of Arch Linux

2026-03-13

Linux

Introduction

I have recently started a new job, and my employer was kind enough to order a brand new laptop for me, carefully preconfigured with Windows and all the software everybody needs and loves, such as Excel, Cisco’s VPN software, and the remote desktop client. Naturally, the best way to show my appreciation and live up to the boss’s trust is to wipe everything they set up and install Linux instead. 😇 Just kidding, of course my boss is informed and the company policy allows installing Linux, it’s just that they don’t offer any kind of support should I ever have problems with the laptop. Well, I’m the kind of person who gets excited when there are Linux problems, so this situation suits me well. Besides, it’s not like I’ve completely wiped everything out, I made a dual boot setup which kept the original Windows alongside Linux. Honestly, I doubt I’ll ever boot Windows again, but it’s nice to have it just in case. The setup I wanted is slightly unconventional, but tailored to my specific needs and taste. I have also tried some things which I had never done before, and I’d like to document the process. There will also be a part 2 where I talk about the post-installation steps (for example, how I’ve decided to embrace Hyprland and its ecosystem). I’m writing this mostly for myself, but should you have similar needs, feel free to read my experience and leave me a comment below. Here is a summary of the problems I encountered along the way.

  • Logging into Windows as admin
  • Resizing the Windows partitions
  • Connecting to WiFi in Arch Linux

Why not Windows

  1. Windows is not for me.

Computers are incredible, you can program and make them do literally anything. As turing machines, they can emulate any computational process in the universe. With Windows, this is not true anymore: I can only do what Mommy Microsoft thinks I want to do. They pre-programmed the computer so that I can only have this or that behaviour. I just don’t like the behaviours they implemented, I want to set up my own.

  1. Windows is really slow.

Using it feels like browsing the internet on the hotel WiFi. Every time I have to use a microsoft product, especially cloud, I cry inside. The workflows for using software like powerpoint, excel, and word are incredibly limited. Sure, they may work well enough for 80% of people, but not for me.

  1. Microsoft is an evil company.

There is plenty of evidence about this.

Arch Linux Installation

With that being said, let’s talk about what I want for my setup. At a high level, these are the not-negotiable features.

  • Dual boot (I should still keep Windows, just in case)
  • Disk encryption at rest (I may have to work with sensitive data, but even my personal files would be sensitive enough)
  • Arch Linux (Mostly because it’s a rolling release, I’m not a fan of having to reinstall the OS just to upgrade the packages)
  • LVM partitioning (eventually, the pacman cache always becomes too big for any partition)

Check out part 2 for the post-installation steps (TODO: insert link).

First problem: logging into Windows as admin

My company is not super strict with its policy and they kindly grant us admin access. So I was a bit surprised when I entered the correct credentials and found myself locked out. I knew it wouldn’t be a big deal, after all I hacked into a company MacBook last year where in theory I didn’t have full admin access. But the fix was much easier than I thought. It turns out that I got access denied because I was not connected to the company’s network.

We can’t sign you in with this credential because your domain isn’t available. Make sure your device is connected to your organization’s network and try again. If you previously signed in on this device with another credential, you can sign in with that credential.

Why? Surely it can’t be a security measure? It doesn’t seem like it, because I found that I can just use the prefix .\ before the username to use the local admin user rather than the remote, corporate one, and at least in my case I could do everything with this local user. Connecting to the company’s network was out of questions since I work in a different city than the one where the main campus is located. Anyways, now that I hacked into my own laptop I can finally start the process of resizing the partitions.

The first thing I had to do was disabling BitLocker, otherwise the disk would be encrypted when I try to install Linux and I wouldn’t be able to make any partitions. I re-enabled it afterwards, when all was said and done.

Then, I tried to resize the partitions. One of the reasons was to make space for Linux. I decided to leave 95GB to Windows’s C:\\ drive, it should be enough for the very limited use I’ll make of it. But besides shrinking the C:\\ partition, I also had to expand the EFI partition. That’s right, the kernel image and firmware files can take quite a bit of space, but unfortunately my EFI partition was a measle 100MB, clearly not enough. It’s not entirely clear why Windows makes it so small by default. I used the Windows disks utility to make the changes, but that didn’t allow me to resize the EFI partition. I tried downloading at least two third-party tools advertised as partitions resizer, but none of them was able to modify the EFI partition, at least in the free plan. In the end I used Paragon Partition Software (community edition), although I think I could have done the same with the stock disks utility. Again, it’s not clear why it has to be so difficult. It’s almost as if Microsoft wanted to make life harder for people trying to install another operating system. But I wouldn’t expect such tricks from them, would I?

Here is the original partition layout:

N. Partition Size
1 EFI partition 100MB
2 MSR partition 16MB
3 C: drive ~950GB
4 Windows recovery ~800MB

And the final result was as follows. Note that at this point the EFI partition has some space to the right, but it hasn’t been resized yet. I thought I could do it later with fdisk.

N. Partition Size
1 EFI partition 100MB
- Free space 900MB
2 MSR partition 16MB
3 C: drive ~95GB
- Free space ~850GB
4 Windows recovery ~800MB

The hidden MSR partition, of just 16MB, is apparently not strictly needed (see here), but I decided to leave it be, since it doesn’t harm too much.

Making the Linux partitions with LVM

At this point I could finally get rid of Windows and boot the Arch Linux live ISO. On this laptop I have to press F12 during startup (without the fn key) to load the bios settings. The first thing I did was connecting to the WiFi to get network access, which will be needed later, when installing the packages. All I had to do was run the command

iwctl

and follow the instructions. I kind of liked this utility and decided to use it also after the system was installed, instead of having a network manager. I still need to figure out how to connect through cable, but that’s a problem for the future.

Now, on with the partitioning. One thing I had to be mindful about was the alignment of the partitions. Modern fdisk should handle that correctly, but I still found two commands useful for checking.

lsblk -td
nvme id-ns -H /dev/nvme0n1 | grep Performance

Both these commands told me that the logical size is 512B and it cannot be changed. Later, when I formatted and encrypted the partitions, I had to make sure that the size was 512B as well. Anything else would introduce overhead.

I used the trusted fdisk to extend the EFI partition to 1GB and create a new partition for Linux in the free space after C:\\. The final layout was as follows.

N. Partition Size
1 EFI partition 1GB
2 MSR partition 16MB
3 C: drive ~95GB
5 Linux partition ~850GB
4 Windows recovery ~800MB

The only annoyance is that the Linux partition is /dev/nvme0n1p5 although it comes before the windows recovery partition, which is /dev/nvme0n1p4. Changing the order can be done in fdisk by entering x to go into expert mode, f to fix the order, and r to return to the main menu (see here), but I didn’t bother to do it. Now that we have a physical partition for Linux, it’s time to encrypt it with LUKS and create the logical partitions with LVM.

Disk encryption and logical partitions

For this I simply followed the LVM on LUKS guide in the Wiki. In 2026 I think encryption at rest should be mandatory for everyone. Besides, my employer handles very sensitive healthcare data, and although I’m not planning to keep any sensitive data on the laptop, I want to be extra safe in case the laptop gets lost or stolen. Here are the commands I ran to set everything up.

cryptsetup luksFormat /dev/nvme0n1p5
cryptsetup luksDump /dev/nvme0n1p5

(Incidentally, the above command confirmed that the sector size was 512 bytes.)

cryptsetup open /dev/nvme0n1p5 cryptlvm

Basically, the above commands encrypted the 850GB partition, so from now on I need to enter a password every time I want to read from that partition. I then created the logical volume group and logical partitions inside such encrypted partition. My typical partition setup is: one for /root, one for /var, one for /home, and one swap partition. The swap partition is necessary for hibernation, but separating /root, /var, and /home is not really necessary. As far as I understand, it can be useful in a bunch of cases.

  • The home partition doesn’t need to be touched if you reinstall the operating system
  • Some people like to have different file systems for /home and /root
  • If /root or /var get full because of logs or the pacman cache, /home can still be used (and vice versa, if /home gets full, you can still boot the system)

In my experience with laptops I have almost never taken advantage of these benefits, but still, I like to do the partitions like this. I decided to format everything with ext4, because, as said, this is a laptop and I don’t need anything fancy. I see my laptop mostly as a lightweight terminal that I just use to connect to the machines that do the real work, such as those in the HPC cluster or the web servers. So, here are the commands I used to create and format the logical partitions.

vgcreate cryptvg /dev/mapper/cryptlvm
lvcreate -L 85G -n rootvol cryptvg
lvcreate -L 50G -n varvol cryptvg
lvcreate -L 32G -n swapvol cryptvg
lvcreate -l 100%FREE -n homevol cryptvg
lvreduce -L -256M cryptvg/homevol # leave 256M at the end to allow using e2scrub
mkfs.ext4 /dev/cryptvg/rootvol
mkfs.ext4 /dev/cryptvg/varvol
mkfs.ext4 /dev/cryptvg/homevol

At this point I realized that, although I resised the EFI partition, the FAT32 filesystem remained at the same size of 100MB. There is a fatresize command, but it cannot resize filesystems which are smaller than 256MB. So what I ended up doing was:

  1. Mount the EFI partition
  2. cp -ar the files to another location
  3. Unmount the EFI partition and recreate the FAT32 filesystem from scratch with mkfs.fat32
  4. cp -ar the file back to the EFI partition
  5. Kept fingers crossed that the file permissions and attributes wouldn’t be screwed up

Finishing the installation

At this point, all that remains to do is a pretty standard Arch Linux installation. I mounted the partitions at /mnt with the proper filesystem structure, then ran pacstrap to install the OS. Here I am not reporting all the commands I run, so please refer to the Arch Wiki for the full story.

mount /dev/cryptvg/rootvol /mnt
mount --mkdir /dev/cryptvg/varvol /mnt/var
mount --mkdir /dev/cryptvg/homevol /mnt/home
mount --mkdir /dev/nvme0n1p1 /mnt/boot
swapon /dev/cryptvg/swapvol
pacstrap -K /mnt \
  base \
  linux \
  linux-firmware \
  amd-ucode \
  e2fsprogs \
  lvm2 \
  iwd \
  nano \
  man-db \
  man-pages \
  texinfo \
  coreutils

There was one pacman error: /etc/vconsole.conf not found. Probably I screwed up something about locales and/or keyboard layouts. From a quick search it looked like the content of this file wasn’t super important, so I simply created an empty one in /mnt/etc and tried the pacstrap command again. After this, I followed the Arch installation guide for genfstab, chrot, time, localization, and hostname.

Boot loader

Because I use LVM and disk encryption, I had to make sure that the relevant hooks were added to the mkinitcpio configuration. Thus, I added lvm2, sd-encrypt, keyboard, and sd-vconsole to the HOOKS part in /etc/mkinitcpio.conf, and regenerated the image with

mkinitcpio -P

Next I added the boot loader. I decided to use grub, since I know it supports dual booting, encryption, and LVM out of the box.

pacman -S grub efibootmgr os-prober
grub-install --target=x86_64-efi --efi-directory=esp --bootloader-id=GRUB

I still wanted to have Windows as an option displayed in the boot menu, and for that I decided to use os-prober. After installing os-prober, I edited /etc/default/grub and uncommented the following line

GRUB_DISABLE_OS_PROBER=false

Then I regenerated the config with

grub-mkconfig -o /boot/grub/grub.cfg

There was still a bit of configuration for encryption and LVM: I had to tell the kernel which volume it should decrypt and where to find the root partition. The Arch Wiki page for this was very detailed. First, I used

blkid /dev/nvme0n1p5

to find the UUID of the Linux partition. Then I added this to /etc/default/grub (replacing the UUID with the correct one) at the end of GRUB_CMD_LINUX_DEFAULT:

rd.luks.name=9dddd787-555a-4r4b-jk71-0a12345678az=cryptlvm root=/dev/cryptvg/rootvol

I had read somewhere that GRUB2 doesn’t yet support some types of encryption. However, this is only true when the /boot partition itself is encrypted. In my case, /boot is shared with Windows and is not encrypted, so everything works.

Finishing touches (and one last problem with networking)

After rebooting and making sure that everything worked, I went back to Windows to re-enable BitLocker. Then, I came back to Linux, only to find out that networking wasn’t networking. Internet seemed unreachable even after systemctl start iwd. I thought it was because I didn’t instally any wireless card drivers, but it turned out I was just missing the DHCP configuration. When I ran ip a, I realized that I didn’t have an IPv4, but I had an IPv6. Indeed, I could actually ping -6 google.com, but not with ping -4. IWD does have a built-in DHCP client, but it needs to be explicitly activated (in the Live ISO, it is already active). Thus, I created /etc/iwd/main.conf and wrote

[General]
EnableNetworkConfiguration=true

IWD still doesn’t have a DNS resolver, so I also have to systemctl start systemd-resolved. In practice, I don’t use a network manager and the iwd unit is not even enabled by default. So, every time I boot, if I want to surf the internet, I have to do

systemctl start iwd
systemctl start systemd-resolved

This works for WiFi, but I haven’t had a chance to connect to a wired network yet, so I’ll have to find out how to connect in that way later.

Summary

Overall, I am pretty happy with this setup. I think I managed to keep things minimal and nicely working. Initially I was a bit afraid of encrypting the disk: I had a bad experience in the past and kinda lost some data. But this time I realized it is actually pretty easy. The big question is which event will be the rarest, booting Windows or resizing the LVM partitions? Only time will tell. I also had a lot of fun tweaking the Hyprland configuration, revamping my dotfiles, and enabling extreme battery-saving optimizations. I wrote about these things in part 2 and part 3.

 Marginalia

Leave a comment