Skip to content

Instantly share code, notes, and snippets.

@mikilian
Forked from mattiaslundberg/arch-linux-install
Last active August 10, 2022 20:19
Show Gist options
  • Save mikilian/bfea5f005c0e2a0121806fa360fc1d12 to your computer and use it in GitHub Desktop.
Save mikilian/bfea5f005c0e2a0121806fa360fc1d12 to your computer and use it in GitHub Desktop.
Minimal instructions for installing arch linux on an UEFI system with full system encryption using dm-crypt and luks

Install Arch Linux with encrypted file-system and UEFI

The official installation guide contains a more verbose description.

Prepare your bootable USB-drive

  1. Download the .iso image from https://www.archlinux.org/
  2. Verify the signature
  3. Backup your data!
  4. Copy the .iso to a USB-drive
    • macOS/Unix: dd if=archlinux.img of /dev/sdX bs=16M && sync
    • Windows: Etcher or Rufus
  5. Reboot and enter the boot menu
    • Disable secure boot
  6. Boot from the USB-drive

Arch Linux installation

This guide uses /dev/nvmeXn1 as an example for the respective hard disk or /dev/nvmeXn1p{1,2,3} for the partitions of the hard disk.

NVMe (M2) SATA
/dev/nvmeXn1 /dev/sdX
/dev/nvmeXn1p{1,2,3} /dev/sdX{1,2,3}
  1. Set your keymap (german in my case): loadkeys de-latin1

  2. If a WIFI connection is needed, establish it with iwctl

  3. Create and format partitions

    WARNING: the following step will delete all data on the selected hard disk. Make sure that you have created a backup.

    1. cgdisk /dev/nvmeXn1
    2. Delete all existing partitions using the navigation menu or by pressing D
    3. Create the EFI partition (N)
      1. Use the default value for the first sector (Enter)
      2. Type +100M for the size in sectors and press Enter
      3. Use the hex code ef00 to set the EFI flags and press Enter
      4. Use the default value for the partition label (Enter)
    4. Create the boot partition (N)
      1. Use the default value for the first sector (Enter)
      2. Type +250M for the size in sectors and press Enter
      3. Use the default hex code 8300 and press Enter
      4. Use the default value for the partition label (Enter)
    5. Create the root partition (N)
      1. Use the default value for the first sector (Enter)
      2. Type 100% for the size in sectors and press Enter
      3. Use the default hex code 8300 and press Enter
      4. Use the default value for the partition label (Enter)
    6. Write all changes by pressing W and quit cgdisk
  4. Format the EFI and boot partitions

    • EFI: mkfs.vfat -F32 /dev/nvmeXn1p1
    • Boot: mkfs.ext2 /dev/nvmeXn1p2
  5. Setup the encryption of the system

  cryptsetup -c aes-xts-plain64 -y --use-random luksFormat /dev/nvmeXn1p3
  cryptsetup luksOpen /dev/nvmeXn1p3 luks
  1. Create encrypted partitions

This creates one partions for root, modify if /home or other partitions should be on separate partitions

pvcreate /dev/mapper/luks
vgcreate vg0 /dev/mapper/luks
lvcreate --size 16G vg0 --name swap
lvcreate -l +100%FREE vg0 --name root
  1. Create filesystems on encrypted partitions
mkfs.ext4 /dev/mapper/vg0-root
mkswap /dev/mapper/vg0-swap
  1. Mount the new system
mount /dev/mapper/vg0-root /mnt # /mnt is the installed system
swapon /dev/mapper/vg0-swap
mkdir /mnt/boot
mount /dev/nvmeXn1p2 /mnt/boot
mkdir /mnt/boot/efi
mount /dev/nvmeXn1p1 /mnt/boot/efi
  1. Install the system also includes stuff needed for starting wifi when first booting into the newly installed system

For Intel and AMD processors, microcode is still required. Append intel-ucode or amd-ucode to the pacstrap command.

You may want to add dialog, wireless_tools, iw, crda and wpa_supplicant to the pacstrap command if you need a WIFI connection

pacstrap /mnt base base-devel dhcpcd efibootmgr git gptfdisk grub-efi-x86_64 lvm2 linux linux-firmware zsh vim
  1. Initialize fstab: genfstab /mnt >> /mnt/etc/fstab
  2. Optional: make /tmp a ramdisk by adding the following line in /mnt/etc/fstab
tmpfs   /tmp      tmpfs     defaults,noatime,mode=1777    0 0
  1. Change relatime on all non-boot partitions to noatime in /mnt/etc/fstab (reduces wear if using an SSD)
  2. Enter the new system: arch-chroot /mnt /bin/bash
  3. Setup system clock
ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime
hwclock --systohc --utc
  1. Set the hostname echo MYHOSTNAME > /etc/hostname (obv. replace MYHOSTNAME with your intended hostname)
  2. Update the hosts file: vim /etc/hosts

