Notes on installing Arch Linux
Published on
A few notes on installing Arch Linux
Introduction
These notes are based on the following articles / wiki pages after I had to re-install ArchLinux on a new SSD. The task was more difficult than anticipated as it had been a while since my last installation. On top of that, I decided to use btrfs
for the main system with a Luks encrypted container. On top of that, I wanted to have a working dual boot as Nvidia Optimus support is still not optimal on older generation.
So here are the requirements:
- Dual boot with windows 10
- Encrypted Linux partition
- Swap file
- Btrfs
- No Password needed to boot windows
Notes:
- grub (/boot) partition will not be encrypted in order to boot windows without having to specify a password. I know this is not optimal, but is enough in my security threat model, which mainly resolves in protecting my documents in case my laptop is stolen.
- This setup is temporary until I ditch windows completely from this laptop.
Based on
- Arch WIki - Encrypting an entire drive
- Arch WIki - Encrypting an entire drive on Btrfs subvolumes
- Egara’s github
- Essential packages
- Another gist from idvoretskyi
- A detailed guide for beginners (not maintained anymore)
- A few others forum post and blogs I used to troubleshoot some issues I forgot to mention
- one last I have to find again
Step 1: boot the installation iso and preparation
On the PC:
-
I have a French layout keyboard so run
loadkeys fr
to set the mapping right. -
Connect to a wireless network:
iwctl
station wlan0 connect SSID
-
We will connect with SSH to this PC from another one. It brings flexibilty in writing the installation commands. First, change the root password. passwd Start the ssh server daemon and get ip address:
systemctl start sshd
ip addr
Now, from another computer: ssh root@[IP-ADDRESS]
Step 2: Prepare the disk
Mapping
# fdisk -l
-----
Device Start End Sectors Size Type
/dev/nvme0n1p1 4096 208895 204800 100M EFI System
/dev/nvme0n1p2 208896 720895 512000 250M Linux filesystem
/dev/nvme0n1p3 720896 1426968575 1426247680 680.1G Linux filesystem
/dev/nvme0n1p4 1426968576 1866235610 439267035 209.5G Microsoft basic data
/dev/nvme0n1p5 1866235904 1867286527 1050624 513M Windows recovery environm
- sda1 - EFI
- sda2 - grub ext4
- sda3 - Luks
- sda4 - ntfs
-> Use btrfs
Create luks container
# cryptsetup -y -v luksFormat /dev/nvme0n1p3
# cryptsetup open /dev/nvme0n1p3 cryptroot
# mkfs.btrfs -L arch /dev/mapper/cryptroot
# mount /dev/mapper/cryptroot /mnt
Check the mapping works as intended:
# umount /mnt
# cryptsetup close cryptroot
# cryptsetup open /dev/nvme0n1p3 cryptroot
# mount /dev/mapper/cryptroot /mnt
Create btrfs subvolume
# btrfs subvolume create /mnt/@
# btrfs subvolume create /mnt/@home
# btrfs subvolume create /mnt/@tmp
# btrfs subvolume create /mnt/@snapshots
# btrfs subvolume create /mnt/@swap
Check subvolumes
# btrfs subvolume list -p mnt
Remount with subvolume
# umount /mnt
# mount -o compress=zstd,subvol=@ /dev/mapper/cryptroot /mnt
# mkdir /mnt/{home,tmp,.snapshots,boot,swap}
# mount -o compress=zstd,subvol=@home /dev/mapper/cryptroot /mnt/home
# mount -o subvol=@tmp /dev/mapper/cryptroot /mnt/tmp
# mount -o compress=zstd,subvol=@snapshots /dev/mapper/cryptroot /mnt/.snapshots
# mount /dev/nvme0n1p2 /mnt/boot
# mkdir /mnt/boot/efi
# mount /dev/nvme0n1p1 /mnt/boot/efi
At this point, I have the following mounted:
root@archiso / # mount
/dev/mapper/cryptroot on /mnt type btrfs (rw,relatime,compress=zstd:3,ssd,space_cache,subvolid=257,subvol=/@)
/dev/mapper/cryptroot on /mnt/home type btrfs (rw,relatime,compress=zstd:3,ssd,space_cache,subvolid=258,subvol=/@home)
/dev/mapper/cryptroot on /mnt/tmp type btrfs (rw,relatime,compress=zstd:3,ssd,space_cache,subvolid=259,subvol=/@tmp)
/dev/mapper/cryptroot on /mnt/.snapshots type btrfs (rw,relatime,compress=zstd:3,ssd,space_cache,subvolid=263,subvol=/@snapshots)
/dev/mapper/cryptroot on /mnt/swap type btrfs (rw,relatime,compress=zstd:3,ssd,space_cache,subvolid=273,subvol=/@swap)
Create swapfile
# mount -o subvol=@swap /dev/mapper/cryptroot /mnt/swap
# chattr +C /mnt/swap
# touch /mnt/swap/swapfile
# chmod 600 /mnt/swap/swapfile
For 16GiB
# dd if=/dev/zero of=/mnt/swap/swapfile bs=1M count=16384 status=progress
# mkswap /mnt/swap/swapfile
# swapon /mnt/swap/swapfile
Create nested subvolume
# btrfs subvolume create /mnt/srv
# btrfs subvolume create /mnt/var/abs
# btrfs subvolume create /mnt/var/tmp
# btrfs subvolume create /mnt/var/lib/portables
# btrfs subvolume create /mnt/var/lib/machines
# btrfs subvolume create /mnt/var/cache/pacman/pkg
This is useful to avoid having these folders in the automatic snapshots of the root partition we will set up later.
You can check the existing subvolumes with:
root@archiso / # btrfs subvolume list -p mnt
ID 257 gen 139 parent 5 top level 5 path @
ID 258 gen 22 parent 5 top level 5 path @home
ID 259 gen 22 parent 5 top level 5 path @tmp
ID 263 gen 15 parent 5 top level 5 path @snapshots
ID 264 gen 132 parent 257 top level 257 path @/srv
ID 265 gen 137 parent 257 top level 257 path @/var/tmp
ID 266 gen 25 parent 257 top level 257 path @/var/abs
ID 267 gen 137 parent 257 top level 257 path @/var/cache/pacman/pkg
ID 270 gen 135 parent 257 top level 257 path @/var/lib/portables
ID 271 gen 136 parent 257 top level 257 path @/var/lib/machines
ID 273 gen 141 parent 5 top level 5 path @swap
The paths starting with @/
are nested subvolumes.
Step 3: Installation
Optional - update mirrors (don’t know if it changes anything though)
# pacman -Sy reflector
# reflector --country France --country Germany --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist --verbose
Install arch base
# pacstrap /mnt base base-devel linux linux-firmware btrfs-progs zsh
Add intel-ucode
if using an Intel CPU, amd-ucode
if for AMD.
Genfstab
# genfstab -U -p /mnt >> /mnt/etc/fstab
Boot into new system
# systemd-nspawn -bD /mnt
Locale gen
# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
# echo "en_GB.UTF-8 UTF-8" >> /etc/locale.gen
# echo "fr_FR.UTF-8 UTF-8" >> /etc/locale.gen
# echo "co_FR.UTF-8 UTF-8" >> /etc/locale.gen
# locale-gen
# localectl set-locale LANG=en_US.UTF-8
- to check LC_COLLATE=C in /etc/locale.conf
# echo "LC_COLLATE=C" >> /etc/locale.conf
To check the locales were installed correctly:
$ localectl list-locales
I then configure them that way:
LANG=en_GB.UTF-8
LC_CTYPE="en_GB.UTF-8"
LC_NUMERIC=en_GB.UTF-8
LC_TIME=en_GB.UTF-8
LC_COLLATE=C
LC_MONETARY=oc_FR.UTF-8
LC_MESSAGES="en_GB.UTF-8"
LC_PAPER="en_GB.UTF-8"
LC_NAME="en_GB.UTF-8"
LC_ADDRESS="en_GB.UTF-8"
LC_TELEPHONE="en_GB.UTF-8"
LC_MEASUREMENT=oc_FR.UTF-8
LC_IDENTIFICATION="en_GB.UTF-8"
LC_ALL=
Time and Date
# timedatectl set-ntp 1
# timedatectl list-timezones
# timedatectl set-timezone Europe/Paris
Set hostname
# hostnamectl set-hostname xxx
Check hostfile
/etc/hosts
127.0.0.1 localhost
::1 localhost
127.0.1.1 myhostname.localdomain myhostname
Keyboard Layout
If you set the keyboard layout, make the changes persistent in vconsole.conf(5):
# echo "KEYMAP=fr" >> /etc/vconsole.conf
# pacman -Sy vim iwd wpa_supplicant dialog terminus-font
Mkinitcpio
Edit /etc/mkinitcpio.conf
BINARIES=(/usr/bin/btrfs) # see https://wiki.archlinux.org/index.php/Btrfs#Corruption_recovery
HOOKS=(base udev autodetect keyboard keymap consolefont modconf block encrypt filesystems fsck) #no need for keymap if US keyboard
# mkinitcpio -P linux
Configuring the boot loader
-> Use grub here. See next section
Quit the container
# poweroff
Need arch-chroot for grub
# arch-chroot /mnt
Install grub
# pacman -S grub efibootmgr
# pacman -S os-prober #for windows
In order to unlock the encrypted root partition at boot, the following kernel parameters need to be set by the boot loader:
Use blkid
to get the UUID. we want the UUID of the physical partition here
Edit /etc/default/grub
as
GRUB_CMDLINE_LINUX='cryptdevice=UUID=device-UUID:cryptroot root=/dev/mapper/cryptroot'
Then run:
# grub-mkconfig -o /boot/grub/grub.cfg
## To check if we correctly booted in efi
# mount | grep efivars &> /dev/null || mount -t efivarfs efivarfs /sys/firmware/efi/efivars
# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB --recheck
Step 4: System Installation
Install again reflector in our freshly install system:
# pacman -Sy reflector
# reflector --country France --country Germany --age 12 --protocol https --sort rate --save /etc/pacman.d/mirrorlist --verbose
Having the lts kernel can be handy in case of problems. I usually have dkms packages as well, so I install the headers alongside.
# pacman -S linux-lts linux-lts-headers linux-headers
NB: why did I add acpi_call-dkms
here?
Intel related video drivers:
pacman -S intel-media-driver intel-compute-runtime libva-intel-driver intel-media-sdk xf86-video-intel
AMD related video drivers:
pacman -S xf86-video-ati xf86-video-amdgpu xf86-video-amdgpu mesa lib32-mesa
Nvidia drivers:
pacman -S nvidia nvidia-settings opencl-nvidia
Check the wiki for more information for both here.
Some system utils, network fonts & media plugins tools, xord server:
pacman -S cronie ntp git snap-pac nss_mdns dhcpcd dhclient neovim samba unrar logrotate rrdtool python2 bluez zip unzip p7zip vim alsa-utils syslog-ng mtools dosfstools lsb-release ntfs-3g exfat-utils bash-completion gst-plugins-{base,good,bad,ugly} gst-libav xorg-{server,xinit} xdg-user-dirs ttf-{bitstream-vera,liberation,freefont,dejavu} freetype2 rsync libappimage ocl-icd lzop lrzip libnfs
Regulatory domain for Wi-Fi:
pacman -S crda
Uncomment this country setting in /etc/conf.d/wireless-regdom
To have the ability to print in a pdf:
pacman -S cups cups-pdf
To have printers drivers, add foomatic-{db,db-ppds,db-gutenprint-ppds,db-nonfree,db-nonfree-ppds} gutenprint ipp-usb
Enable system services
systemctl enable ntpd
#systemctl enable systemd-resolved.service ## not sure. apparently does not work with avahi. pkg systemd-resolvconf
systemctl enable syslog-ng@default
systemctl enable cronie
systemctl enable bluetooth
systemctl enable avahi-daemon
systemctl enable avahi-dnsconfd
systemctl enable org.cups.cupsd.socket ## according to the wiki, can start the daemon when smth is received on the socket
systemctl is-enabled org.cups.cupsd.socket ## should be True
systemctl is-enabled org.cups.cupsd.service ## should be False
/usr/bin/cups-genppdupdate
Add new user
export MyUSER=XXX
useradd -m -g $MyUSER -G wheel,storage,uucp,audio,video,plugdev,users -c 'FULL NAME' -s /bin/zsh $MyUSER
--groupadd $MyUSER
--usermod -g $MyUSER $MyUSER
to check
groupadd plugdev
usermod -aG plugdev $MyUSER
Create a subvolume for our user cache folder:
btrfs subvolume create /home/$MyUSER/.cache
UI level service
Install plasma group and default apps, firefox and some utils.
pacman -S plasma appmenu-gtk-module kdegraphics-thumbnailers plasma-workspace-wallpapers breeze-gtk kwalletmanager drkonqi bluez-utils dolphin-plugins sddm
localectl set-x11-keymap fr
systemctl start sddm
If the above work, enable the service and reboot.
# systemctl enable sddm
# systemctl enable NetworkManager.service
Now we can reboot
.
Step 5: System Installation for user
== Login as user
Soft:
sudo pacman -S firefox ffmpegthumbs kimageformats keepass kate kate ktorrent thunderbird tilix hunspell-{fr,de,en_GB,en_US} okular libreoffice-fresh baobab
Utils:
sudo pacman -S aria2 firejail ark android-tools android-udev gvfs-{afc,goa,google,gphoto2,mtp,nfs,smb} antiword docx2txt virtualbox htop i7z moreutils nvme-cli testdisk vdpauinfo powertop python-virtualenv python-pynvim ipython tree gparted
After installing virtualbox
, don’t forget to add the user to the vboxusers
group to be able to attach usb devices to the VM
sudo usermod -aG vboxusers $USER
Sound:
sudo pacman -S pulseaudio pulseaudio-alsa paprefs pulseaudio-zeroconf pulseaudio-bluetooth
Video and images soft:
sudo pacman -S darktable displaycal colord-kde gnome-color-manager musescore gimp clementine kdenlive rawtherapee handbrake spectacle calibre shotwell vlc
NOTE: is mtpfs needed for android access??
Remove some pkg installed with the plasma group
sudo pacman -R discover plasma-vault
Install yay
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
Install oh my zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
Install from aur
yay -S aic94xx-firmware airvpn-bin downgrade protonmail-bridge-bin rambox-bin tlpui-git upd72020x-fw vivaldi wd719x-firmware yay-bin ventoy-bin
Step 6: Various tweaks
Config to do
-
Reflector in
/etc/xdg/reflector/reflector.conf
Select countries, destination file.sudo systemctl enable reflector.timer
to enable automatic update -
iwd -> install
networkmanager-iwd-overlay
on AUR if lazy -
swapiness: Decrease to 10 in
/etc/sysctl.d/99-swappiness.conf
-
TLP: To avoid filesystem corruption on btrfs formatted partitions, in
/etc/tlp.conf
set:SATA_LINKPWR_ON_BAT=max_performance
-
PS1 used by root. add in
/root/.bashrc
. Looks like:[02:03 pm] root @machine {~} >
PS1="\[\033[38;5;6m\][\[$(tput sgr0)\]\[\033[38;5;14m\]\@\[$(tput sgr0)\]\[\033[38;5;6m\]]\[$(tput sgr0)\] \[$(tput sgr0)\]\[\033[38;5;11m\]\u\[$(tput sgr0)\] \[$(tput sgr0)\]\[$(tput bold)\]\[\033[38;5;10m\]@\[$(tput sgr0)\]\h\[$(tput sgr0)\] \[$(tput sgr0)\]\[\033[38;5;13m\]{\w}\[$(tput sgr0)\] > \[$(tput sgr0)\]"
Numlock in tty at boot
nvim /usr/local/bin/numlock
--------
#!/bin/bash
for tty in /dev/tty{1..6}
do
/usr/bin/setleds -D +num < "$tty";
done
chmod +x /usr/local/bin/numlock
nvim /etc/systemd/system/numlock.service
--------
[Unit]
Description=numlock
[Service]
ExecStart=/usr/local/bin/numlock
StandardInput=tty
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
systemctl enable numlock.service
Avoid ghosting of FN keys on MSI GS40
vim /etc/X11/xorg.conf.d/10-quirks.conf
Section "InputClass"
Identifier "Spooky Ghosts"
MatchProduct "Video Bus"
Option "Ignore" "on"
EndSection
Add the following in /etc/default/grub
GRUB_CMDLINE_LINUX=“acpi_osi="!Windows 2015"”
NB: it seems i915.enable_rc6=0
is ignored. To be investigated
GP AE Not found - ACPI ERROR
Kernel msg error - dmesg was flooded with:
Sep 17 13:09:59 xxx kernel: ACPI BIOS Error (bug): Could not resolve symbol [\_GPE._L69.D1F0], AE_NOT_FOUND (20190816/psargs-330)
Sep 17 13:09:59 xxx kernel: ACPI Error: Aborting method \_GPE._L69 due to previous error (AE_NOT_FOUND) (20190816/psparse-529)
Sep 17 13:09:59 xxx kernel: ACPI Error: AE_NOT_FOUND, while evaluating GPE method [_L69] (20190816/evgpe-511)
Check what is unusual (high nb)
$ grep . -r /sys/firmware/acpi/interrupts/
Add the kernel param to your bootloader: acpi_mask_gpe=0x[XX]
Pacman config and tweaks
In /etc/pacman.conf
, untick the following options:
color
total download
and add the following repository (to your own risk):
[seblu]
SigLevel = Required
Server = http://al.seblu.net/$repo/$arch
From seblu repo or aur
yay -Sy virtualbox-ext-oracle spotify
Hdparm - put spinning disk to sleep
To enable this now (after 12*5 sec = 1min)
sudo hdparm -B 12 /dev/sda
Putting a drive to sleep directly after boot
vim /etc/systemd/system/hdparm.service
-----
[Unit]
Description=hdparm sleep
[Service]
Type=oneshot
ExecStart=/usr/bin/hdparm -q -S 12 /dev/sda
[Install]
WantedBy=multi-user.target
$ sudo systemctl enable hdparm.service
APM level reset after suspend
vim /etc/systemd/system/apm.service
-----
[Unit]
Description=Local system resume actions
After=suspend.target hybrid-sleep.target hibernate.target
[Service]
Type=simple
ExecStart=/usr/bin/hdparm -B 12 /dev/sda
[Install]
WantedBy=sleep.target
$ sudo systemctl enable apm.service
Suspend on disk with swapfile on btrfs partition
Add resume
hooks in /etc/mkinitcpio.conf
See the wiki c prgm to calculate file offset:
$ wget https://github.com/osandov/osandov-linux/blob/master/scripts/btrfs_map_physical.c
to compile:
$ gcc -O2 -o btrfs_map_physical btrfs_map_physical.c
Get file offset:
$ sudo ./btrfs_map_physical /swap/swapfile | column -ts $'\t'
Get the top-right-hand corner value.
$ getconf PAGESIZE
$ dc -e 'number_in_top_right_hand_corner page_size /p'
Edit /etc/default/grub
add resume=UUID=xxx
OR resume=/dev/mapper/cryptroot
(if dev mapper mounted there)
AND resume_offset=yyy
-> being what was calculated above
Alternative command to suspend on disk:
# echo disk > /sys/power/state
Snapper - auto snapshot
Follow the instructions on the wiki and this chapter as well.
–> disable hourly snapshot of / partition by setting a var to no in /etc/snapper/configs/root
–> create config for home:
sudo snapper -c home create-config /home
For users to have access to snapshots. root must be owner but we can update the group
cd /
chmod a+rx .snapshots
chown :users .snapshots
Snapshot bootpartition if not on btrfs
See https://wiki.archlinux.org/index.php/Snapper#Wrapping_pacman_transactions_in_snapshots !! Check that rsync is installed
mkdir /.bootbackup
nvim /usr/share/libalpm/hooks/50_bootbackup.hook
-------
[Trigger]
Operation = Upgrade
Operation = Install
Operation = Remove
Type = Package
Target = linux*
[Action]
Depends = rsync
Description = Backing up /boot...
When = PreTransaction
Exec = /usr/bin/rsync -a --delete /boot /.bootbackup
TRIM ssd
disabled by default! add ``:allow-discards` in grub config file as option for mapper device. See the [wiki](https://wiki.archlinux.org/index.php/Dm-crypt/Specialties#Discard/TRIM_support_for_solid_state_drives_(SSD))
Then we can either add discard
option in fstab for continuous tril
or enable fstrim.timer` (weekly trim) for periodic trim
fsck
Check ext4 filesystem every 50 mounts or 2 weeks:
sudo tune2fs -c 50 -i 2w /dev/sdaX
Customization
Some nice grub theme
$ git clone https://github.com/vinceliuice/grub2-themes.git
$ cd grub2-themes
$ sudo ./install.sh -b -t # read man to select grub theme
Check intel audio power consumption
$ cat /sys/module/snd_hda_intel/parameters/power_save*
$ echo 1 | sudo tee /sys/module/snd_hda_intel/parameters/power_save
$ echo Y | sudo tee /sys/module/snd_hda_intel/parameters/power_save_controller
$ pkill pulseaudio
HW probe (to help the community)
$ aria2c https://github.com/linuxhw/hw-probe/releases/download/1.5/hw-probe-1.5-149-x86_64.AppImage
$ chmod +x ./hw-probe-1.5-149-x86_64.AppImage
$ sudo -E ./hw-probe-1.5-149-x86_64.AppImage -all -upload\n
lm-sensors
The first thing to do is to run as root to calibrate the sensors
# sensors-detect
Touchpad sensitivity
$ yay -S xorg-xinput
$ xinput --set-prop 'ETPS/2 Elantech Touchpad' 'libinput Accel Speed' 0.017324
Other useful information
f-prot antivirus
https://sebsauvage.net/wiki/doku.php?id=fprot-linux
For macOS vm
See Github’s project
$ yay -S dmg2img
Darktable crash with opencl
https://github.com/darktable-org/darktable/issues/5842
fxthomas commented on Aug 5 Thanks, by the way I can confirm that downgrading intel-graphics-compiler to 1.0.4361 (package link here) fixes the issue. Will open an issue on their GitHub when I get the time!
For some reason, clearing ~/.cache/darktable/cached_kernels*, downgrading, starting Darktable once with the previous version and then upgrading again seemed to fix the issue, now I have no issue with 1.0.4427.
Kwallet manager & gnome-keyring
Doc here
-
Install
kwalletmanager kwallet-pam
-
Install
gnome-keyring seahorse
Handle ssh keys and git credentials with
Install ksshaskpass
and create an executable script ~/.config/plasma-workspace/env/askpass.sh
:
#!/bin/sh
# Using the KDE Wallet to store ssh key passphrases
export SSH_ASKPASS='/usr/bin/ksshaskpass'
# Using the KDE Wallet to store Git credentials
export GIT_ASKPASS='/usr/bin/ksshaskpass'
and ~/.config/autostart-scripts/ssh-add.sh
#!/bin/sh
ssh-add -q ~/.ssh/key1 ~/.ssh/key2 ~/.ssh/key3 < /dev/null
Note that a ssh-agent
must be running.