Arch Linux installation on AMD 5800X3D/7800XT

This is a summary of my installation of Arch Linux on my AMD 5800X3D CPU/RX 7800XT GPU PC in Dec 2023.

It should only be considered an approximate guide and probably has errors in. You may not want to follow it exactly, eg you may not want to set up encryption or logical volumes (LVs).

It sets up (on a single SSD) two partitions: one small, unencrypted partition will be mounted as /boot. The second is a LUKS-encrypted partition occupying the rest of the drive. Inside this will be logical volumes for the rest of the system, eg /, /home, /usr, /var, and swap (/tmp will use a temporary file system tmpfs).

See https://wiki.archlinux.org/title/Installation_guide for more details of installation of Arch Linux in general. Many of my steps below are copied/adapted from there 1.

Feel free to email me at ルーキー@エボ猫.コム if you have a question, or if I have made an error. David.



Download arch linux, burn to usb stick, initial checks

See https://archlinux.org/download/.

Use bittorrent, or download arch linux from a nearby mirror as listed in above page, eg (for UK):

(where VERSION is the current latest version date).

Compare sha256sum of iso with that on download page (sha256sum archlinux-VERSION-x86_64.iso). Check gpg sig (gpg --keyserver-options auto-key-retrieve --verify archlinux-VERSION-x86_64.iso.sig).

Burn iso to usb stick, eg on a linux system:

sudo dd bs=4M if=archlinux-VERSION-x86_64.iso of=/dev/sdX conv=fsync oflag=direct status=progress

(replace X by the usb device letter).

Boot off usb stick (secure boot must be off on PC - this is the default initial state for the Gigabyte B550 Aorus Elite AX V2 motherboard I built this PC with).

Boot options are:

Suggest connect to network via ethernet cable.

If available, I recommend ssh in from other computer on network to complete setup (need to first set root password on system being setup with passwd).

Verify boot mode:

cat /sys/firmware/efi/fw_platform_size

should give “64”. (See [1] if other value given.)

Check internet connection, eg

ping archlinux.org

Check time and date:

timedatectl

Partition drive, set up LUKS encryption and LVM (assuming single nvme ssd drive)

Set up partitions:

Run

fdisk /dev/nvme0n1

(note, I don’t create a swap partition here, as I want it to be inside the encrypted container).

Create a LUKS container on partition 2:

cryptsetup --cipher aes-xts-plain --key-size 512 --hash sha512 -v luksFormat /dev/nvme0n1p2

(follow instructions, including entering a passphrase).

Open LUKS container and set up LVM:

cryptsetup luksOpen /dev/nvme0n1p2 nvme0n1p2_crypt
pvcreate /dev/mapper/nvme0n1p2_crypt

Set up Volume Group/Logical Volumes:

Fire up bash shell (ie don’t use the default zsh)

bash

vgname=MYVGNAME # volume group name, change as needed
vgcreate $vgname /dev/mapper/nvme0n1p2_crypt

# The LVs to create. `lvs` has elements: <name of lv> <size of lv in GiB>
# (change the logical volumes to be created and their sizes as needed)
lvs=(root 1 swap 64 usr 20 usr_local 10 usr_src 80 var 40 var_tmp 15 home 200 opt 15 games 400 music 60 videos 60)
for ((j=0; j<${#lvs[*]}; j+=2)); do lvcreate -L ${lvs[$j+1]}g $vgname -n ${lvs[$j]}; done

Notes:

Format partitions:

# what will be /boot
mkfs.fat -F 32 /dev/nvme0n1p1

# all the remaining (non-swap) filesystems. "-m 1" specified to reserve 1% for root user on each fs (not default 5%)
for ((j=0; j<${#lvs[*]}; j+=2)); do if [[ ${lvs[$j]} != swap ]]; then mkfs.ext4 -m 1 /dev/$vgname/${lvs[$j]}; fi; done

# set up the swap partition
mkswap /dev/$vgname/swap

Mount filesystems

(with $vgname, $lvs as defined above, and still running under bash)

mount /dev/$vgname/root /mnt

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

swapon /dev/$vgname/swap

# mount non-root, non-swap LVM volumes to under /mnt, eg usr->mnt/usr, usr_local to mnt/usr/local (use IFS to "split" volume names on "_", then rejoin with "/")
IFS_bak="$IFS"; for ((j=0; j<${#lvs[*]}; j+=2)); do if [[ ${lvs[$j]} != root && ${lvs[$j]} != swap ]]; then IFS=_ pArray=(${lvs[$j]}); IFS=/ p="${pArray[*]}"; mount --mkdir /dev/$vgname/${lvs[$j]} /mnt/"$p"; fi; done; IFS="$IFS_bak"

Install essential packages

(May be safest to be running under default zsh shell of the archlinux installation image, so exit bash if have been running under it (run exit).)

# change this list of "essential" packages as needed
pacstrap -K /mnt base linux linux-firmware \
  dosfstools exfatprogs e2fsprogs \
  lvm2 \
  cryptsetup \
  man-db man-pages texinfo \
  vim \
  pacman-contrib pkgfile \
  sudo \
  base-devel git

Set up /etc/fstab, chroot to /mnt, and other configuration

Run

genfstab -U /mnt > /mnt/etc/fstab
# -U means use UUIDs in fstab to identify the filesystems
# Take a look at /mnt/etc/fstab to check it looks ok

# change root to new system
# (arch-chroot calls chroot(1), but also mounts /dev etc so they are available to the chrooted system)
# (runs bash unless a command to run is specified)
arch-chroot /mnt

# set time zone
# ln -sf /usr/share/zoneinfo/Region/City /etc/localtime, eg
ln -sf /usr/share/zoneinfo/Europe/London /etc/localtime

# set hardware clock and generate /etc/adjtime
hwclock --systohc

# set localization
# Edit /etc/locale.gen,
# uncomment locales to support, eg
# (note: recommend always install en_US.UTF-8 locale)
cd /etc
cp locale.gen locale.gen.orig
for lang in en_US.UTF-8 en_GB.UTF-8; do sed -E -i -e "s/^#($lang )/\1/" /etc/locale.gen; done

locale-gen

# Create /etc/locale.conf  - this defines environment variable assignments, and is read at early boot by systemd (see locale.conf(5))
cat <<+ > /etc/locale.conf
LANG=en_GB.UTF-8
+
# (change LANG value as needed)

# Set console keyboard layout if not US, eg
echo "KEYMAP=uk" > /etc/vconsole.conf

# Set hostname (change as needed)
echo MYHOSTNAME > /etc/hostname

Initramfs (/etc/mkinitcpio.conf)

(All run as root)

See

Edit /etc/mkinitcpio.conf (backup original to mkinitcpio.conf.orig):

Specify (in addition to default hooks):

Remove from default hooks:

cd /etc
cp mkinitcpio.conf mkinitcpio.conf.orig
sed -i -e 's/^HOOKS=.*/HOOKS=(base udev autodetect modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems resume fsck usr)/' mkinitcpio.conf

mkinitcpio -P

(See the grub section below re passing of kernel parameters specifying the swap partition and encrypted partition via grub.)


Boot loader (grub)

(See https://wiki.archlinux.org/title/GRUB.)

(All run as root)

Install grub and efibootmgr packages

pacman -S grub efibootmgr

Install grub EFI application grubx64.efi to /boot/EFI/GRUB/ and install its modules to /boot/grub/x86_64-efi/

Note I will reinstall grub later (see Secure Boot).

Find what partition is the EFI System partition, and the directory it is mounted on:

efi_part=$(fdisk -l -o device,type /dev/nvme0n1 | grep EFI | awk '{print $1}') # expect = /dev/nvme0n1p1 for this AMD system
efi_d=$(mount | grep -F "$efi_part" | awk '{print $3}') # expect = /boot for this AMD system

Install grub:

grub-install --target=x86_64-efi --efi-directory=$efi_d --bootloader-id=GRUB

Edit /etc/default/grub:

cd /etc/default
cp grub grub.orig

# Find UUID of crypto_LUKS partition with:
uuid=$(blkid | grep crypto_LUKS | sed -E -e 's/^.* UUID="([a-z0-9-]+).*/\1/')

vgname=MYVGNAME # volume group name, change as needed (see earlier)

# Set the kernel command line via GRUB_CMDLINE_LINUX (ie for all kernel boots).
# resume=<device> specifies the location of the swap partition (https://wiki.archlinux.org/title/Dm-crypt/System_configuration).
# cryptdevice=UUID=$uuid specifies the location of the device to be decrypted.
# Option "cryptlvm" means the decrypted partition will be available at /dev/mapper/cryptlvm
# "allow-discards" enables TRIM for the decrypted device.
# (https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system#LVM_on_LUKS)
# (https://wiki.archlinux.org/title/Dm-crypt/Specialties)
# NOTE: only use allow-discards option if the encrypted partition is on an SSD (remove ":allow-discards" if not on an SSD). See also below for enabling the fstrim timer.
sed -i -e "s|^GRUB_CMDLINE_LINUX=.*|GRUB_CMDLINE_LINUX=\"resume=/dev/$vgname/swap cryptdevice=UUID=$uuid:cryptlvm:allow-discards\"|" grub

# Turn off "quiet" option for default kernel boot
sed -i -E -e 's/^(GRUB_CMDLINE_LINUX_DEFAULT=".*) quiet([ "].*)/\1\2/' grub

# Disable watchdog timers (no need on non-server system, see https://wiki.archlinux.org/title/Improving_performance#Watchdogs)
sed -i -E -e 's/^(GRUB_CMDLINE_LINUX_DEFAULT=.*)"/\1 nowatchdog"/' grub

# Disable graphical terminal
sed -i -E -e 's/^#(GRUB_TERMINAL_OUTPUT)/\1/' grub

Generate main configuration file /boot/grub/grub.cfg

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

Add main user, configure sudo, disable root login

(All run as root)

Add main user

useradd -m USERNAME # change USERNAME to username of user to add
passwd USERNAME

# Add to wheel group
usermod -aG wheel USERNAME

Configure sudo

# Allow members of wheel group to run commands as root
# (The default /etc/sudoers has a commented out line allowing this already, so just uncomment it)
cd /etc
sed -i -e 's/^# \(%wheel ALL=(ALL:ALL) ALL\)$/\1/' sudoers

Disable root login

passwd --lock root

Change user to USERNAME above

sudo -i -u USERNAME

Set up wifi

(See https://wiki.archlinux.org/title/Wpa_supplicant.)

Install iw and wpa_supplicant packages:

sudo pacman -S iw wpa_supplicant

# Configure wpa_supplicant:
# (run as root)
# (setting update_config to 1 allows wpa_supplicant to overwrite the configuration file)
sudo -s
cat <<+ > /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/run/wpa_supplicant
update_config=1
+
exit # leave root

Set up wifi to a given connection via wpa_cli:

# Get wifi interface name (assuming there is only one), eg wlan0
iwdev=$(iw dev | grep Interface | awk '{print $2}')

# Run:
sudo wpa_supplicant -B -i $iwdev -c /etc/wpa_supplicant/wpa_supplicant.conf

# Run
sudo wpa_cli

Within wpa_cli, run:

> scan
> scan_results
> add_network
(get reply eg "0")
> set_network 0 ssid "MYSSID"
> set_network 0 psk "passphrase"
> enable_network 0
(replace "0" with reply from add_network, replace MYSSID and passphrase as needed)
> save_config
> quit

This typically adds a section of the form

network={
  ssid="MYSSID"
  psk="passphrase"
  mesh_fwding=1
}

to /etc/wpa_supplicant/wpa_supplicant.conf

(See below re starting wpa_supplicant automatically with dhcpcd.)

Can use wpa_cli to add additional network sections (or just do it with a text editor).

If have more than 1 possible ssid to connect to, consider adding a priority value within the network section (an integer, starting at 0, the higher the value, the greater the priority) eg

  priority=2

(Note: suggest put a working /etc/wpa_supplicant/wpa_supplicant.conf on the arch linux live usb stick at /tmp/sda2/local/etc/wpa_supplicant/wpa_supplicant.conf (mount the second partition of the usb stick at /tmp/sda2), and create an executable script at /tmp/sda2/local/sh/run_wpa_supplicant.sh:

#!/bin/bash
iwdev=$(iw dev | grep Interface | awk '{print $2}')
echo "iwdev=$iwdev"

mkdir -p /etc/wpa_supplicant
cp ../etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant

wpa_supplicant -B -i $iwdev -c /etc/wpa_supplicant/wpa_supplicant.conf

Then if need to reboot off live usb stick, can mount this partition, and run the script (from the directory the script is in) to set up wifi. )


Set up dhcpcd

(See https://wiki.archlinux.org/title/Dhcpcd.)

Install dhcpcd package:

sudo pacman -S dhcpcd
# (as root)
sudo -s
cd /etc
cp dhcpcd.conf dhcpcd.conf.orig
grep -q '^noarp' dhcpcd.conf || echo -e "\nnoarp" >> dhcpcd.conf
exit # leave root

For a desktop system (which this AMD system is) do the following 2 steps. For a laptop system, suggest skip these steps and install NetworkManager later (see below).

Enable wpa_supplicant hook, so wpa_supplicant is started by dhcpcd:

sudo ln -s /usr/share/dhcpcd/hooks/10-wpa_supplicant /usr/lib/dhcpcd/dhcpcd-hooks/

Enable dhcpcd service

sudo systemctl enable dhcpcd.service

Reboot into grub

Reboot system, booting off SSD (will probably need to press key on boot to go into boot device menu).

Log in as USERNAME.


/etc/hosts

Create /etc/hosts, of the form:

127.0.0.1 localhost

# Hosts on this LAN. Only possible if they have fixed ip addresses.
# The LAN router may also provide ip addresses (possibly with a "domain" of .lan or .local).
192.168.1.1 router.MYDOMAIN router # change MYDOMAIN to the domain I am giving this LAN
192.168.1.19 MYHOSTNAME.MYDOMAIN MYHOSTNAME # (change MYHOSTNAME to this system's hostname) this host
192.168.1.20 foo.MYDOMAIN bar # consider adding for other hosts on network with permanent ip addrs

1.2.3.4 someserver # shortname for system on other network

Set up ssh

(See https://wiki.archlinux.org/title/OpenSSH.)

install openssh package:

sudo pacman -S openssh

enable service

sudo systemctl enable sshd.service

Create main user’s ~/.ssh/

mkdir ~/.ssh
chmod 700 ~/.ssh

Allow users to login from remote systems

touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# add ssh public keys from remote systems to ~/.ssh/authorized_keys

SSD Trim

(See https://wiki.archlinux.org/title/Solid_state_drive.)

List which block devices support TRIM.

# Non-zero values for a device's DISC-GRAN and DISC-MAX indicate TRIM support
# (check that they make sense -- ie only SSDs should have TRIM enabled)
lsblk --discard

Enable fstrim service (controlled by a timer)

sudo systemctl --now enable fstrim.timer

Run fstrim as a test (should list all partitions that can be trimmed):

sudo fstrim --listed-in /etc/fstab:/proc/self/mountinfo --verbose

systemd-timesyncd (systemd version of ntp)

(See https://wiki.archlinux.org/title/Systemd-timesyncd.)

Configure:

cd /etc/systemd
sudo cp timesyncd.conf timesyncd.conf.orig
# enable the default ntp fallback servers
sudo sed -i -E -e 's/^#(FallbackNTP=)/\1/' timesyncd.conf

Enable/start

sudo systemctl --now enable systemd-timesyncd.service

Check status:

timedatectl status

Show Sync status:

timedatectl timesync-status

Enable git on /etc

Become root user

sudo -s

Create /root/.gitconfig:

cat <<+ > /root/.gitconfig
[user]
    name = root
    email = root@localhost
+

Create /etc/.gitignore:

(still as root user)

cat <<+ > /etc/.gitignore
*.swp
*-
*~
.updated
ld.so.cache
resolv.conf
lvm/archive/
lvm/backup/
+

Initial commit of /etc

(still as root user)

cd /etc
pacman -Q > pacman.lst # I keep a list of the currently installed packages here
git init
git add .
git commit -m 'initial commit'

Leave root user

exit

Later

I run

sudo bash -c "pacman -Q > /etc/pacman.lst"

after updating/installing packages to maintain a list of current packages installed.

Can run

cd /etc
sudo git status

after anything that might change files in /etc to see which files there have changed.

Can run

cd /etc
sudo git add .
sudo git commit -m 'package foo added' # eg

to record the changes.


Microcode updates

(See https://wiki.archlinux.org/title/Microcode.)

Install package amd-ucode (if have AMD CPU) or intel-ucode (if have Intel CPU):

sudo pacman -S amd-ucode

or

sudo pacman -S intel-ucode

Rerun grub-mkconfig

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

(grub automatically detects /boot/<cpu_manufacturer-ucode>.img and will load it before the normal initramfs.)


Secure Boot

NOTE: if grub is updated in the future, need to re-sign it (see end of this section)

(See

Will enable secure boot with “shim” (using shim from ubuntu which is signed with the Microsoft key). Shim then loads grub. Grub needs to be signed with a Machine Owner Key (MOK) I generate (which needs to be enrolled with shim).

Install shim-signed

shim-signed is in the Arch Linux User Repository (AUR). See https://wiki.archlinux.org/title/Arch_User_Repository for how to install an AUR package.

eg

mkdir -p ~/build/aur/
cd ~/build/aur/
git clone https://aur.archlinux.org/shim-signed.git
cd shim-signed
makepkg
sudo pacman -U shim-signed-15.7+ubuntu+1.56-1-any.pkg.tar.zst # change version to whatever tar.zst file was created
git clean -dfx

(Can later check for updates with

cd ~/build/aur/shim-signed
git pull

and rerun

makepkg
sudo pacman -U shim-signed-...tar.zst
git clean -dfx

if git pull reports the package had been updated.

Recommended though to use aur-check-updates (see below) regularly to check if package has been updated. )

Copy shim and MokManager to the boot loader directory

(This needs to be repeated whenever shim-signed is updated.)

(these instructions differ slightly from [2] - as my grub installation installed grub into $efi_d/EFI/GRUB/grubx64.efi and not into /boot/EFI/BOOT/BOOTx64.EFI as suggested in [2]:

Find what partition is the EFI System partition, and the directory it is mounted on:

efi_part=$(sudo fdisk -l -o device,type /dev/nvme0n1 | grep EFI | awk '{print $1}') # expect /dev/nvme0n1p1 for this AMD system
efi_d=$(mount | grep -F "$efi_part" | awk '{print $3}') # expect /boot for this AMD system

Copy shim and MokManager:

sudo cp /usr/share/shim-signed/shimx64.efi $efi_d/EFI/GRUB/
sudo cp /usr/share/shim-signed/mmx64.efi $efi_d/EFI/GRUB

The remaining steps only need doing on initial install

Install sbsigntools:

sudo pacman -S sbsigntools

Check boot order:

# make a note of any `BootXXXX` entries
sudo efibootmgr

Create nvram entry:

Find the disk and partition number of the EFI System partition:

[[ $efi_part =~ (/dev/nvme0n[0-9]+)p([0-9]+) ]]
efi_disk=${BASH_REMATCH[1]} # expect /dev/nvme0n1 on this AMD system
efi_p=${BASH_REMATCH[2]} # expect 1 on this AMD system

Create nvram entry:

sudo efibootmgr --unicode --disk $efi_disk --part $efi_p  --create --label "shim" --loader /EFI/GRUB/shimx64.efi

Delete any previous grubx64.efi entry

bootXXXX=$(sudo efibootmgr | grep -iF grubx64.efi | awk '{print $1}' | sed -E -e 's/^Boot([0-9]+).*/\1/') # eg '0000' if Boot0000 was the grubx64.efi entry added when grub was first installed (above)
[[ -n $bootXXXX ]] && sudo efibootmgr -b $bootXXXX -B

Create a MOK and sign the kernel:

sudo efi_d=$efi_d -s # become root, setting efi_d (from above) in root's environment

hostname=$(cat /etc/hostname)

mkdir /root/mok
chmod 700 /root/mok
cd /root/mok
openssl req -newkey rsa:2048 -nodes -keyout $hostname.key -new -x509 -sha256 -days 3650 -subj "/CN=$hostname/" -out $hostname.crt
openssl x509 -outform DER -in $hostname.crt -out $hostname.cer

sudo chmod 600 $hostname.key

# Save cer to under $efi_d/EFI/GRUB/$hostname.cer (can be publicly readable)
cp $hostname.cer $efi_d/EFI/GRUB

# sign the kernel
sbsign --key $hostname.key --cert $hostname.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux

exit # leave root

Automatically sign kernel when it is updated:

(adapted from [2])

sudo -s # become root

hostname=$(cat /etc/hostname)
cat <<+ > /etc/initcpio/post/kernel-sbsign
#!/usr/bin/env bash

kernel="\$1"
[[ -n "\$kernel" ]] || exit 0

# use already installed kernel if it exists
[[ ! -f "\$KERNELDESTINATION" ]] || kernel="\$KERNELDESTINATION"

keypairs=(/root/mok/$hostname.key /root/mok/$hostname.crt)

for (( i=0; i<\${#keypairs[@]}; i+=2 )); do
    key="\${keypairs[\$i]}" cert="\${keypairs[(( i + 1 ))]}"
    if ! sbverify --cert "\$cert" "\$kernel" &>/dev/null; then
      sbsign --key "\$key" --cert "\$cert" --output "\$kernel" "\$kernel"
    fi
done
+

exit # leave root

sudo chmod +x /etc/initcpio/post/kernel-sbsign

Reinstall grub with all modules embedded, and sign it

(Need to repeat this if grub is updated.)

(Note I do not copy $efi_d/EFI/GRUB/grubx64.efi to $efi_d/EFI/BOOT/grubx64.efi as in [2])

sudo -s # become root

PATH=/usr/bin

efi_part=$(fdisk -l -o device,type /dev/nvme0n1 | grep EFI | awk '{print $1}') # expect /dev/nvme0n1p1 for this AMD system
efi_d=$(mount | grep -F "$efi_part" | awk '{print $3}') # expect /boot for this AMD system

GRUB_MODULES="all_video boot btrfs cat chain configfile echo efifwsetup efinet ext2 fat font gettext gfxmenu gfxterm gfxterm_background gzio halt help hfsplus iso9660 jpeg keystatus loadenv loopback linux ls lsefi lsefimmap lsefisystab lssal memdisk minicmd normal ntfs part_apple part_msdos part_gpt password_pbkdf2 png probe reboot regexp search search_fs_uuid search_fs_file search_label sleep smbios squash4 test true video xfs zfs zfscrypt zfsinfo"
GRUB_MODULES+=" play cpuid tpm"
GRUB_MODULES+=" cryptodisk luks lvm"

# --bootloader-id=GRUB so that grubx64.efi is installed to $efi_d/EFI/GRUB/
# --no-nvram option so that it does not add a boot entry
grub-install --target=x86_64-efi --efi-directory=$efi_d --bootloader-id=GRUB --no-nvram --modules="${GRUB_MODULES}" --sbat /usr/share/grub/sbat.csv

hostname=$(cat /etc/hostname)
sbsign --key /root/mok/$hostname.key --cert /root/mok/$hostname.crt --output $efi_d/EFI/GRUB/grubx64.efi $efi_d/EFI/GRUB/grubx64.efi

exit # leave root

(Recommend put the above (except for the initial sudo -s and final exit) into a script eg /root/sh/grub-post-upgrade.sh. Add at the end:

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

Can run the script under sudo after any update of grub.)

Can use sbverify to check if files are signed:

hostname=$(cat /etc/hostname)
sudo sbverify --cert /root/mok/$hostname.crt /boot/vmlinuz-linux
sudo sbverify --cert /root/mok/$hostname.crt $efi_d/EFI/GRUB/grubx64.efi

Expect output Signature verification OK for each sbverify.

Enroll MOK certificate. Check secure boot

Reboot into BIOS, enable Secure Boot 2, boot into linux. On first boot after grub was signed, MokManager will launch so <hostname>.cer can be enrolled.

Check secure boot is enabled with

bootctl

Should be line:

Secure Boot: enabled

Enable magic SysRq key functionality

(See https://wiki.archlinux.org/title/Keyboard_shortcuts#Kernel_(SysRq), https://en.wikipedia.org/wiki/Magic_SysRq_key.)

The Alt-SysRq-X (or Alt-PrtScn-X) key combinations can be useful to grab control of the keyboard and then possibly kill all processes/reboot.

Under systemd, only a filesystem sync is allowed (Alt-SysRq-s) by default. To enable all functionality:

sudo bash -c 'echo "kernel.sysrq=1" > /etc/sysctl.d/100-sysrq.conf'

(it will then be available after the next boot).

Run

sudo bash -c 'echo 1 > /proc/sys/kernel/sysrq'

to enable immediately (but the previous command is needed for this change to persist on a reboot).

Note that this presents a small security risk if physical access is available to the system.


Enable multilib

(See https://wiki.archlinux.org/title/Official_repositories#multilib.)

Multilib is needed for eg steam.

Uncomment the [multilib] section in /etc/pacman.conf:

sudo sed -i -e '/^#\[multilib\]$/ {s/^#//; n; s/^#//}' /etc/pacman.conf

Upgrade system:

sudo pacman -Syu

Xorg

(See https://wiki.archlinux.org/title/Xorg.)

Install xorg group of packages:

sudo pacman -S xorg

(when asked which members in group xorg to install, just press “enter”, so all members are installed)

(Note this will also install wayland.)

Install graphics driver and libs for AMD GPU:

(check above link for notes on how to choose a driver)

sudo pacman -S xf86-video-amdgpu mesa lib32-mesa vulkan-radeon lib32-vulkan-radeon # for amd rdna and later

Additional packages:

sudo pacman -S mesa-utils

NetworkManager

(See https://wiki.archlinux.org/title/NetworkManager.)

Note: I did not install NetworkManager on this AMD 5800X3D/7800XT system, as it is a static desktop.

However, as this document is referred to by other documents (eg Arch Linux installation on my Razer Stealth 13 (early 2020) laptop), installation instructions are given here.

Install networkmanager package

sudo pacman -S networkmanager

Stop any network services currently running

eg

sudo systemctl stop dhcpcd
sudo systemctl stop wpa_supplicant

Enable and start NetworkManager

sudo systemctl –now enable NetworkManager

Under gnome (installed below), the wifi network to connect to can be set up under Settings -> Wi-Fi.


Gnome

(See https://wiki.archlinux.org/title/GNOME.)

Gnome provides a graphical desktop environment. See https://wiki.archlinux.org/title/Desktop_environment for other environments supported by Arch Linux.

Install gnome package group:

sudo pacman -S gnome

(when asked which members in group gnome to install, just press “enter”, so all members are installed)

(I chose noto-fonts-emoji (not ttf-joypixels) as provider for emoji-font (no particular reason), pipewire-jack as provider for jack (not jack2, see https://wiki.archlinux.org/title/JACK_Audio_Connection_Kit#Comparison_of_JACK_implementations, but no particular reason))

Install dconf-editor package:

(Not essential, but can be useful to see settings available for gnome.)

sudo pacman -S dconf-editor

Enable gnome to start automatically on next boot:

sudo systemctl enable gdm.service

Reboot system. Should boot up into gnome.

Gnome settings

Log in. Bring up Settings (eg Windows key -> [Search for Settings]).

Check Keyboard -> Input Sources lists the correct keyboard layout. Change if needed.

I prefer to set other settings manually, eg:

gsettings set org.gnome.desktop.wm.preferences focus-mode sloppy # windows will get focus when mouse cursor is moved to it (don't have to click)
gsettings set org.gnome.desktop.wm.preferences audible-bell false
gsettings set org.gnome.desktop.interface clock-show-weekday true
gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type nothing # Disable suspend when on AC power
gsettings set org.gnome.desktop.lockdown disable-lock-screen false # enable screen locking
gsettings set org.gnome.desktop.session idle-delay 1200 # time before screen goes blank (in secs)
gsettings set org.gnome.desktop.screensaver lock-delay 0 # time after blanking screen before locking screen (in secs)

Set up a custom key-combination (Ctrl-Alt-t) to open a Gnome Console:

gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']"

# kgx is the Gnome Console
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ name Console
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ command kgx
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ binding "<Primary><Alt>t"

(add further custom keys by replacing custom0 above by custom1 etc).

I also like to be automatically logged in to my account on power up (since I already have to enter the LUKS-encryption password).

Edit /etc/gdm/custom.conf. In section [daemon], add:

AutomaticLoginEnable = True
AutomaticLogin = USERNAME

where USERNAME is the username of who should be logged in.

Note: (2024-01-26) Temporarily disabled automatic login on this system (by commenting out the above lines) as am regularly getting boot stuck on Started Session 1 of User USERNAME before gnome session starts. Have to then remote log in, then sudo pkill gdm. (2024-06-02) Reenabled automatic login which seems to work ok now (have linux-6.9.3.arch1-1, gdm 46.2-1, wayland-1.23.0-1).

Fractional scaling on some monitors

(See also https://wiki.archlinux.org/title/HiDPI.)

I usually have the system connected to a 28” 3840x2160 monitor, but occasionally connect instead to a 27” 2560x1440 monitor where I find the windows and fonts too large. I want to scale everything to be smaller. To do this:

    gsettings set org.gnome.mutter experimental-features '["scale-monitor-framebuffer", "xwayland-native-scaling"]'

The above assumes gnome is running under wayland.

Not everything works right. Eg Elder Scrolls Online running under steam/proton in full screen mode does not work properly (but windowed mode runs fine).

Allowed scales

The value for <scale> must be chosen such that <width>/<scale> and <height>/<scale> are integers (where <width> and <height> are as appear in ~/.config/monitors.xml). Else get error in log “Scaled logical monitor size is fractional”, and the config file will be ignored (see code in https://gitlab.gnome.org/GNOME/gnome-flashback/-/blob/master/backends/gf-logical-monitor-config.c).

Gnome reads the scale as a float (via read_float defined in https://gitlab.gnome.org/GNOME/gnome-flashback/-/blob/master/backends/gf-monitor-config-store.c), and the width and height as ints. Then <scale> must be such that

floorf(width/scale) == width/scale

and

floorf(height/scale) == height/scale

where floorf(x) is a c function returning the integer value ≤x. So for example, if width=1366 and height=768, it is ok to set scale=0.66666666: width/scale will be calculated as 2049.0000000000000000 and height/scale will be calculated as 1152.0000000000000000 (ie they are integers to within float precision).

GDM settings

GDM (Gnome Display Manager) handles the initial graphical user login (amongst other things).

It has its own gsettings database.

By default the system will suspend if the gdm user login screen is displayed without a user logging in for more than 900s. To prevent this when on AC power (https://wiki.archlinux.org/title/GDM#GDM_auto-suspend_(GNOME_3.28)) :

sudo -u gdm dbus-launch gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type 'nothing'

CUPS

(If have printers.)

(See https://wiki.archlinux.org/title/CUPS.)

Install cups package:

sudo pacman -S cups

Install cups-pdf to allow printing to pdf

sudo pacman -S cups-pdf

Install any additional drivers. Eg:

# HP DeskJet, OfficeJet, Photosmart, Business Inkjet and some LaserJet
sudo pacman -S hplip

Modify the cups-pdf output directory

# Change output directory from default of /var/spool/cups-pdf/${USER} to {$HOME}/Documents
sudo sed -i -E -e 's/^#Out (.*)/Out ${HOME}\/Documents/' /etc/cups/cups-pdf.conf

Set cups to use cups.socket rather than cups.services

(So the service will not always run, it will just start up for each print job.)

sudo systemctl enable cups.socket
sudo systemctl start cups.socket

Add printers

Use eg web interface at http://localhost:631 -> Administration -> Find New Printers

If have git management of /etc (see above), suggest:

sudo bash -c 'echo "cups/printers.conf" >> /etc/.gitignore'
sudo bash -c 'echo "cups/printers.conf.O" >> /etc/.gitignore'
sudo bash -c 'echo "cups/subscriptions.conf" >> /etc/.gitignore'
sudo bash -c 'echo "cups/subscriptions.conf.O" >> /etc/.gitignore'
sudo bash -c 'echo "*.socket" >> /etc/.gitignore'

Subsequent configuration

(A sketch of some initial configuration to do.)

[core]
    editor = /usr/bin/vim
[user]
    name = MYNAME
    email = NAME@DOMAIN
[alias]
    log-with-tags = log --pretty=oneline --abbrev-commit --graph --decorate

change MYNAME etc as needed; I’ve set up an alias so git log-with-tags gives an abbreviated git log also showing tags).


Other archlinux packages

This is a list of packages I find useful. See https://archlinux.org/packages/ for the list of Arch Linux packages.

I run

  sudo paccache -r

occasionally to clear the cache in /var/cache/pacman/pkg/ (leaving the latest 3 versions of any package).


Other archlinux user repository (AUR) packages

(See https://aur.archlinux.org/packages)

[P]: must be reinstalled if python is upgraded to a new minor version.


Subsequent installation notes

2024-01-09
systemd 255.2-1 -> 255.2-2

systemd got a new dependency: dbus-units, which could be provided by either dbus-broker-units (the default), or dbus-daemon-units. https://archlinux.org/news/making-dbus-broker-our-default-d-bus-daemon/ recommends dbus-broker-units, which is what I chose.

2024-01-18
amd-ucode 20231211.f2e52a1c-1 -> 20240115.9b6d0b08-1, linux-firmware 20231211.f2e52a1c-1 -> 20240115.9b6d0b08-1, linux-firmware-whence 20231211.f2e52a1c-1 -> 20240115.9b6d0b08-1

This caused a lot of problems. Most boots, it would not get past “Triggering uevents” in the initramfs stage of the boot. If it did get past that stage, wifi would generally not work. Kernel version is linux 6.7.arch3-1.

I downgraded the packages back to their earlier versions, and added

IgnorePkg  = amd-ucode linux-firmware linux-firmware-whence

to /etc/pacman.conf. This seemed to fix the issue.

(2024-01-24 (after kernel upgraded to linux 6.7.1.arch1-1): removed the above IgnorePkg line, and reupgraded amd-ucode, linux-firmware, linux-firmware-whence. Boots more reliably now.)

2024-03-17
mkinitcpio 38-4 -> mkinitcpio 38.1-1

The ALL_microcode option in /etc/mkinitcpio.d/linux.preset is now deprecated (see https://archlinux.org/news/mkinitcpio-hook-migration-and-early-microcode/). I removed it and recreated the initramfs with sudo mkinitcpio -P . (The microcode is still loaded by grub - see /boot/grub/grub.cfg, see the line initrd /amd-ucode.img /initramfs-linux.img. So there’s no need to use the microcode hook in /etc/mkinitcpio.conf.)

2024-05-04
linux 6.8.8.arch1-1 -> 6.8.9.arch1-1

gnome-shell dumped core, and got a forced logout. Even after a restart, could not play Elder Scrolls Online (game froze during login). Downgraded back to earlier version, and added

IgnorePkg = linux

to /etc/pacman.conf.

See also https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/47.

2024-05-15
python-exceptiongroup removed

python-exceptiongroup has been dropped (https://archlinux.org/todo/drop-python-exceptiongroup/). Remove with

sudo pacman -R python-exceptiongroup
2024-05-19
linux 6.8.8.arch1-1 -> 6.9.1.arch1-1

linux 6.9.1 has been released, which hopefully fixes problem of 2024-05-04. Removed IgnorePkg = linux from /etc/pacman.conf and upgraded system. System seems fine now.

2024-09-28
tracker3 replaced by extra/tinysparql, tracker3-miners replaced by extra/localsearch

See https://blogs.gnome.org/carlosg/2024/07/14/goodbye-tracker-hello-tinysparql-and-localsearch/.

2024-09-29
qemu-common 9.0.2-1 -> qemu-common-9.1.0-2

qemu-common-9.1.0-2 and qemu-system-nios2-9.0.2-1 reported as in conflict. Remove qemu-system-nios2 when prompted. See https://wiki.qemu.org/ChangeLog/9.1 (the NIOS II target has been removed).

2024-11-24
linux-6.11.9 -> linux-6.12.1,

System misbehaved (in particular, browsers would not start up, ssh did not work). Downgraded back to earlier version, and added

IgnorePkg = linux

to /etc/pacman.conf.

2024-12-19
linux 6.11.9 -> 6.12.4,

linux 6.12.4 has been released, which hopefully fixes problem of 2024-11-24. Removed IgnorePkg = linux from /etc/pacman.conf and upgraded system. System seems fine now.

2024-12-28
qemu-common 9.1.2-1 -> qemu-common-9.2.0-1

qemu-common-9.2.0-1 and qemu-system-cris-9.1.2-1 reported as in conflict. Responding “y” to “Remove qemu-system-cris?” during attempted update fails (as qemu-system-cris is a dependency of qemu-emulators-full).

Force removal of qemu-system-cris with sudo pacman -Rdd qemu-system-cris. Can then proceed with sudo pacman -Syu.


Refs


  1. Many of the steps were taken/adapted from [1], and so this document is released under the GNU Free Documentation License 1.3 or later.↩︎

  2. For the motherboard for this build (Gigabyte B550 Aorus Elite AX V2), to enable secure boot:

    • (Advanced Mode) Boot -> CSM Support: set Disabled (Boot -> Secure Boot option now appears )
    • “System Mode” is shown as “Setup”, and need to enroll platform key:
      • Change Secure Boot Mode to Custom, then back to Standard.
      • Install factory defaults? Yes
      • Reset without saving? Yes (system reboots)
    ↩︎