If the system has a permanent IP address, it should be used instead of 127.0.1.1 - Arch Wiki.

# Static table lookup for hostnames.
# See hosts(5) for details.
127.0.0.1     localhost
::1           localhost
127.0.0.1     arch        arch
  1. Open /etc/locale.gen with vim and generate the locales using locale-gen

    • Search for en_US.UTF-8 UTF and remove the # character
    • Repeat this for all wanted locale
    • Run echo LANGUAGE=en_US.UTF-8 >> /etc/locale.conf
    • Optional vim into /etc/vconsole.conf and add KEYMAP=layout
  2. Set password for the root user: passwd

I had problems with vi using visudo, so I created a symlink as hacky workaround: ln -s /usr/bin/vim /usr/bin/vi

  1. Setup the user account

    1. Create a new user and add them to the wheel group: useradd -m -g users -G wheel -s /bin/zsh MYUSERNAME
    2. Set a password: passwd MYUSERNAME
    3. Create a new user group with the same name: groupadd MYUSERNAME
    4. Add the user to the new group: usermod -a -G MYUSERNAME MYUSERNAME
    5. Run visudo and find ## Uncomment to allow members of group wheel to execute any command followed by # %wheel ALL=(ALL) ALL. Remove the # and space characters, save and quit.
  2. Configure mkinitcpio with modules needed for the initrd image: vim /etc/mkinitcpio.conf

    • Add ext4 to MODULES
    • For PCI passthrough via OVMF add vfio_pci vfio vfio_iommu_type1 vfio_virqfd behind ext4
    • Add keymap encrypt lvm2 resume between block and filesystems
    • Regenerate initrd image: mkinitcpio -p linux
  3. Install the GRUB bootloader: grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=ArchLinux --removable --recheck --debug

  4. Modify the default GRUB config: vim /etc/default/grub

    • Remove the # character in front of GRUB_ENABLE_CRYPTODISK=y
    • Set GRUB_CMDLINE_LINUX to cryptdevice=/dev/nvmeXn1p3:luks root=/dev/mapper/vg0-root resume=/dev/mapper/vg0-swap
    • For PCI passthrough via OVMF append intel_iommu=on or amd_iommu=on to GRUB_CMDLINE_LINUX_DEFAULT
    • Re-generate GRUb config: grub-mkconfig -o /boot/grub/grub.cfg
  5. Open /etc/pacman.conf with vim and uncomment this line: ParallelDownloads = 5

You may also want to enable multilib in /etc/pacman.conf

  1. If you are using a LAN connection, you should now enable the dhcpcd service:
systemctl enable dhcpcd.service
  1. Exit new system and go into the cd shell: exit
  2. Unmount all partitions: umount -R /mnt && swapoff -a
  3. Reboot into the new system, don't forget to remove the CD/USB: reboot

Arch Linux post installation

  1. Install Xorg display server:
sudo pacman -S xorg-server xorg-apps xorg-xinit xterm xorg-fonts-100dpi xorg-fonts-75dpi autorandr
  1. Install a video driver (intel/nvidia):

    1. Intel: sudo pacman -S xf86-video-intel

    The nouveau driver is an open source alternative to the native nvidia binary drivers. Sadly many people having issues with the nouveau driver, so it's recommended to blacklist the driver.

    Login into the root account and execute the following command: echo blacklist nouveau >> /etc/modprobe.d/blacklist.conf

    1. If you're not planning to use a custom kernel, install the nvidia package, otherwise dkms and nvidia-dkms are required!
  2. For notebooks synaptics is also required: sudo pacman -S xf86-input-synaptics synaptics

  3. Install your favorite desktop environment and window manager, for example:

    1. KDE Plasma: pacman -S sddm plasma plasma-nm ttf-dejavu ttf-liberation kde-applications

    Don't install kde-applications for a lightweight installation! You have to manually install the applications instead. Example: pacman -S ark dolphin konsole yakuake

    1. xfce4 (optional replace lightdm with sddm)
    sudo pacman -S \
        lightdm \
        xfce4 \
        lightdm-gtk-greeter \
        lightdm-gtk-greeter-settings \
        ristretto \
        xfce4-datetime-plugin \
        xfce4-mount-plugin \
        xfce4-netload-plugin \
        xfce4-notifyd \
        xfce4-pulseaudio-plugin \
        xfce4-screensaver \
        xfce4-taskmanager \
        xfce4-wavelan-plugin \
        xfce4-whiskermenu-plugin \
        thunar-archive-plugin \
        thunar-media-tags-plugin \
        xarchiver \
        networkmanager \
        pulseaudio \
        pulseaudio-alsa \
        pulseaudio-bluetooth \
        network-manager-applet \
        paprefs \
        pavucontrol \
        libcanberra \
        libcanberra-pulse
    # optional packages and requirements for notebook users
    sudo pacman -S \
        mousepad \
        parole \
        xfce4-battery-plugin \
        xfce4-weather-plugin \
        xfce4-xkb-plugin \
        file-roller \
        leafpad \
        epdfview \
        galculator \
        capitaine-cursors \
        arc-gtk-theme \
        xdg-user-dirs-gtk
    1. Enable lightdm or sddm using sudo systemctl enable lightdm
  4. Install yay from source:

cd /opt
sudo git clone https://aur.archlinux.org/yay.git
sudo chown -Rh $USER:$USER yay/
cd yay
makepkg -si
yay -Yc
  1. PCI passthrough via OVMF

    1. Confirm that IOMMU has been correctly enabled during installation as mentioned above: sudo dmesg | grep -i -e DMAR -e IOMMU
    # Example output
    [    0.000000] ACPI: DMAR 0x00000000BDCB1CB0 0000B8 (v01 INTEL  BDW      00000001 INTL 00000001)
    [    0.000000] Intel-IOMMU: enabled
    [    0.028879] dmar: IOMMU 0: reg_base_addr fed90000 ver 1:0 cap c0000020660462 ecap f0101a
    [    0.028883] dmar: IOMMU 1: reg_base_addr fed91000 ver 1:0 cap d2008c20660462 ecap f010da
    [    0.028950] IOAPIC id 8 under DRHD base  0xfed91000 IOMMU 1
    [    0.536212] DMAR: No ATSR found
    [    0.536229] IOMMU 0 0xfed90000: using Queued invalidation
    [    0.536230] IOMMU 1 0xfed91000: using Queued invalidation
    [    0.536231] IOMMU: Setting RMRR:
    [    0.536241] IOMMU: Setting identity map for device 0000:00:02.0 [0xbf000000 - 0xcf1fffff]
    [    0.537490] IOMMU: Setting identity map for device 0000:00:14.0 [0xbdea8000 - 0xbdeb6fff]
    [    0.537512] IOMMU: Setting identity map for device 0000:00:1a.0 [0xbdea8000 - 0xbdeb6fff]
    [    0.537530] IOMMU: Setting identity map for device 0000:00:1d.0 [0xbdea8000 - 0xbdeb6fff]
    [    0.537543] IOMMU: Prepare 0-16MiB unity mapping for LPC
    [    0.537549] IOMMU: Setting identity map for device 0000:00:1f.0 [0x0 - 0xffffff]
    [    2.182790] [drm] DMAR active, disabling use of stolen memory
    
    1. Ensuring that the groups are valid
    #!/bin/bash
    shopt -s nullglob
    for g in `find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V`; do
        echo "IOMMU Group ${g##*/}:"
        for d in $g/devices/*; do
            echo -e "\t$(lspci -nns ${d##*/})"
        done;
    done;

    Example output:

    IOMMU Group 1:
    	00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port [8086:0151] (rev 09)
    IOMMU Group 2:
    	00:14.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB xHCI Host Controller [8086:0e31] (rev 04)
    IOMMU Group 4:
    	00:1a.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 [8086:0e2d] (rev 04)
    IOMMU Group 10:
    	00:1d.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 [8086:0e26] (rev 04)
    IOMMU Group 13:
    	06:00.0 VGA compatible controller: NVIDIA Corporation GM204 [GeForce GTX 970] [10de:13c2] (rev a1)
    	06:00.1 Audio device: NVIDIA Corporation GM204 High Definition Audio Controller [10de:0fbb] (rev a1)
    
    1. Binding vfio-pci via device ID to isolate the PCI device: vim /etc/modprobe.d/vfio.conf and add the following line. options vfio-pci ids=ID1,ID2,...

    Replace ID1 and ID2 with the correct IOMMU group ids

    1. Regenerate initramfs: sudo mkinitcpio -p linux
    2. Reboot
    3. Verify that the configuration worked: sudo dmesg | grep -i vfio, example output:
    [    0.329224] VFIO - User Level meta-driver version: 0.3
    [    0.341372] vfio_pci: add [10de:13c2[ffff:ffff]] class 0x000000/00000000
    [    0.354704] vfio_pci: add [10de:0fbb[ffff:ffff]] class 0x000000/00000000
    [    2.061326] vfio-pci 0000:06:00.0: enabling device (0100 -> 0103)
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment