%! TEX program = lualatex

\documentclass[10pt]{dustdoc}

\title{\texorpdfstring{{\scshape{\Huge DustArch}\\{\normalsize\vspace{2.5em}}}}{DustArch: }DustVoice’s Arch Linux from scratch}
\author{David Holland}
\date{\today{}}

\begin{document}
\maketitle

\tableofcontents

\chapter{Inside the \texttt{archiso}}
\label{sec:inside-the-archiso}

This chapter is aimed at assisting with the general setup of a customized Arch Linux installation, using an official Arch Linux image (\texttt{archiso}).

\begin{NOTE}
    As Arch Linux is a rolling release GNU/Linux distribution, it is advised, to have a working internet connection, in order to get the latest package upgrades and to install additional software, as the \texttt{archiso} doesn't have all packages available from cache, especially the ones that need to be installed from the \texttt{AUR}.

    Furthermore, one should bear in mind that depending on the version, or rather modification date, of this guide, the exact steps taken may already be outdated.
    If you encounter any problems along the way, you will either have to resolve the issue yourself, or utilize the great \hreffn{https://wiki.archlinux.org/}{ArchWiki}, or the \hreffn{https://bbs.archlinux.org/}{Arch Linux forums}.
\end{NOTE}

\section{\texttt{Sy}ncing up \texttt{pacman}}
\label{sec:syncing-up-pacman}

First of all we need to sync up \texttt{pacman}'s package repository, in order to be able to install the latest, as well as new packages to the \texttt{archiso} and our new system.

\begin{minted}{console}
root@archiso ~ # pacman -Sy
\end{minted}

\begin{WARNING}
    Using \mintinline{console}{$ pacman -Sy} should be sufficient, in order to be able to search for packages from within the \texttt{archiso}, without upgrading the system, but might break your system, if you use this command on an existing installation!

    To be on the safe side, it is advised to always use \mintinline{console}{$ pacman -Syu} instead!

    \texttt{pacstrap} uses the latest packages anyways.
\end{WARNING}

\subsection{Official repositories}
\label{sec:official-repositories}

After doing that, we can now install any software from the official repositories by issuing

\begin{minted}{console}
root@archiso ~ # pacman -S <package_name>
\end{minted}

\noindent
where you would replace \texttt{<package\_name>} with the actual package name.

If you want to remove an installed package, just use

\begin{minted}{console}
root@archiso ~ # pacman -Rsu <package_name>
\end{minted}

If you don’t know the exact package name, or if you just want to search for a keyword, for example \texttt{xfce}, to list all packages having to do something with \texttt{xfce}, use

\begin{minted}{console}
root@archiso ~ # pacman -Ss <keyword>
\end{minted}

\begin{CAUTION}
    If you really need to force remove a package, which you should use \emph{with extreme caution}, you could use

    \begin{minted}{console}
root@archiso ~ # pacman -Rdd <package_name>
    \end{minted}
\end{CAUTION}

\subsection{\texttt{AUR}}
\label{sec:aur}

If you want to install a package from the \hreffn{https://aur.archlinux.org/}{\texttt{AUR}}, I would advise proceeding in the following manner

\begin{enumerate}
    \item \texttt{cd} into the dedicated \mintinline{text}{~/AUR} directory, if you’re using the \texttt{dotfiles} repo, which provides you with an \mintinline{text}{update} \texttt{bash} script within that folder, to check every subfolder for updates

        \begin{minted}{console}
dustvoice@archiso ~ $ cd AUR
        \end{minted}

    \item Clone the package with \texttt{git}

        \begin{minted}{console}
dustvoice@archiso ~/AUR $ git clone https://aur.archlinux.org/pacman-git.git
        \end{minted}

    \item Switch to the package directory

        \begin{minted}{console}
dustvoice@archiso ~/AUR $ cd pacman-git
        \end{minted}

    \item Execute \mintinline{console}{$ makepkg}

        \begin{minted}{console}
dustvoice@archiso ~/AUR/pacman-git $ makepkg -si
        \end{minted}

    \item Delete all files created by \texttt{makepkg}, in order to easily see, if a package needs an update by using \mintinline{console}{$ git fetch --all} and \mintinline{console}{$ git status}

        \begin{minted}{console}
dustvoice@archiso ~/AUR/pacman-git $ git reset HEAD --hard
dustvoice@archiso ~/AUR/pacman-git $ git clean -fdx
        \end{minted}
\end{enumerate}

\begin{NOTE}
    You might have to resolve some \texttt{AUR} dependencies manually, which can’t be automatically resolved by \texttt{makepkg}'s \texttt{-s} option, whitch uses \texttt{pacman}.
\end{NOTE}

\begin{WARNING}
    In order to install the desired \texttt{AUR} package, you \emph{must} switch to your normal, non-\texttt{root} user, because \texttt{makepkg} doesn’t run as \texttt{root}.
\end{WARNING}

\begin{NOTE}
    As mentioned before, there is an \mintinline{text}{update} \texttt{bash} script available within the \mintinline{text}{~/AUR} directory, when using the \texttt{dotfiles} repository, which enables you to quickly check all cloned \texttt{AUR} repositories within said directory for updates and even install them in the same step.

    Issue \mintinline{console}{$ ./update --help} for command line options.
\end{NOTE}

\subsection{Software categories}
\label{sec:software-categories}

In this guide, software is categorized in three different categories

\begin{itemize}
    \item \texttt{Console} software is intended to be used with either the native linux console, or with a terminal emulator

    \item \texttt{GUI} software is intended to be used within a graphical desktop environment

    \item \texttt{Hybrid} software can either be used within both a console and a graphical desktop environment (e.g. \texttt{networkmanager}), or there are packages available for both console and a graphical desktop environment (e.g. \texttt{pulseaudio} with \texttt{pulsemixer} for \texttt{Console} and \texttt{pavucontrol} for \texttt{GUI})
\end{itemize}

\subsection{Software installation}
\label{sec:software-installation}

In this guide, I’ll be explicitly listing the packages installed in a specific section at the beginning of the individual sections.

This allows you to

\begin{itemize}
    \item clearly see what packages get installed / need to be installed in a specific section

    \item install packages before you start with the section in order to minimize waiting time

    \item not having to accidentally reinstall already installed packages
\end{itemize}

\begin{NOTE}
    The packages are always the recommended packages.

    For further clarification for specific packages (e.g. \texttt{UEFI} specific packages), continue reading the section, as there is most certainly an explanation there.

    Of course, as always, you can and should adapt everything according to your needs, as this guide is, again, \emph{no tutorial, but a guide}.
\end{NOTE}

\subsubsection{Example section}
\label{sec:example-section}

\begin{packagetable}
    \texttt{core} & \texttt{libutil-linux} \\
    \texttt{extra} & \texttt{git} \\
    \texttt{community} & \texttt{ardour cadence jsampler linuxsampler qsampler sample-package} \\
    \texttt{AUR} & \texttt{sbupdate} \\
\end{packagetable}

You have to configure \texttt{sample-package}, by editing \texttt{/etc/sample.conf}

\begin{mintedlisting}
    \begin{minted}{text}
Sample.text=useful
    \end{minted}

    \caption{\mintinline{text}{/etc/sample.conf}}
\end{mintedlisting}

\section{Formatting the drive}
\label{sec:formatting-the-drive}

First, you probably want to get a list of all available drives, together with their corresponding device name, by issuing

\begin{minted}{console}
root@archiso ~ # fdisk -l
\end{minted}

\begin{NOTE}
    The output of \mintinline{console}{$ fdisk -l} is dependent on your system configuration and many other factors, like \texttt{BIOS} initialization order, etc.

    \begin{CAUTION}
        Don't assume the same path of a device between reboots!

        Always double check!

        There is nothing worse than formatting a drive you didn't mean to format!
    \end{CAUTION}
\end{NOTE}

\subsection{The standard way}
\label{sec:the-standard-way}

In my case, the partition I want to install the root file system on is \mintinline{text}{/dev/sdb2}.
\mintinline{text}{/dev/sdb3} will be my \texttt{swap} partition.

\begin{NOTE}
    A \texttt{swap} size twice the size of your RAM is recommended by a lot of people.

    To be exact, every distribution has different recommendations for \texttt{swap} sizes.
    Also \texttt{swap} size heavily depends on whether you want to be able to hibernate, etc.

    \paragraph{In my opinion}
    You should make the \texttt{swap} size at least your RAM size and for RAM sizes over \texttt{4GB} and the wish to hibernate, at least one and a half your RAM size.
\end{NOTE}

\begin{IMPORTANT}
    If you haven’t yet partitioned your disk, please refer to the \hreffn{https://wiki.archlinux.org/index.php/Partitioning}{general partitioning tutorial} in the ArchWiki.
\end{IMPORTANT}

Now we need to format the partitions accordingly

\begin{minted}{console}
root@archiso ~ # mkfs.ext4 /dev/sdb2
root@archiso ~ # mkswap /dev/sdb3
\end{minted}

After doing that, we can turn on the \texttt{swap} and mount the root partition.

\begin{minted}{console}
root@archiso ~ # swapon /dev/sdb3
root@archiso ~ # mount /dev/sdb2 /mnt
\end{minted}

\begin{NOTE}
    If you have an additional EFI System partition, because of a \emph{UEFI - GPT} setup or an existing Windows installation, for example, which we will assume to be located under \mintinline{text}{/dev/sda2} (\mintinline{text}{/dev/sda} is the disk of my Windows install), you’ll have to mount this partition to the new system's \mintinline{text}{/boot} folder

    \begin{minted}{console}
root@archiso ~ # mkdir /mnt/boot
root@archiso ~ # mount /dev/sda2 /mnt/boot
    \end{minted}
\end{NOTE}

\subsection{Full system encryption}
\label{sec:full-system-encryption}

\begin{NOTE}
    This is only one way to do it and it is the way I have done it.
    I’m using a \texttt{LVM} on \texttt{LUKS} setup, with \texttt{lvm2} and \texttt{luks2}.
    For more information look into the \hreffn{https://wiki.archlinux.org/}{ArchWiki}.
\end{NOTE}

\begin{NOTE}
    This setup has different partitions, used for the EFI System partition, the \texttt{root} partition, etc., compared to the ones used in the rest of the guide.
    If you want to use \texttt{grub} in conjunction with some full system encryption, you would have to adapt the disk and partition names accordingly.
    The only part of the guide, which currently uses the drives \& partitions used in this section is \nameref{sec:the-manual-way}.
\end{NOTE}

To start things, we first have to decide, which disk, or partition, is going to hold the \texttt{luks2} encrypted \texttt{lvm2} stuff.

In my case I’ll be using my NVMe SSD, with a \texttt{GPT} partition scheme, for both the EFI System partition, in my case \mintinline{text}{/dev/nvme0n1p1}, defined as a \texttt{EFI System} partition type in \texttt{fdisk}, as well as the main \texttt{LUKS} volume, in my case \mintinline{text}{/dev/nvme0n1p2}, defined as a \texttt{Linux filesystem} partition type in \texttt{fdisk}.

After partitioning our disk, we now have to set everything up.

\subsubsection{EFI System partition}
\label{sec:efi-system-partition}

\begin{packagetable}
    \texttt{core} & \texttt{dosfstools} \\
\end{packagetable}

I won’t setup my EFI System partition with \texttt{cryptsetup}, as it makes no sense in my case.

Every \texttt{EFI} binary (or \texttt{STUB}) will have to be signed with my custom Secure Boot keys, as described in \nameref{sec:the-manual-way}, so tempering with the EFI System partition poses no risk to my system.

Instead I will simply format it with a \texttt{FAT32} filesystem

\begin{minted}{console}
root@archiso ~ # mkfs.fat -F 32 -L /efi /dev/nvme0n1p1
\end{minted}

We will bother with mounting it later on.

\begin{NOTE}
    When you \emph{do} want to encrypt your EFI System partition, in conjunction with using \texttt{grub}, please either use \texttt{LUKS 1}, or make sure to have the latest version of \texttt{grub} installed on your system, to make it work with \texttt{LUKS 2}!
\end{NOTE}

\subsubsection{\texttt{LUKS}}
\label{sec:luks}

\begin{packagetable}
    \texttt{core} & \texttt{cryptsetup} \\
\end{packagetable}

First off we have to create the \texttt{LUKS} volume

\begin{minted}{console}
root@archiso ~ # cryptsetup luksFormat --type luks2 /dev/nvme0n1p2
\end{minted}

After that we have to open the volume

\begin{minted}{console}
root@archiso ~ # cryptsetup open /dev/nvme0n1p2 cryptroot
\end{minted}

The volume is now accessible under \mintinline{text}{/dev/mapper/cryptroot}.

\subsubsection{\texttt{LVM}}
\label{sec:lvm}

\begin{packagetable}
    \texttt{core} & \texttt{lvm2} \\
\end{packagetable}

I’m going to create one \texttt{PV} (Physical Volume) using the just created and opened \texttt{cryptroot} \texttt{LUKS} volume, one \texttt{VG} (Volume Group), named \texttt{DustArch1}, which will contain two \texttt{LV}s (Logical Volumes) named \texttt{root} and \texttt{swap} containing the \texttt{root} filesystem and the \texttt{swap} space respectively.

\begin{minted}{console}
root@archiso ~ # pvcreate /dev/mapper/cryptroot
root@archiso ~ # vgcreate DustArch1 /dev/mapper/cryptroot
root@archiso ~ # lvcreate -L 100%FREE -n root DustArch1
root@archiso ~ # lvreduce -l -32G /dev/DustArch1/root
root@archiso ~ # lvcreate -L 100%FREE -n swap DustArch1
\end{minted}

\subsubsection{Format \& mount}
\label{sec:format-and-mount}

Now the only thing left to do is formatting our freshly created logical volumes appropriately

\begin{minted}{console}
root@archiso ~ # mkfs.ext4 -L / /dev/DustArch1/root
root@archiso ~ # mkswap /dev/DustArch1/swap
\end{minted}

\noindent
as well as mounting them and enabling the \texttt{swap}, in order to proceed with the next steps.

\begin{minted}{console}
root@archiso ~ # mount /dev/DustArch1/root /mnt
root@archiso ~ # mkdir /mnt/efi
root@archiso ~ # mount /dev/nvme0n1p1 /mnt/efi
root@archiso ~ # swapon /dev/DustArch1/swap
\end{minted}

\subsubsection{Unmount \& Close}
\label{sec:unmount-and-close}

\begin{WARNING}
    Only do this, after you’re finished with your setup within the \texttt{archiso} and are about to reboot into your new system, or else the next steps won’t work for you.
\end{WARNING}

To close everything back up again,

\begin{enumerate}
    \item unmount the volumes

        \begin{minted}{console}
root@archiso ~ # umount /mnt/efi /mnt
        \end{minted}

    \item deactivate the \texttt{VG}

        \begin{minted}{console}
root@archiso ~ # vgchange -a n DustArch1
        \end{minted}

    \item close the \texttt{LUKS} volume

        \begin{minted}{console}
root@archiso ~ # cryptsetup close cryptroot
        \end{minted}
\end{enumerate}

\section{Preparing the \texttt{chroot} environment}
\label{sec:preparing-the-chroot-environment}

First it might make sense to edit \mintinline{text}{/etc/pacman.d/mirrorlist} to move the mirror(s) geographically closest to you to the top.

If you're using an older version of the \texttt{archiso}, you might want to replace the mirrorlist present on the \texttt{archiso} with the newest one from \hreffn{https://archlinux.org/mirrorlist}{https://archlinux.org/mirrorlist}

\begin{minted}{console}
root@archiso ~ # curl https://archlinux.org/mirrorlist/all > /etc/pacman.d/mirrorlist
\end{minted}

\begin{NOTE}
    \begin{packagetable}
        \texttt{community} & \texttt{reflector} \\
    \end{packagetable}

    The best way to do this, is using a package from the official repositories named \texttt{reflector}.
    It comes with all sorts of options, for example sorting mirrors by speed, filtering by country, etc.

    \begin{minted}{console}
root@archiso ~ # reflector --verbose --latest 200 --sort rate --save /etc/pacman.d/mirrorlist
    \end{minted}

    After that you would need to reinstall the \texttt{pacman-mirror} package and run

    \begin{minted}{console}
root@archiso ~ # pacman -Syyuu
    \end{minted}

    \noindent
    for the best results.
\end{NOTE}

After that we can \texttt{pacstrap} the \emph{minimum packages} needed.
We will install all other packages later on.

\begin{packagetable}
    \texttt{core} & \texttt{base linux linux-firmware} \\
\end{packagetable}

\begin{NOTE}
    This is the actual command used in my case

    \begin{minted}{console}
root@archiso ~ # pacstrap /mnt base linux linux-firmware
    \end{minted}
\end{NOTE}

After that generate an \texttt{fstab} using \texttt{genfstab}

\begin{minted}{console}
root@archiso ~ # genfstab -U /mnt >> /mnt/etc/fstab
\end{minted}

\noindent
and you’re ready to enter the \texttt{chroot} environment.

\chapter{Entering the \texttt{chroot}}
\label{sec:entering-the-chroot}

\begin{NOTE}
    As we want to set up our new system, we need to have access to the different partitions, the internet, etc. which we wouldn’t get by solely using \texttt{chroot}.

    That’s why we are using \texttt{arch-chroot}, provided by the \texttt{arch-install-scripts} package, which is shipped with the \texttt{archiso}.
    This script takes care of all the afforementioned stuff, so we can set up our system properly.
\end{NOTE}

\begin{minted}{console}
root@archiso ~ # arch-chroot /mnt
\end{minted}

Et Voil\`{a}! You successfully \texttt{chroot}ed inside your new system and you’ll be greeted by a \texttt{bash} prompt, which is the default shell on fresh Arch Linux installations.

\section{Installing additional packages}
\label{sec:installing-additional-packages}

\begin{packagetable}
    \texttt{core} & \texttt{amd-ucode base-devel diffutils dmraid dnsmasq dosfstools efibootmgr exfat-utils grub iputils lvm2 openssh sudo usbutils} \\
    \texttt{extra} & \texttt{efitools git intel-ucode networkmanager networkmanager-openconnect networkmanager-openvpn parted polkit rsync zsh} \\
    \texttt{community} & \texttt{neovim os-prober} \\
\end{packagetable}

\begin{NOTE}
    There are many command line text editors available, like \texttt{nano}, \texttt{vi}, \texttt{vim}, \texttt{emacs}, etc.

    I’ll be using \texttt{neovim}, though it shouldn’t matter what editor you choose for the rest of the guide.
\end{NOTE}

Make sure to enable the \mintinline{text}{NetworkManager.service} service, in order for the Internet connection to work correctly, upon booting into the fresh system later on.

\begin{minted}{console}
[root@archiso /]# systemctl enable NetworkManager.service
\end{minted}

With \texttt{polkit} installed, create a file to enable users of the \texttt{network} group to add new networks without the need of \texttt{sudo}.

\begin{mintedlisting}
    \begin{minted}{text}
polkit.addRule(function(action, subject) {
    if (action.id.indexOf("org.freedesktop.NetworkManager.") == 0 && subject.isInGroup("network")) {
        return polkit.Result.YES;
    }
});
    \end{minted}

    \caption{\mintinline{text}{/etc/polkit-1/rules.d/50-org.freedesktop.NetworkManager.rules}}
\end{mintedlisting}

If you use \texttt{UEFI}, you’ll also need the \texttt{efibootmgr}, in order to modify the \texttt{UEFI} entries.

\section{Master of time}
\label{sec:master-of-time}

After that, you have to set your timezone and update the system clock.

Generally speaking, you can find all the different timezones under \mintinline{text}{/usr/share/zoneinfo}.

In my case, my timezone file resides under \mintinline{text}{/usr/share/zoneinfo/Europe/Berlin}.

To achieve the desired result, I will want to symlink this to \mintinline{text}{/etc/localtime} and set the hardware clock.

\begin{minted}{console}
[root@archiso /]# ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
[root@archiso /]# hwclock --systohc --utc
\end{minted}

Now you can also enable time synchronization over network

\begin{minted}{console}
[root@archiso /]# timedatectl set-timezone Europe/Berlin
[root@archiso /]# timedatectl set-ntp true
\end{minted}

\noindent
and check that everything is alright

\begin{minted}{console}
[root@archiso /]# timedatectl status
\end{minted}

\section{Master of locales}
\label{sec:master-of-locales}

Now you have to generate your locale information.

For that you have to edit \mintinline{text}{/etc/locale.gen} and uncomment the locales you want to enable.

\begin{NOTE}
    I recommend to always uncomment \mintinline{text}{en_US.UTF-8 UTF8}, even if you want to use another language primarily.
\end{NOTE}

In my case I only uncommented the \mintinline{text}{en_US.UTF-8 UTF8} line

\begin{mintedlisting}
    \begin{minted}{text}
en_US.UTF-8 UTF8
    \end{minted}

    \caption{\mintinline{text}{/etc/locale.gen}}
\end{mintedlisting}

After that you still have to actually generate the locales by issuing

\begin{minted}{console}
[root@archiso /]# locale-gen
\end{minted}

\noindent
and set the locale

\begin{minted}{console}
[root@archiso /]# localectl set-locale LANG="en_US.UTF-8"
\end{minted}

After that we’re done with this part.

\section{Naming your machine}
\label{sec:naming-your-machine}

Now we can set the \texttt{hostname} for our new install and add \texttt{hosts} entries.

Apart from being mentioned in your command prompt, the \texttt{hostname} also serves the purpose of identifying, or naming your machine locally, as well as in a networked scenario.  This will enable you to see your PC with the correct name in your router, etc.

\subsection{\texttt{hostname}}
\label{sec:hostname}

To change the \texttt{hostname}, simply edit \mintinline{text}{/etc/hostname}, enter the desired name, then save and quit

\begin{mintedlisting}
    \begin{minted}{text}
DustArch
    \end{minted}

    \caption{\mintinline{text}{/etc/hostname}}
\end{mintedlisting}

\subsection{\texttt{hosts}}
\label{sec:hosts}

Now we need to specify some \texttt{hosts} entries by editing \mintinline{text}{/etc/hosts}

\begin{mintedlisting}
    \begin{minted}{text}
# Static table lookup for hostnames.
# See hosts(5) for details.

127.0.0.1   localhost           .
::1         localhost           .
127.0.1.1   DustArch.localhost  DustArch
    \end{minted}

    \caption{\mintinline{text}{/etc/hosts}}
\end{mintedlisting}

\section{User setup}
\label{sec:user-setup}

Now you should probably change the default \texttt{root} password and create a new non-\texttt{root} user for yourself, as using your new system purely through the native \texttt{root} user is not recommended from a security standpoint.

\subsection{Give \texttt{root} a password}
\label{sec:give-root-a-password}

To change the password for the current user (the \texttt{root} user) issue

\begin{minted}{console}
[root@archiso /]# passwd
\end{minted}

\noindent
and choose a new password.

\subsection{Create a personal user}
\label{sec:create-a-personal-user}

\begin{packagetable}
    \texttt{core} & \texttt{sudo} \\
    \texttt{extra} & \texttt{zsh} \\
\end{packagetable}

We are going to create a new user and set the password, groups and shell for this user

\begin{minted}{console}
[root@archiso /]# useradd -m -p "" -G "adm,audio,disk,floppy,kvm,log,lp,network,rfkill,scanner,storage,users,optical,power,wheel" -s /usr/bin/zsh dustvoice
[root@archiso /]# passwd dustvoice
\end{minted}

We now have to allow the \texttt{wheel} group \texttt{sudo} access.

For that we edit \mintinline{text}{/etc/sudoers} and uncomment the \mintinline{text}{%wheel [...]} line

\begin{mintedlisting}
    \begin{minted}{text}
%wheel ALL=(ALL) ALL
    \end{minted}

    \caption{\mintinline{text}{/etc/sudoers}}
\end{mintedlisting}

You could also add a new line below the \texttt{root} line

\begin{mintedlisting}
    \begin{minted}{text}
root ALL=(ALL) ALL
    \end{minted}

    \caption{\mintinline{text}{/etc/sudoers}}
\end{mintedlisting}

\noindent
with your new username

\begin{mintedlisting}
    \begin{minted}{text}
dustvoice ALL=(ALL) ALL
    \end{minted}

    \caption{\mintinline{text}{/etc/sudoers}}
\end{mintedlisting}

\noindent
to solely grant the \emph{new} user \texttt{sudo} privileges.

\section{Boot manager}
\label{sec:boot-manager}

In this section different boot managers / boot methods are explained.

\subsection{\texttt{EFISTUB}}
\label{sec:efistub}

\begin{packagetable}
    \texttt{core} & \texttt{efibootmgr} \\
\end{packagetable}

You can directly boot the system, by making use of the \texttt{EFISTUB} contained in the kernel image.
To utilize this, we can use \texttt{efibootmgr} to create an entry in the \texttt{UEFI}

\begin{minted}{console}
[root@archiso /]# efibootmgr --disk /dev/sda --part 2 --create --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=6ff60fab-c046-47f2-848c-791fbc52df09 rw initrd=\initramfs-linux.img resume=UUID=097c6f11-f246-40eb-a702-ba83c92654f2' --verbose
\end{minted}

\begin{NOTE}
    This only makes sense of course, if you're using \texttt{UEFI} instead of a legacy \texttt{BIOS}.
    In this case it doesn't matter of course, if your machine \emph{theoretically supports} \texttt{UEFI}, but rather if it is the \emph{enabled mode}!
\end{NOTE}

\subsection{\texttt{grub}}
\label{sec:grub}

\begin{packagetable}
    \texttt{core} & \texttt{dosfstools efibootmgr grub} \\
    \texttt{extra} & \texttt{mtools} \\
    \texttt{community} & \texttt{os-prober} \\
\end{packagetable}

Of course you can also use a boot manager to boot the system, as the name implies.

If I can't use \texttt{EFISTUB}, e.g. either because the system has no \texttt{UEFI} support, or because I need another feature of a boot manager, I normally use \texttt{grub}.

\begin{NOTE}
    You'll probably only need the \texttt{efibootmgr} package, if you plan to utilize \texttt{UEFI}.
\end{NOTE}

\subsubsection{\texttt{BIOS}}
\label{sec:bios}

If you chose the \texttt{BIOS - MBR} variation, you’ll have to \emph{do nothing special}

If you chose the \texttt{BIOS - GPT} variation, you’ll have to \emph{have a \texttt{+1M} boot partition} created with the partition type set to \texttt{BIOS boot}.

In both cases you’ll have to \emph{run the following comman} now

\begin{minted}{console}
[root@archiso /]# grub-install --target=i386-pc /dev/sdb
\end{minted}

\begin{NOTE}
    It should obvious that you would need to replace \mintinline{text}{/dev/sdb} with the disk you actually want to use.
    Note however that you have to specify a \emph{disk} and \emph{not a partition}, so \emph{no number}.
\end{NOTE}

\subsubsection{\texttt{UEFI}}
\label{sec:uefi}

If you chose the \texttt{UEFI - GPT} variation, you’ll have to \emph{have the EFI System partition mounted} at \mintinline{text}{/boot} (where \mintinline{text}{/dev/sda2} is the partition holding said EFI System partition in my particular setup)

Now \emph{install \texttt{grub} to the EFI System partition}

\begin{minted}{console}
[root@archiso /]# grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=grub --recheck
\end{minted}

\begin{IMPORTANT}
    If you’ve planned on dual booting arch with Windows and therefore reused the EFI System partition created by Windows, you might not be able to boot to grub just yet.

    In this case, boot into Windows, open a \texttt{cmd} window as Administrator and type in

    \begin{minted}{text}
bcdedit /set {bootmgr} path \EFI\grub\grubx64.efi
    \end{minted}

    To make sure that the path is correct, you can use

    \begin{minted}{console}
[root@archiso /]# ls /boot/EFI/grub
    \end{minted}

    \noindent
    under Linux to make sure, that the \mintinline{text}{grubx64.efi} file is really there.
\end{IMPORTANT}

\subsubsection{\texttt{grub} config}
\label{sec:grub-config}

In all cases, you now have to create the main \mintinline{text}{grub.cfg} configuration file.

But before we actually generate it, we’ll make some changes to the default \texttt{grub} settings, which the \mintinline{text}{grub.cfg} will be generated from.

\paragraph{Adjust the timeout}
\label{par:adjust-the-timeout}

First of all, I want my \texttt{grub} menu to wait indefinitely for my command to boot an OS.

\begin{mintedlisting}
    \begin{minted}{text}
GRUB_TIMEOUT=-1
    \end{minted}

    \caption{\mintinline{text}{/boot/grub/grub.cfg}}
\end{mintedlisting}

\begin{NOTE}
    I decided on this, because I’m dual booting with Windows and after Windows updates itself, I don’t want to accidentally boot into my Arch Linux, just because I wasn’t quick enough to select the Windows Boot Loader from the \texttt{grub} menu.

    Of course you can set this parameter to whatever you want.

    Another way of achieving what I described, would be to make \texttt{grub} remember the last selection.

    \begin{mintedlisting}
        \begin{minted}{text}
GRUB_TIMEOUT=5
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT="true"
        \end{minted}

        \caption{\mintinline{text}{/etc/default/grub}}
    \end{mintedlisting}
\end{NOTE}

\paragraph{Enable the recovery}
\label{par:enable-the-recovery}

After that I also want the recovery option showing up, which means that besides the standard and fallback images, also the recovery one would show up.

\begin{mintedlisting}
    \begin{minted}{text}
GRUB_DISABLE_RECOVERY=false
    \end{minted}

    \caption{\mintinline{text}{/etc/default/grub}}
\end{mintedlisting}

\paragraph{NVIDIA fix}
\label{par:nvidia-fix}

Now, as I’m using the binary NVIDIA driver for my graphics card, I also want to make sure, to revert \texttt{grub} back to text mode, after I select a boot entry, in order for the NVIDIA driver to work properly.
You might not need this

\begin{mintedlisting}
    \begin{minted}{text}
GRUB_GFXPAYLOAD_LINUX=text
    \end{minted}

    \caption{\mintinline{text}{/etc/default/grub}}
\end{mintedlisting}

\paragraph{Add power options}
\label{par:add-power-options}

I also want to add two new menu entries, to enable me to shut down the PC, or reboot it, right from the \texttt{grub} menu.

\begin{mintedlisting}
    \begin{minted}{text}
menuentry '=> Shutdown' {
    halt
}

menuentry '=> Reboot' {
    reboot
}
    \end{minted}

    \caption{\mintinline{text}{/etc/default/grub}}
\end{mintedlisting}

\paragraph{Installing \texttt{memtest}}
\label{par:installing-memtest}

As I want all possible options to possibly troubleshoot my PC right there in my \texttt{grub} menu,  without the need to boot into a live OS, I also want to have a memory tester there.

\subparagraph{\texttt{BIOS}}
\label{par:installing-memtest-bios}

\begin{packagetable}
    \texttt{extra} & \texttt{memtest86+} \\
\end{packagetable}

For a \texttt{BIOS} setup, you’ll simply need to install the \texttt{memtest86+} package, with no further configuration.

\subparagraph{\texttt{UEFI}}
\label{par:installing-memtest-uefi}

\begin{packagetable}
    \texttt{AUR} & \texttt{memtest86-efi} \\
\end{packagetable}

For a \texttt{UEFI} setup, you’ll first need to install the package and then tell \texttt{memtest86-efi\textsuperscript{\texttt{AUR}}} how to install itself

\begin{minted}{console}
[root@archiso /]# memtest86-efi -i
\end{minted}

Now select option 3, to install it as a \texttt{grub2} menu item.

\paragraph{Enabling hibernation}
\label{par:enabling-hibernation}

We need to add the \texttt{resume} kernel parameter to \mintinline{text}{/etc/default/grub}, containing my \texttt{swap} partition \texttt{UUID}, in my case

\begin{mintedlisting}
    \begin{minted}{text}
GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=097c6f11-f246-40eb-a702-ba83c92654f2"
    \end{minted}

    \caption{\mintinline{text}{/etc/default/grub}}
\end{mintedlisting}

\begin{NOTE}
    If you have to change anything, like the \texttt{swap} partition \texttt{UUID}, inside the \texttt{grub} configuration files, you’ll always have to rerun \mintinline{console}{$ grub-mkconfig} as explained in the paragraph \nameref{par:generating-the-grub-config} of the section \nameref{sec:grub-config}.
\end{NOTE}

\paragraph{Generating the \texttt{grub} config}
\label{par:generating-the-grub-config}

Now we can finally generate our \mintinline{text}{grub.cfg}

\begin{minted}{console}
[root@archiso /]# grub-mkconfig -o /boot/grub/grub.cfg
\end{minted}

Now you’re good to boot into your new system.

\section{Switch to a \texttt{systemd} based \texttt{ramdisk}}
\label{sec:switch-to-a-systemd-based-ramdisk}

\begin{NOTE}
    There is nothing particularily better about using a \texttt{systemd} based \texttt{ramdisk} instead of a \texttt{busybox} one, it’s just that I prefer it.

    Some advantages, at least in my opinion, that the \texttt{systemd} based \texttt{ramidsk} has, are the included \texttt{resume} hook, as well as password caching, when decrypting encrypted volumes, which means that because I use the same \texttt{LUKS} password for both my data storage \texttt{HDD}, as well as my \texttt{cryptroot}, I only have to input the password once for my \texttt{cryptroot} and my data storage \texttt{HDD} will get decrypted too, without the need to create \mintinline{text}{/etc/crypttab} entries, etc.
\end{NOTE}

To switch to a \texttt{systemd} based \texttt{ramdisk}, you will normally need to substitute the \texttt{busybox} specific hooks for \texttt{systemd} ones.
You will also need to use \texttt{systemd} hooks from now on, for example \texttt{sd-encrypt} instead of \texttt{encrypt}.

\begin{itemize}
    \item \texttt{base}

        In my case, I left the \texttt{base} hook untouched, to get a \texttt{busybox} recovery shell, if something goes wrong, although you wouldn’t technically need it, when using \texttt{systemd}.

        \begin{WARNING}
            Don’t remove this, when using \texttt{busybox}, unless you’re absolutely knowing what you’re doing.
        \end{WARNING}

    \item \texttt{udev}

        Replace this with \texttt{systemd} to switch from \texttt{busybox} to \texttt{systemd}.

    \item \texttt{keymap} and/or \texttt{consolefont}

        These two, or one, if you didn’t use one of them, need to be replaced with \texttt{sd-vconsole}.
        Everything else stays the same with these.

    \item \texttt{encrypt}

        Isn’t used in the default \mintinline{text}{/etc/mkinitcpio.conf}, but could be important later on, for example when using \nameref{sec:full-system-encryption}.
        You need to substitute this with \texttt{sd-encrypt}.

    \item \texttt{lvm2}

        Same thing as with \texttt{encrypt} and needs to be substituted with \texttt{sd-lvm2}.
\end{itemize}

\begin{NOTE}
    You can find all purposes of the individual hooks, as well as the \texttt{busybox} / \texttt{systemd} equivalent of each one in the \hreffn{https://wiki.archlinux.org/index.php/Mkinitcpio\#Common\_hooks}{ArchWiki}.
\end{NOTE}

\section{Hibernation}
\label{sec:hibernation}

In order to use the hibernation feature, you should make sure that your \texttt{swap} partition/file is at least the size of your RAM.

\begin{NOTE}
    If you use a \texttt{busybox} based \texttt{ramdisk}, you need to

    \begin{enumerate}
        \item add the \texttt{resume} hook to \mintinline{text}{/etc/mkinitcpio.conf}, before \texttt{fsck} and definetely after \texttt{block}

            \begin{mintedlisting}
                \begin{minted}{text}
HOOKS=(base udev autodetect modconf block filesystems keyboard resume fsck)
                \end{minted}

                \caption{\mintinline{text}{/etc/mkinitcpio.conf}}
            \end{mintedlisting}
        \item run

            \begin{minted}{console}
[root@archiso /]# mkinitcpio -p linux
            \end{minted}
    \end{enumerate}
\end{NOTE}

\begin{NOTE}
    When using \texttt{EFISTUB} without \texttt{sbupdate}, your motherboard has to support kernel parameters for boot entries.
    If your motherboard doesn’t support this, you would need to use \hreffn{https://wiki.archlinux.org/index.php/Systemd-boot}{\texttt{systemd-boot}}.
\end{NOTE}

\section{Secure Boot}
\label{sec:secure-boot}

\subsection{\texttt{shim}}
\label{sec:shim}

\begin{packagetable}
    \texttt{AUR} & \texttt{shim-signed} \\
\end{packagetable}

\begin{WARNING}
    This is a way of handling secure boot that aims at just making everything work!

    It is not the way Secure Boot was intended to be used and you might as well disable it.

    If you need Secure Boot to be enabled, e.g. for Windows, but you couldn’t care less for the security it could bring to your device, use this method.

    If you want to actually make use of the Secure Boot feature, read \nameref{sec:the-manual-way}.
\end{WARNING}

I know I told you that you’re now good to boot into your new system.
That is only correct, if you’re \emph{not} using Secure Boot.

You can either proceed by disabling Secure Boot in your firmware settings, or by using \texttt{shim} as kind of a pre-bootloader, as well as signing your bootloader (\texttt{grub}) and your kernel.

If you decided on using Secure Boot, you will first have to install the package.

Now we just need to copy \mintinline{text}{shimx64.efi}, as well as \mintinline{text}{mmx64.efi} to our EFI System partition

\begin{minted}{console}
[root@archiso /]# cp /usr/share/shim-signed/shimx64.efi /boot/EFI/grub/
[root@archiso /]# cp /usr/share/shim-signed/mmx64.efi /boot/EFI/grub/
\end{minted}

\begin{NOTE}
    If you have to use \texttt{bcdedit} from within Windows, as explained in section \nameref{sec:uefi}, you need to adapt the command accordingly

    \begin{minted}{text}
bcdedit /set {bootmgr} path \EFI\grub\shimx64.efi
    \end{minted}
\end{NOTE}

Now you will be greeted by \texttt{MokManager} everytime you update your bootloader or kernel.

Just choose "Enroll hash from disk" and enroll your bootloader binary (\mintinline{text}{grubx64.efi}) and kernel (\mintinline{text}{vmlinuz-linux}).

Reboot and your system should fire up just fine.

\subsection{The manual way}
\label{sec:the-manual-way}

\begin{WARNING}
    As this is a very tedious and time consuming process, it only makes sense when also utilizing some sort of disk encryption, which is, why I would advise you to read \nameref{sec:full-system-encryption} first.
\end{WARNING}

\subsubsection{File formats}
\label{sec:file-formats}

In the following subsections, we will be dealing with some different file formats.

\begin{sidebar}{\mintinline{text}{.key}}
    \texttt{PEM} format private keys for \texttt{EFI} binary and \texttt{EFI} signature list signing.
\end{sidebar}

\begin{sidebar}{\mintinline{text}{.crt}}
    \texttt{PEM} format certificates for \texttt{sbsign}.
\end{sidebar}

\begin{sidebar}{\mintinline{text}{.cer}}
    \texttt{DER} format certigficates for firmware.
\end{sidebar}

\begin{sidebar}{\mintinline{text}{.esl}}
    Certificates in \texttt{EFI} Signature List for \texttt{KeyTool} and/or firmware.
\end{sidebar}

\begin{sidebar}{\mintinline{text}{.auth}}
    Certificates in \texttt{EFI} Signature List with authentication header (i.e. a signed certificate update file) for \texttt{KeyTool} and/or firmware.
\end{sidebar}

\subsubsection{Create the keys}
\label{sec:create-the-keys}

First off, we have to generate our Secure Boot keys.

These will be used to sign any binary which will be executed by the firwmare.

\paragraph{\texttt{GUID}}
\label{par:guid}

Let’s create a \texttt{GUID} first to use with the next commands.

\begin{minted}{console}
[root@archiso ~/sb]# uuidgen --random > GUID.txt
\end{minted}

\paragraph{\texttt{PK}}
\label{par:pk}

We can now generate our \texttt{PK} (Platform Key)

\begin{minted}{console}
[root@archiso ~/sb]# openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -subj "/CN=Platform Key for DustArch/" -out PK.crt
[root@archiso ~/sb]# openssl x509 -outform DER -in PK.crt -out PK.cer
[root@archiso ~/sb]# cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl
[root@archiso ~/sb]# sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth
\end{minted}

In order to allow deletion of the \texttt{PK}, for firmwares which do not provide this functionality out of the box, we have to sign an empty file.

\begin{minted}{console}
[root@archiso ~/sb]# sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK /dev/null rm_PK.auth
\end{minted}

\paragraph{\texttt{KEK}}
\label{par:kek}

We proced in a similar fashion with the \texttt{KEK} (Key Exchange Key)

\begin{minted}{console}
[root@archiso ~/sb]# openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -subj "/CN=Key Exchange Key for DustArch/" -out KEK.crt
[root@archiso ~/sb]# openssl x509 -outform DER -in KEK.crt -out KEK.cer
[root@archiso ~/sb]# cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl
[root@archiso ~/sb]# sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth
\end{minted}

\paragraph{\texttt{DB}}
\label{par:db}

And finally the \texttt{DB} (Signature Database) key.

\begin{minted}{console}
[root@archiso ~/sb]# openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -subj "/CN=Signature Database key for DustArch" -out db.crt
[root@archiso ~/sb]# openssl x509 -outform DER -in db.crt -out db.cer
[root@archiso ~/sb]# cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl
[root@archiso ~/sb]# sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth
\end{minted}

\subsubsection{Windows stuff}
\label{sec:windows-stuff}

As your plan is to be able to control, which things do boot on your system and which don’t, you’re going through all this hassle to create and enroll custom keys, so only \texttt{EFI} binaries signed with said keys can be executed.

But what if you have a Windows dual boot setup?

Well the procedure is actually pretty straight forward.
You just grab Microsoft’s certificates, convert them into a usable format, sign them and enroll them.
No need to sign the Windows boot loader.

\begin{minted}{console}
[root@archiso ~/sb]# curl -fLo WinCert.crt https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt
[root@archiso ~/sb]# openssl x509 -inform DER -outform PEM -in MicWinCert.crt -out MicWinCert.pem
[root@archiso ~/sb]# cert-to-efi-sig-list -g 77fa9abd-0359-4d32-bd60-28f4e78f784b MicWinCert.pem MS_db.esl
[root@archiso ~/sb]# sign-efi-sig-list -a -g 77fa9abd-0359-4d32-bd60-28f4e78f784b -k KEK.key -c KEK.crt db MS_db.esl add_MS_db.auth
\end{minted}

\subsubsection{Move the kernel \& keys}
\label{sec:move-the-kernel-and-keys}

In order to ensure a smooth operation, with actual security, we need to move some stuff around.

\paragraph{Kernel, \texttt{initramfs}, microcode}
\label{par:kernel-initramfs-microcode}

\texttt{pacman} will put its unsigned and unencrypted kernel, \texttt{initramfs} and microcode images into \mintinline{text}{/boot}, which is, why it will be no longer a good idea, to leave your EFI System partition mounted there.
Instead we will create a new mountpoint under \mintinline{text}{/efi} and modify our \texttt{fstab} accordingly.

\paragraph{Keys}
\label{par:keys}

As you probably want to automate signing sooner or later and only use the ultimately necessary keys for this process, as well as store the other more important keys somewhere more safe and secure than your \texttt{root} home directory, we will move the necessary keys.

I personally like to create a \mintinline{text}{/etc/efi-keys} directory, \texttt{chmod}ded to \texttt{700} and place my \mintinline{text}{db.crt} and \mintinline{text}{db.key} there.
All the keys will get packed into a \texttt{tar} archive and encrypted with a strong symmetric pass phrase and stored somewhere secure and safe.

\subsubsection{Signing}
\label{sec:signing}

Signing is the process of, well, signing your \texttt{EFI} binaries, in order for them to be allowed to be executed, by the motherboard firmware.
At the end of the day, that’s why you’re doing all this, to prevent an attack by launching unknown code.

\paragraph{Manual signing}
\label{par:manual-signing}

Of course, you can sign images yourself manually.
In my case, I used this, to sign the boot loader, kernel and \texttt{initramfs} of my USB installation of Arch Linux.

\begin{NOTE}
    As always, manual signing also comes with its caveats!

    If I update my kernel, boot loader, or create an updated \texttt{initramfs} on my Arch Linux USB installation, I have to sign those files again, in order to be able to boot it on my PC.

    Of course you can always script and automate stuff, but if you want something more easy for day to day use, I really recommend that you try out \texttt{sbupdate},  which I will explain in the next paragraph \nameref{par:sbupdate}.
\end{NOTE}

For example, if I want to sign the kernel image of my USB installation, where I mounted the boot partition to \mintinline{text}{/mnt/dustarchusb/boot}, I would have to do the following

\begin{minted}{console}
[root@archiso ~/sb]# sbsign --key /etc/efi-keys/db.key --cert /etc/efi-keys/db.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
\end{minted}

\paragraph{\texttt{sbupdate}}
\label{par:sbupdate}

\begin{packagetable}
    \texttt{AUR} & \texttt{sbupdate-git} \\
\end{packagetable}

Of course, if you’re using Secure Boot productively, you would want something more practical than manual signing, especially since you need to sign

\begin{itemize}
    \item the boot loader

    \item the kernel image

    \item the \texttt{initramfs}
\end{itemize}

Fortunately there is an easy and uncomplicated tool out there, that does all that for you, called \texttt{sbupdate}.

It not only signs everything and also foreign \texttt{EFI} binaries, if specified, but also combines your kernel and \texttt{initramfs} into a single executable \texttt{EFI} binary, so you don’t even need a boot loader, if your motherboard implementation supports booting those.

After installing \texttt{sbupdate}, we can edit the \mintinline{text}{/etc/sbupdate.conf} file, to set everything up.

Everything in this config should be self-explanatory.

You will probably need to

\begin{itemize}
    \item set \mintinline{text}{ESP_DIR} to \mintinline{text}{/efi}

    \item add any other \texttt{EFI} binary you want to have signed to \mintinline{text}{EXTRA_SIGN}

    \item add your kernel parameters, for example

        \begin{itemize}
            \item \mintinline{text}{rd.luks.name}
            \item \mintinline{text}{root}
            \item \mintinline{text}{rw}
            \item \mintinline{text}{resume}
            \item etc.
        \end{itemize}

        \noindent
        to \mintinline{text}{CMDLINE_DEFAULT}
\end{itemize}

After you’ve successfully configured \texttt{sbupdate}, you can run it as root, to create all the signed files.

\begin{NOTE}
    \texttt{sbupdate} will be executed upon kernel updates by \texttt{pacman}, but not if you change your \texttt{initramfs} with something like \texttt{mkinitcpio}.
    In that case you will have to run \texttt{sbupdate} manually.
\end{NOTE}

\subsubsection{Add \texttt{EFI} entries}
\label{sec:add-efi-entries}

\begin{packagetable}
    \texttt{core} & \texttt{efibootmgr} \\
\end{packagetable}

Now the only thing left to do, if you want to stay boot loader free anyways, is to add the signed images to the boot list of your \texttt{NVRAM}.
You can do this with \texttt{efibootmgr}.

\begin{minted}{console}
[root@archiso ~/sb]# efibootmgr -c -d /dev/nvme0n1 -p 1 -L "Arch Linux fallback" -l "EFI\Arch\linux-fallback-signed.efi
[root@archiso ~/sb]# efibootmgr -c -d /dev/nvme0n1 -p 1 -L "Arch Linux" -l "EFI\Arch\linux-signed.efi
\end{minted}

Of course you can extend this list, with whichever entries you need.

\subsubsection{Enrolling everything}
\label{sec:enrolling-everything}

First off, copy all \mintinline{text}{.cer}, \mintinline{text}{.esl} and \mintinline{text}{.auth} files to a \texttt{FAT} formatted filesystem.
I’m using my EFI System partition for this.

After that reboot into the firmware setup of your motherboard, clear the existing Platform Key, to set the firmware into "Setup Mode" and enroll the \texttt{db}, \texttt{KEK} and \texttt{PK} certificates in sequence.

\begin{NOTE}
    Enroll the Platform Key last, as it sets most firmware’s Secure Boot sections back into "User mode", exiting "Setup Mode".
\end{NOTE}

\chapter{Inside the \texttt{DustArch}}
\label{sec:inside-the-dustarch}

This section helps at setting up the customized system from within an installed system.

This section mainly provides aid with the basic set up tasks, like networking, dotfiles, etc.

\begin{NOTE}
    Not everything in this section is mandatory.

    This section is rather a guideline, because it is easy to forget some steps needed, for example \texttt{jack} for audio production, that only become apparent, when they’re needed.

    It is furthermore the responsibility of the reader to decide which steps to skip and which need further research.
    As I mentioned, this is only a guide and not the answer to everything.
\end{NOTE}

\section{Someone there?}
\label{sec:someone-there}

First we have to check if the network interfaces are set up properly.

To view the network interfaces with all their properties, we can issue

\begin{minted}{text}
DustArch% ip link
\end{minted}

To make sure that you have a working \emph{Internet} connection, issue

\begin{minted}{text}
DustArch% ping archlinux.org
\end{minted}

Everything should run smoothly if you have a wired connection.

If there is no connection and you’re indeed using a wired connection, try restarting the \texttt{NetworkManager} service

\begin{minted}{text}
DustArch% sudo systemctl restart NetworkManager.service
\end{minted}

\noindent
and then try \mintinline{console}{$ ping}ing again.

If you're trying to utilize a Wi-Fi connection, use \texttt{nmcli}, the NetworkManager's command line tool, or \texttt{nmtui}, the NetworkManager terminal user interface, to connect to a Wi-Fi network.

\begin{NOTE}
    I never got \texttt{nmtui} to behave like I wanted it to, in my particular case at least, which is the reason why I use \texttt{nmcli} or the GUI tools.
\end{NOTE}

First make sure, the scanning of nearby Wi-Fi networks is enabled for your Wi-Fi device

\begin{minted}{text}
DustArch% nmcli radio
\end{minted}

\noindent
and if not, enable it

\begin{minted}{text}
DustArch% nmcli radio wifi on
\end{minted}

Now make sure your Wi-Fi interface appears under

\begin{minted}{text}
DustArch% nmcli device
\end{minted}

Rescan for available networks

\begin{minted}{text}
DustArch% nmcli device wifi rescan
\end{minted}

\noindent
and list all found networks

\begin{minted}{text}
DustArch% nmcli device wifi list
\end{minted}

After that connect to the network

\begin{minted}{text}
DustArch% nmcli device wifi connect --ask
\end{minted}

Now try \mintinline{console}{$ ping}ing again.

\section{Update and upgrade}
\label{sec:update-and-upgrade}

After making sure that you have a working Internet connection, you can then proceed to update and upgrade all installed packages by issuing

\begin{minted}{text}
DustArch% sudo pacman -Syu
\end{minted}

\section{Enabling the \texttt{multilib} repository}
\label{sec:enabling-the-multilib-repository}

In order to make 32-bit packages available to \texttt{pacman}, we’ll need to enable the \texttt{multilib} repository in \mintinline{text}{/etc/pacman.conf} first.
Simply uncomment

\begin{mintedlisting}
    \begin{minted}{text}
[multilib]
Include = /etc/pacman.d/mirrorlist
    \end{minted}

    \caption{\mintinline{text}{/etc/pacman.conf}}
\end{mintedlisting}

\noindent
and update \texttt{pacman}'s package repositories afterwards

\begin{minted}{text}
DustArch% sudo pacman -Syu
\end{minted}

\section{\texttt{zsh} for president}
\label{sec:zsh-for-president}

Of course you can use any shell you want.
In my case I’ll be using the \texttt{zsh} shell.

\begin{NOTE}
    I am using \texttt{zsh} because of its auto completion functionality and extensibility, as well as a brilliant \texttt{vim} like navigation implementation through a plugin, though that might not be what you’re looking for.
\end{NOTE}

We already set the correct shell for the \texttt{dustvoice} user in the \nameref{sec:create-a-personal-user} step, but I want to use \texttt{zsh} for the \texttt{root} user too, so I’ll have to change \texttt{root}'s default shell to it.

\begin{minted}{text}
DustArch% sudo chsh -s /usr/bin/zsh root
\end{minted}

Don’t worry about the looks by the way, we’re gonna change all that in just a second.

\section{\texttt{git}}
\label{sec:git}

\begin{packagetable}
    \texttt{extra} & \texttt{git} \\
\end{packagetable}

Install the package and you’re good to go for now, as we’ll care about the \mintinline{text}{.gitconfig} in just a second.

\section{Security is important}
\label{sec:security-is-important}

\begin{packagetable}
    \texttt{core} & \texttt{gnupg} \\
\end{packagetable}

If you’ve followed the tutorial using a recent version of the archiso, you’ll probably already have the most recent version of \texttt{gnupg} installed by default.

\subsection{Smartcard shenanigans}
\label{sec:smartcard-shenanigans}

\begin{packagetable}
    \texttt{extra} & \texttt{libusb-compat} \\
    \texttt{community} & \texttt{ccid opensc pcsclite} \\
\end{packagetable}

After that you’ll still have to setup \texttt{gnupg} correctly.
In my case I have my private keys stored on a smartcard.

To use it, I’ll have to install the listed packages and then enable and start the \mintinline{text}{pcscd.service} service

\begin{minted}{text}
DustArch% sudo systemctl enable pcscd.service
DustArch% sudo systemctl start pcscd.service
\end{minted}

After that, you should be able to see your smartcard being detected

\begin{minted}{text}
DustArch% gpg --card-status
\end{minted}

\begin{NOTE}
    If your smartcard still isn’t detected, try logging off completely or even restarting, as that sometimes is the solution to the problem.

\end{NOTE}

\section{Additional required tools}
\label{sec:additional-required-tools}

\begin{packagetable}
    \texttt{core} & \texttt{make openssh} \\
    \texttt{extra} & \texttt{clang cmake jdk-openjdk python} \\
    \texttt{community} & \texttt{pass python-pynvim} \\
\end{packagetable}

To minimize the effort required by the following steps, we’ll install most of the required packages beforehand

This will ensure, we proceed through the following section without the need for interruption, because a package needs to be installed, so the following content can be condensed to the relevant informations.

\section{Setting up a \texttt{home} environment}
\label{sec:setting-up-a-home-environment}

In this step we’re going to setup a home environment for both the \texttt{root} and my personal \texttt{dustvoice} user.

\begin{NOTE}
    In my case these 2 home environments are mostly equivalent, which is why I’ll execute the following commands as the \texttt{dustvoice} user first and then switch to the \texttt{root} user and repeat the same commands.

    I decided on this, as I want to edit files with elevated permissions and still have the same editor style and functions/plugins.

    Note that this comes with some drawbacks.
    For example, if I change a configuration for my \texttt{dustvoice} user, I would have to regularly update it for the \texttt{root} user too.
    This bears the problem, that I have to register my smartcard for the root user.
    This in turn is problematic, cause the \texttt{gpg-agent} used for \texttt{ssh} authentication, doesn’t behave well when used within a \mintinline{console}{$ su} or \mintinline{console}{$ sudo -i} session.
    So in order to update \texttt{root}'s config files I would either need to symlink everything, which I won’t do, or I’ll need to login as the \texttt{root} user now and then, to update everything.
\end{NOTE}

\begin{NOTE}
    In my case, I want to access all my \texttt{git} repositories with my \texttt{gpg} key on my smartcard.
    For that I have to configure the \texttt{gpg-agent} with some configuration files that reside in a \texttt{git} repository.
    This means I will have to reside to using the \texttt{https} URL of the repository first and later changing the URL either in the corresponding \mintinline{text}{.git/config} file, or by issuing the appropriate command.
\end{NOTE}

\subsection{Use \texttt{dotfiles} for a base config}
\label{sec:use-dotfiles-for-a-base-config}

To provide myself with a base configuration, which I can then extend, I have created a \texttt{dotfiles} repository, which contains all kinds of configurations.

The special thing about this \texttt{dotfiles} repository is that it \emph{is} my home folder.
By using a curated \mintinline{text}{.gitignore} file, I’m able to only include the configuration files I want to keep between installs into the repository and ignore everything else.

To achieve this very specific setup, I have to turn my home directory into said \texttt{dotfiles} repository first

\begin{minted}{text}
DustArch% git init
DustArch% git remote add origin https://git.dustvoice.de/DustVoice/dotfiles.git
DustArch% git fetch
DustArch% git reset origin/master --hard
DustArch% git branch --set-upstream-to=origin/master master
\end{minted}

Now I can issue any \texttt{git} command in my \mintinline{text}{~} directory, because it now is a \texttt{git} repository.

\subsection{Set up \texttt{gpg}}
\label{sec:set-up-gpg}

As I wanted to keep my \texttt{dotfiles} repository as modular as possible, I utilize \texttt{git}'s \texttt{submodule} feature.
Furthermore I want to use my \texttt{nvim} repository, which contains all my configurations and plugins for \texttt{neovim}, on Windows, but without all the Linux specific configuration files.
I am also using the \texttt{Pass} repository on my Android phone and Windows PC, where I only need this repository without the other Linux configuration files.

Before we’ll be able to update the \texttt{submodule}s (\texttt{nvim} config files and \texttt{pass}word-store) though, we will have to setup our \texttt{gpg} key as an \texttt{ssh} key, as I use it to authenticate

\begin{minted}{console}
dustvoice@DustArch ~
$ chmod 700 .gnupg
dustvoice@DustArch ~
$ gpg --card-status
dustvoice@DustArch ~
$ gpg --card-edit
\end{minted}

\begin{minted}{console}
(insert) gpg/card> fetch
(insert) gpg/card> q
\end{minted}

\begin{minted}{console}
dustvoice@DustArch ~
$ gpg-connect-agent updatestartuptty /bye
\end{minted}

\begin{NOTE}
    You would have to adapt the \texttt{keygrip} present in the \mintinline{text}{~/.gnupg/sshcontrol} file to your specific \texttt{keygrip}, retrieved with \mintinline{console}{$ gpg -K --with-keygrip}.
\end{NOTE}

Now, as mentioned before, I’ll switch to using \texttt{ssh} for authentication, rather than \texttt{https}

\begin{minted}{console}
dustvoice@DustArch ~
$ git remote set-url origin git@git.dustvoice.de:DustVoice/dotfiles.git
\end{minted}

As the best method to both make \texttt{zsh} recognize all the configuration changes, as well as the \texttt{gpg-agent} behave properly, is to re-login, we’ll do just that

\begin{minted}{console}
dustvoice@DustArch ~
$ exit
\end{minted}

\begin{WARNING}
    It is very important to note, that I mean \emph{a real re-login}.

    That means that if you’ve used \texttt{ssh} to log into your machine, it probably won’t be sufficient to login into a new \texttt{ssh} session.
    You’ll probably need to restart the machine completely.
\end{WARNING}

\subsection{Finalize the \texttt{dotfiles}}
\label{sec:finalize-the-dotfiles}

Now log back in and continue

\begin{minted}{console}
dustvoice@DustArch ~
$ git submodule update --recursive --init
dustvoice@DustArch ~
$ source .zshrc
dustvoice@DustArch ~
$ cd .config/nvim
dustvoice@DustArch ~/.config/nvim
$ echo 'let g:platform = "linux"' >> platform.vim
dustvoice@DustArch ~/.config/nvim
$ echo 'let g:use_autocomplete = 3' >> custom.vim
dustvoice@DustArch ~/.config/nvim
$ echo 'let g:use_clang_format = 1' >> custom.vim
dustvoice@DustArch ~/.config/nvim
$ echo 'let g:use_font = 0' >> custom.vim
dustvoice@DustArch ~/.config/nvim
$ nvim --headless +PlugInstall +qa
dustvoice@DustArch ~/.config/nvim
$ cd plugged/YouCompleteMe
dustvoice@DustArch ~/.config/nvim/plugged/YouCompleteMe
$ python3 install.py --clang-completer --java-completer
dustvoice@DustArch ~/.config/nvim/plugged/YouCompleteMe
$ cd ~
\end{minted}

\subsection{\texttt{gpg-agent} forwarding}
\label{sec:gpg-agent-forwarding}

Now there is only one thing left to do, in order to make the \texttt{gpg} setup complete: \texttt{gpg-agent} forwarding over \texttt{ssh}.
This is very important for me, as I want to use my smartcard on my development server too, which requires me, to forward/tunnel my \texttt{gpg-agent} to my remote machine.

First of all, I want to setup a config file for \texttt{ssh}, as I don’t want to pass all parameters manually to ssh every time.

\begin{mintedlisting}
    \begin{minted}{text}
Host <connection name>
    HostName <remote address>
    ForwardAgent yes
    ForwardX11 yes
    RemoteForward <remote agent-socket> <local agent-extra-socket>
    RemoteForward <remote agent-ssh-socket> <local agent-ssh-socket>
    \end{minted}

    \caption{\mintinline{text}{~/.ssh/config}}
\end{mintedlisting}

\begin{NOTE}
    You would of course, need to adapt the content in between the \texttt{<} and \texttt{>} brackets.

    To get the paths needed as parameters for \texttt{RemoteForward}, issue

    \begin{minted}{console}
dustvoice@DustArch ~
$ gpgconf --list-dirs
    \end{minted}
\end{NOTE}

\begin{example}
    An example for a valid \mintinline{text}{~/.ssh/config} would be

    \begin{mintedlisting}
        \begin{minted}{text}
Host archserver
    HostName pc.dustvoice.de
    ForwardAgent yes
    ForwardX11 yes
    RemoteForward /run/user/1000/gnupg/S.gpg-agent /run/user/1000/gnupg/S.gpg-agent.extra
    RemoteForward /run/user/1000/gnupg/S.gpg-agent.ssh /run/user/1000/gnupg/S.gpg-agent.ssh
        \end{minted}

        \caption{\mintinline{text}{~/.ssh/config}}
    \end{mintedlisting}
\end{example}

Now you’ll still need to enable some settings on the remote machine(s).

\begin{mintedlisting}
    \begin{minted}{text}
StreamLocalBindUnlink yes
AllowAgentForwarding yes
X11Forwarding yes
    \end{minted}

    \caption{\mintinline{text}{/etc/ssh/sshd\_config}}
\end{mintedlisting}

Now just restart your remote machine(s) and you’re ready to go.

\begin{NOTE}
    If you use \texttt{alacritty}, to connect to your remote machine over \texttt{ssh}, you will need to install the \texttt{alacritty} on the remote machine too, as \texttt{alacritty} uses its own \texttt{\$TERM}.

    Another option would be changing that variable for the \texttt{ssh} command

    \begin{minted}{console}
dustvoice@DustArch ~
$ TERM=xterm-256colors ssh remote-machine
    \end{minted}
\end{NOTE}

\subsection{Back to your \texttt{root}s}
\label{sec:back-to-your-roots}

As mentioned before, you would now switch to the \texttt{root} user, either by logging in as \texttt{root}, or by using

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo -iu root
\end{minted}

Now go back to \nameref{sec:setting-up-a-home-environment} to repeat all commands for the \texttt{root} user.

\begin{WARNING}
    A native login would be better compared to \mintinline{console}{$ sudo -iu root}, as there could be some complications, like already running \texttt{gpg-agent} instances, etc., which you would need to manually resolve, when using \mintinline{console}{$ sudo -iu root}.
\end{WARNING}

\section{Audio}
\label{sec:audio}

Well, why wouldn’t you want audio...

\subsection{\texttt{alsa}}
\label{sec:alsa}

\begin{packagetable}
    \texttt{extra} & \texttt{alsa-utils} \\
\end{packagetable}

\begin{NOTE}
    You’re probably better off using \texttt{pulseaudio} and/or \texttt{jack}.
\end{NOTE}

Now choose the sound card you want to use

\begin{minted}{console}
dustvoice@DustArch ~
$ cat /proc/asound/cards
\end{minted}

\noindent
and then create \mintinline{text}{/etc/asound.conf}

\begin{mintedlisting}
    \begin{minted}{text}
defaults.pcm.card 2
defaults.ctl.card 2
    \end{minted}

    \caption{\mintinline{text}{/etc/asound.conf}}
\end{mintedlisting}

\begin{NOTE}
    It should be apparent, that you would have to switch out \texttt{2} with the number corresponding to the sound card you want to use.
\end{NOTE}

\subsection{\texttt{pulseaudio}}
\label{sec:pulseaudio}

\begin{packagetable}
    \texttt{extra} & \texttt{pavucontrol pulseaudio} \\
    \texttt{community} & \texttt{pulsemixer} \\
\end{packagetable}

Some applications require \texttt{pulseaudio}, or work better with it, for example \texttt{discord}, so it might make sense to use \texttt{pulseaudio}

For enabling real-time priority for \texttt{pulseaudio} on Arch Linux, please make sure your user is part of the \texttt{audio} group and edit the file \mintinline{text}{/etc/pulse/daemon.conf}, so that you uncomment the lines

% TODO: Check what values I currently use!
\begin{mintedlisting}
    \begin{minted}{text}
high-priority = yes
nice-level = -11

realtime-scheduling = yes
realtime-priority = 5
    \end{minted}

    \caption{\mintinline{text}{/etc/pulse/daemon.conf}}
\end{mintedlisting}

If your system can handle the load, you can also increase the remixing quality, by changing the \mintinline{text}{resample-method}

\begin{mintedlisting}
    \begin{minted}{text}
resample-method = speex-float-10
    \end{minted}

    \caption{\mintinline{text}{/etc/pulse/daemon.conf}}
\end{mintedlisting}

Of course a restart of the \texttt{pulseaudio} daemon is necessary to reflect the changes you just made

\begin{minted}{console}
dustvoice@DustArch ~
$ pulseaudio --kill
dustvoice@DustArch ~
$ pulseaudio --start
\end{minted}

\subsection{\texttt{jack}}
\label{sec:jack}

\begin{packagetable}
    \texttt{extra} & \texttt{pulseaudio-jack} \\
    \texttt{community} & \texttt{cadence jack2} \\
\end{packagetable}

If you either want to manually control audio routing, or if you use some kind of audio application like \texttt{ardour}, you’ll probably want to use \texttt{jack} and \texttt{cadence} as a GUI to control it, as it has native support for bridging \texttt{pulseaudio} to \texttt{jack}.

\subsection{Audio handling}
\label{sec:audio-handling}

\begin{packagetable}
    \texttt{extra} & \texttt{libao libid3tag libmad libpulse opus wavpack} \\
    \texttt{community} & \texttt{sox twolame} \\
\end{packagetable}

To also play audio, we need to install the mentioned packages and then simply do

\begin{minted}{console}
dustvoice@DustArch ~
$ play audio.wav
dustvoice@DustArch ~
$ play audio.mp3
\end{minted}

\noindent
to play audio.

\section{Bluetooth}
\label{sec:bluetooth}

\begin{packagetable}
    \texttt{extra} & \texttt{bluez bluez-utils pulseaudio-bluetooth} \\
    \texttt{community} & \texttt{blueman} \\
\end{packagetable}

To set up Bluetooth, we need to install the \texttt{bluez} and \texttt{bluez-utils} packages in order to have at least a command line utility \texttt{bluetoothctl} to configure connections

Now we need to check if the \texttt{btusb} kernel module was already loaded

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo lsmod | grep btusb
\end{minted}

After that we can enable and start the \mintinline{text}{bluetooth.service} service

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo systemctl enable bluetooth.service
dustvoice@DustArch ~
$ sudo systemctl start bluetooth.service
\end{minted}

\begin{NOTE}
    To use \texttt{bluetoothctl} and get access to the Bluetooth device of your PC, your user needs to be a member of the \texttt{lp} group.
\end{NOTE}

Now simply enter \texttt{bluetoothctl}

\begin{minted}{console}
dustvoice@DustArch ~
$ bluetoothctl
\end{minted}

In most cases your Bluetooth interface will be preselected and defaulted, but in some cases, you might need to first select the Bluetooth controller

\begin{minted}{console}
(insert) [DustVoice]# list
(insert) [DustVoice]# select <MAC_address>
\end{minted}

After that, power on the controller

\begin{minted}{console}
(insert) [DustVoice]# power on
\end{minted}

Now enter device discovery mode

\begin{minted}{console}
(insert) [DustVoice]# scan on
\end{minted}

\noindent
and list found devices

\begin{minted}{console}
(insert) [DustVoice]# devices
\end{minted}

\begin{NOTE}
    You can turn device discovery mode off again, after your desired device has been found

    \begin{minted}{console}
(insert) [DustVoice]# scan off
    \end{minted}
\end{NOTE}

Now turn on the agent

\begin{minted}{console}
(insert) [DustVoice]# agent on
\end{minted}

\noindent
and pair with your device

\begin{minted}{console}
(insert) [DustVoice]# pair <MAC_address>
\end{minted}

\begin{NOTE}
    If your device doesn’t support PIN verification you might need to manually trust the device

    \begin{minted}{console}
(insert) [DustVoice]# trust <MAC_address>
    \end{minted}
\end{NOTE}

Finally connect to your device

\begin{minted}{console}
(insert) [DustVoice]# connect <MAC_address>
\end{minted}

\begin{NOTE}
    If your device is an audio device, of some kind you might have to install \texttt{pulseaudio-bluetooth}.

    You will then also need to append 2 lines to \mintinline{text}{/etc/pulse/system.pa}

    \begin{mintedlisting}
        \begin{minted}{text}
load-module module-bluetooth-policy
load-module module-bluetooth-discover
        \end{minted}

        \caption{\mintinline{text}{/etc/pulse/system.pa}}
    \end{mintedlisting}

    \noindent
    and restart \texttt{pulseaudio}

    \begin{minted}{console}
dustvoice@DustArch ~
$ pulseaudo --kill
dustvoice@DustArch ~
$ pulseaudo --start
    \end{minted}
\end{NOTE}

If you want a GUI to do all of this, just install \texttt{blueman} and launch \texttt{blueman-manager}

\section{Graphical desktop environment}
\label{sec:graphical-desktop-environment}

\begin{packagetable}
    \texttt{extra} & \texttt{ttf-hack xclip xorg xorg-drivers xorg-xinit} \\
    \texttt{community} & \texttt{arandr alacritty bspwm dmenu sxhkd} \\
    \texttt{AUR} & \texttt{polybar} \\
\end{packagetable}

If you decide, that you want to use a graphical desktop environment, you have to install additional packages in order for that to work.

\begin{NOTE}
    \texttt{xclip} is useful, when you want to send something to the \texttt{X} clipboard.
    It is also required, in order for \texttt{neovim}'s clipboard to work correctly.
    It is not required though.
\end{NOTE}

\subsection{NVIDIA}
\label{sec:nvidia}

\begin{packagetable}
    \texttt{extra} & \texttt{nvidia nvidia-utils nvidia-settings opencl-nvidia} \\
\end{packagetable}

If you also want to utilize special NVIDIA functionality, for example for \texttt{davinci-resolve}, you’ll most likely need to install their proprietary driver.

To configure the \texttt{X} server correctly, one can use \texttt{nvidia-xconfig}

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo nvidia-xconfig
\end{minted}

If you want to further tweak all settings available, you can use \texttt{nvidia-settings}.

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo nvidia-settings
\end{minted}

\noindent
will enable you to \emph{"Save to X Configuration File"}, witch merges your changes with \mintinline{text}{/etc/X11/xorg.conf}.

With

\begin{minted}{console}
dustvoice@DustArch ~
$ nvidia-settings
\end{minted}

\noindent
you’ll only be able to save the current configuration to \mintinline{text}{~/.nvidia-settings-rc}, witch you have to source after \texttt{X} startup with

\begin{minted}{console}
dustvoice@DustArch ~
$ nvidia-settings --load-config-only
\end{minted}

\begin{NOTE}
    You will have to reboot sooner or later after installing the NVIDIA drivers, so you might as well do it now, before any complications come up.
\end{NOTE}

\subsection{Launching the graphical environment}
\label{sec:launching-the-graphical-environment}

After that you can now do \texttt{startx} in order to launch the graphical environment.

If anything goes wrong in the process, remember that you can press \mintinline{text}{Ctrl+Alt+<Number>} to switch \texttt{tty}s.

\subsubsection{The NVIDIA way}
\label{sec:the-nvidia-way}

\begin{packagetable}
    \texttt{community} & \texttt{bbswitch} \\
    \texttt{AUR} & \texttt{nvidia-xrun} \\
\end{packagetable}

If you’re using an NVIDIA graphics card, you might want to use \texttt{nvidia-xrun\textsuperscript{\texttt{AUR}}} instead of \texttt{startx}.
This has the advantage, of the \texttt{nvidia} kernel modules, as well as the \texttt{nouveau} ones not loaded at boot time, thus saving power.
\texttt{nvidia-xrun\textsuperscript{\texttt{AUR}}} will then load the correct kernel modules and run the \mintinline{text}{.nvidia-xinitrc} script in your home directory (for more file locations look into the documentation for \texttt{nvidia-xrun\textsuperscript{\texttt{AUR}}}).

\begin{IMPORTANT}
    At the time of writing, \texttt{nvidia-xrun\textsuperscript{\texttt{AUR}}} needs \texttt{sudo} permissions before executing its task.
\end{IMPORTANT}

\begin{NOTE}
    \begin{packagetable}
        \texttt{AUR} & \texttt{nvidia-xrun-pm} \\
    \end{packagetable}

    If your hardware doesn’t support \texttt{bbswitch}, you would need to use \texttt{nvidia-xrun-pm\textsuperscript{\texttt{AUR}}} instead.
\end{NOTE}

Now we need to blacklist \emph{both \texttt{nouveau} and \texttt{nvidia}} kernel modules.

To do that, we first have to find out, where our active \mintinline{text}{modprobe.d} directory is located.
There are 2 possible locations, generally speaking: \mintinline{text}{/etc/modprobe.d} and \mintinline{text}{/usr/lib/modprobe.d}.
In my case it was the latter, which I could tell, because this directory already had files in it.

Now I’ll create a new file named \mintinline{text}{nvidia-xrun.conf} and write the following into it

\begin{mintedlisting}
    \begin{minted}{text}
blacklist nvidia
blacklist nvidia-drm
blacklist nvidia-modeset
blacklist nvidia-uvm
blacklist nouveau
    \end{minted}

    \caption{\mintinline{text}{/usr/lib/modprobe.d/nvidia-xrun.conf}}
\end{mintedlisting}

With this config in place,

\begin{minted}{console}
dustvoice@DustArch ~
$ lsmod | grep nvidia
\end{minted}

\noindent
and

\begin{minted}{console}
dustvoice@DustArch ~
$ lsmod | grep nouveau
\end{minted}

\noindent
should return no output.
Else you might have to place some additional entries into the file.

\begin{NOTE}
    Of course, you’ll need to reboot, after blacklisting the modules and before issuing the 2 commands mentioned.
\end{NOTE}

\begin{NOTE}
    If you installed \texttt{nvidia-xrun-pm} instead of \texttt{nvidia-xrun} and \texttt{bbswitch}, you might want to also enable the \texttt{nvidia-xrun-pm} service

    \begin{minted}{console}
dustvoice@dustArch ~
$ sudo systemctl enable nvidia-xrun-pm.service
    \end{minted}
\end{NOTE}

\begin{NOTE}
    The required \mintinline{text}{.nvidia-xinitrc} file, mentioned previously, should already be provided in the \texttt{dotfiles} repository.
\end{NOTE}

Now instead of \texttt{startx}, just run \texttt{nvidia-xrun}, enter your \texttt{sudo} password and you’re good to go.

\section{Additional \texttt{console} software}
\label{sec:additional-console-software}

Software that is useful in combination with a \texttt{console}.

\subsection{\texttt{tmux}}
\label{sec:tmux}

\begin{packagetable}
    \texttt{community} & \texttt{tmux} \\
\end{packagetable}

I would reccommend to install \texttt{tmux} which enables you to have multiple terminal instances (called \texttt{windows} in \texttt{tmux}) open at the same time.
This makes working with the linux terminal much easier.

\begin{NOTE}
    To view a list of keybinds, you just need to press \mintinline{text}{Ctrl+b} followed by \texttt{?}.
\end{NOTE}

\subsection{Communication}
\label{sec:console-communication}

Life is all about communicating.
Here are some pieces of software to do exactly that.

\subsubsection{\texttt{weechat}}
\label{sec:weechat}

\begin{packagetable}
    \texttt{community} & \texttt{weechat} \\
\end{packagetable}

\texttt{weechat} is an \texttt{IRC} client for the terminal, with the best features and even a \texttt{vim} mode, by using a plugin

To configure everything, open \texttt{weechat}

\begin{minted}{console}
dustvoice@DustArch ~
$ weechat
\end{minted}

\noindent
and install \texttt{vimode}, as well as configure it

\begin{minted}{text}
/script install vimode.py
/vimode bind_keys
/set plugins.var.python.vimode.mode_indicator_normal_color_bg "blue"
\end{minted}

Now add \mintinline{text}{mode_indicator+} in front of and \mintinline{text}{,[vi_buffer]} to the end of \mintinline{text}{weechat.bar.input.items}, in my case

\begin{minted}{text}
/set weechat.bar.input.items "mode_indicator+[input_prompt]+(away),[input_search],[input_paste],input_text,[vi_buffer]"
\end{minted}

Now add \mintinline{text}{,cmd_completion} to the end of \mintinline{text}{weechat.bar.status.items}, in my case

\begin{minted}{text}
/set weechat.bar.status.items "[time],[buffer_last_number],[buffer_plugin],buffer_number+:+buffer_name+(buffer_modes)+{buffer_nicklist_count}+buffer_zoom+buffer_filter,scroll,[lag],[hotlist],completion,cmd_completion"
\end{minted}

Now enable \texttt{vimode} searching

\begin{minted}{text}
/set plugins.var.python.vimode.search_vim on
\end{minted}

Now you just need to add a new connection, for example \mintinline{text}{irc.freenode.net}

\begin{minted}{text}
/server add freenode irc.freenode.net
\end{minted}

\noindent
and connect to it

\begin{minted}{text}
/connect freenode
\end{minted}

\begin{NOTE}
    You might need to authenticate with \texttt{NickServ}, before being able to write in a channel

    \begin{minted}{text}
/msg NickServ identify <password>
    \end{minted}
\end{NOTE}
\begin{NOTE}
    Instead of directly \mintinline{text}{/set}ting the values specified above, you can also do

    \begin{minted}{text}
/fset weechat.var.name
    \end{minted}

    \noindent
    after that, using the cursor, select the entry you want to modify (for example \mintinline{text}{plugins.var.python.vimode}) and then press \texttt{s} (make sure you’re in \texttt{insert} mode) and \texttt{Return}, in order to modify the existing value.
\end{NOTE}

\subsection{PDF viewer}
\label{sec:console-pdf-viewer}

\begin{packagetable}
    \texttt{extra} & \texttt{ghostscript} \\
    \texttt{community} & \texttt{fbida} \\
\end{packagetable}

To use \texttt{asciidoctor-pdf}, you might be wondering how you are supposed to open the generated PDFs from the native linux console.

This \texttt{fbida} package provides the \texttt{fbgs} software, which renders a PDF document using the native framebuffer.

To view this PDF document (\mintinline{text}{Documentation.pdf}) for example, you would run

\begin{minted}{console}
dustvoice@DustArch ~
$ fbgs Documentation.pdf
\end{minted}

\begin{NOTE}
    You can view all the controls by pressing \texttt{h}.
\end{NOTE}

\section{Additional \texttt{hybrid} software}
\label{sec:additional-hybrid-software}

Some additional software providing some kind of \texttt{GUI} to work with, but that can be useful in a \texttt{console} only environment nevertheless.

\subsection{\texttt{Pass}word management}
\label{sec:password-management}

I’m using \texttt{pass} as my password manager.
As we already installed it in the \nameref{sec:additional-required-tools} step and updated the \texttt{submodule} that holds our \mintinline{text}{.password-store}, there is nothing left to do in this step

\subsection{\texttt{python}}
\label{sec:python}

\begin{packagetable}
    \texttt{extra} & \texttt{python} \\
\end{packagetable}

Python has become really important for a magnitude of use cases.

\subsection{\texttt{ruby} \& \texttt{asciidoctor}}
\label{sec:ruby-and-asciidoctor}

\begin{packagetable}
    \texttt{extra} & \texttt{ruby rubygems} \\
\end{packagetable}

In order to use \texttt{asciidoctor}, we have to install \texttt{ruby} and \texttt{rubygems}.
After that we can install \texttt{asciidoctor} and all its required gems.

\begin{NOTE}
    If you want to have pretty and highlighted source code, you’ll need to install a code formatter too.

    For me there are mainly two options

    \begin{itemize}
        \item \texttt{pygments.rb}, which requires python to be installed

            \begin{minted}{console}
dustvoice@DustArch ~
$ gem install pygments.rb
            \end{minted}

        \item \texttt{rouge} which is a native \texttt{ruby} gem

            \begin{minted}{console}
dustvoice@DustArch ~
$ gem install rouge
            \end{minted}
    \end{itemize}
\end{NOTE}

Now the only thing left, in my case at least, is adding \mintinline{text}{~/.gem/ruby/2.7.0/bin} to your path.

\begin{NOTE}
    Please note that if you run a ruby version different from \texttt{2.7.0}, or if you upgrade your ruby version, you have to use the \texttt{bin} path for that version.
\end{NOTE}

For \texttt{zsh} you’ll want to add a new entry inside the \mintinline{text}{.zshpath} file

\begin{mintedlisting}
    \begin{minted}{text}
path+=("$HOME/.gem/ruby/2.7.0/bin")
    \end{minted}

    \caption{\mintinline{text}{~/.zshpath}}
\end{mintedlisting}

\noindent
which then gets sourced by the provided \mintinline{text}{.zshenv} file.
An example is provided with the \mintinline{text}{.zshpath.example} file

\begin{NOTE}
    You might have to re-\mintinline{console}{$ source} the \mintinline{text}{.zshenv} file to make the changes take effect immediately

    \begin{minted}{console}
dustvoice@DustArch ~
$ source .zshenv
    \end{minted}
\end{NOTE}
\begin{NOTE}
    If you want to add a new entry to the \texttt{path} variable, you have to append it to the array

    \begin{minted}{text}
path+=("pass:[$HOME/.gem/ruby/2.7.0/bin" "$]HOME/.gem/ruby/2.6.0/bin")
    \end{minted}
\end{NOTE}
\begin{NOTE}
    If you use another shell than \texttt{zsh}, you might have to do something different, to add a directory to your \texttt{PATH}.

\end{NOTE}

\subsection{\texttt{JUCE} and \texttt{FRUT}}
\label{sec:juce-and-frut}

\texttt{JUCE} is a library for \texttt{C++} that enables you to develop cross-platform applications with a single codebase.

\texttt{FRUT} makes it possible to manage \texttt{JUCE} projects purely from \texttt{cmake}.

% TODO: Update things regarding FRUT, cmake, etc.
\begin{NOTE}
    Note that apparently in the new \texttt{JUCE} version, \texttt{cmake} support is integrated.
    It remains to be seen how well this will work and if \texttt{FRUT} will become obsolete.

    The information in this guide should be updated ASAP, if it is apparent that \texttt{FRUT} has now become obsolete.
\end{NOTE}

\begin{minted}{console}
dustvoice@DustArch ~
$ git clone https://github.com/WeAreROLI/JUCE.git
dustvoice@DustArch ~
$ cd JUCE
dustvoice@DustArch ~/JUCE
$ git checkout develop
dustvoice@DustArch ~/JUCE
$ cd ..
dustvoice@DustArch ~
$ git clone https://github.com/McMartin/FRUT.git
\end{minted}

\subsubsection{Using \texttt{JUCE}}
\label{sec:using-juce}

\begin{packagetable}
    \texttt{core} & \texttt{gcc gnutls} \\
    \texttt{extra} & \texttt{alsa-lib clang freeglut freetype2 ladspa libx11 libxcomposite libxinerama libxrandr mesa webkit2gtk} \\
    \texttt{community} & \texttt{jack2 libcurl-gnutls} \\
    \texttt{multilib} & \texttt{lib32-freeglut} \\
\end{packagetable}

In order to use \texttt{JUCE}, you’ll need to have some dependency packages installed, where \texttt{ladspa} and \texttt{lib32-freeglut} are not neccessarily needed.

\subsection{Additional development tools}
\label{sec:additional-development-tools}

Here are just some examples of development tools one could install in addition to what we already have.

\subsubsection{Code formatting}
\label{sec:code-formatting}

\begin{packagetable}
    \texttt{community} & \texttt{astyle} \\
\end{packagetable}

We already have \texttt{clang-format} as a code formatter, but this only works for \texttt{C}-family languages.
For \texttt{java} stuff, we can use \texttt{astyle}

\subsubsection{Documentation}
\label{sec:documentation}

\begin{packagetable}
    \texttt{extra} & \texttt{doxygen} \\
\end{packagetable}

To generate a documentation from source code, I mostly use \texttt{doxygen}

\subsubsection{Build tools}
\label{sec:build-tools}

\begin{packagetable}
    \texttt{community} & \texttt{ninja} \\
\end{packagetable}

In addition to \texttt{make}, I’ll often times use \texttt{ninja} for my builds

\subsection{Android file transfer}
\label{sec:android-file-transfer}

\begin{packagetable}
    \texttt{extra} & \texttt{gvfs-mtp libmtp} \\
\end{packagetable}

Now you should be able to see your phone inside either your preferred filemanager, in my case \texttt{thunar}, or \texttt{gigolo\textsuperscript{\texttt{AUR}}}.

If you want to access the android’s file system from the command line, you will need to either install and use \texttt{simple-mtpfs\textsuperscript{\texttt{AUR}}}, or \texttt{adb}

\subsubsection{\texttt{simple-mtpfs\texorpdfstring{\textsuperscript{AUR}}{ (AUR)}}}
\label{sec:simple-mtpfs-aur}

\begin{packagetable}
    \texttt{AUR} & \texttt{simple-mtpfs} \\
\end{packagetable}

Edit \mintinline{text}{/etc/fuse.conf} to uncomment

\begin{mintedlisting}
    \begin{minted}{text}
user_allow_other
    \end{minted}

    \caption{\mintinline{text}{/etc/fuse.conf}}
\end{mintedlisting}

\noindent
and mount the android device

\begin{minted}{console}
dustvoice@DustArch ~
$ simple-mtpfs -l
dustvoice@DustArch ~
$ mkdir ~/mnt
dustvoice@DustArch ~
$ simple-mtpfs --device <number> ~/mnt -allow_other
\end{minted}

\noindent
and respectively unmount it

\begin{minted}{console}
dustvoice@DustArch ~
$ fusermount -u mnt
dustvoice@DustArch ~
$ rmdir mnt
\end{minted}

\subsubsection{\texttt{adb}}
\label{sec:adb}

\begin{packagetable}
    \texttt{community} & \texttt{android-tools} \\
\end{packagetable}

Kill the \texttt{adb} server, if it is running

\begin{minted}{console}
dustvoice@DustArch ~
$ adb kill-server
\end{minted}

\begin{NOTE}
    If the server is currently not running, \mintinline{console}{$ adb [...]} will output an error with a \texttt{Connection refused} message.
\end{NOTE}

Now connect your phone, unlock it and start the \texttt{adb} server

\begin{minted}{console}
dustvoice@DustArch ~
$ adb start-server
\end{minted}

If the PC is unknown to the android device, it will display a confirmation dialog.
Accept it and ensure that the device was recognized

\begin{minted}{console}
dustvoice@DustArch ~
$ adb devices
\end{minted}

Now you can \texttt{push}/\texttt{pull} files.

\begin{minted}{console}
dustvoice@DustArch ~
$ adb pull /storage/emulated/0/DCIM/Camera/IMG.jpg .
dustvoice@DustArch ~
$ adb push IMG.jpg /storage/emulated/0/DCIM/Camera/IMG2.jpg
dustvoice@DustArch ~
$ adb kill-server
\end{minted}

\begin{NOTE}
    Of course you would need to have the \emph{developer options} unlocked, as well as the \emph{USB debugging} option enabled within them, for \texttt{adb} to even work.
\end{NOTE}

\subsection{Partition management}
\label{sec:partition-management}

\begin{packagetable}
    \texttt{extra} & \texttt{gparted parted} \\
\end{packagetable}

You may also choose to use a graphical partitioning software instead of \texttt{fdisk} or \texttt{cfdisk}.
For that you can use \texttt{gparted}.
Of course there is also the \texttt{console} equivalent \texttt{parted}.

\subsection{PDF viewer}
\label{sec:gui-pdf-viewer}

\begin{packagetable}
    \texttt{extra} & \texttt{evince} \\
    \texttt{community} & \texttt{zathura zathura-pdf-mupdf} \\
\end{packagetable}

To use \texttt{asciidoctor-pdf}, you might be wondering how you are supposed to open the generated PDFs using the GUI.

\texttt{zathura} has a minimalistic design and UI with a focus on vim keybinding, whereas \texttt{evince} is a more desktop like experience, with things like a print dialogue, etc.

\subsection{Process management}
\label{sec:process-management}

\begin{packagetable}
    \texttt{extra} & \texttt{htop xfce4-taskmanager} \\
\end{packagetable}

The native tool is \texttt{top}.

The next evolutionary step would be \texttt{htop}, which is an improved version of \texttt{top} (like \texttt{vi} and \texttt{vim} for example)

If you prefer a GUI for that kind of task, use \texttt{xfce4-taskmanager}.

\subsection{Video software}
\label{sec:console-video-software}

Just some additional software related to videos.

\subsubsection{Live streaming a terminal session}
\label{sec:live-streaming-a-terminal-session}

\begin{packagetable}
    \texttt{community} & \texttt{tmate} \\
\end{packagetable}

For this task, you’ll need a program called \texttt{tmate}.

\section{Additional \texttt{GUI} software}
\label{sec:additional-gui-software}

As you now have a working graphical desktop environment, you might want to install some software to utilize your newly gained power.

\subsection{Session Lock}
\label{sec:session-lock}

\begin{packagetable}
    \texttt{community} & \texttt{xsecurelock xss-lock} \\
\end{packagetable}

Probably the first thing you’ll want to set up is a session locker, which locks your \texttt{X}-session after resuming from sleep, hibernation, etc.
It then requires you to input your password again, so no unauthorized user can access you machine.

I’ll use \texttt{xss-lock} to hook into the necessary \texttt{systemd} events and then use \texttt{xsecurelock} as my locker.

\begin{IMPORTANT}
    You need to make sure this command gets executed upon start of the \texttt{X}-session, so hook it into your window manager startup script, or in a file called by your desktop environment

    \begin{minted}{console}
dustvoice@DustArch ~
$ xss-lock -l -- xsecurelock &
    \end{minted}
\end{IMPORTANT}

\subsection{\texttt{xfce-polkit\texorpdfstring{\textsuperscript{AUR}}{ (AUR)}}}
\label{sec:xfce-polkit-aur}

\begin{packagetable}
    \texttt{AUR} & \texttt{xfce-polkit} \\
\end{packagetable}

In order for GUI applications to acquire \texttt{sudo} permissions, we need to install a \texttt{PolicyKit} authentication agent.

We could use \texttt{gnome-polkit} for that purpose, which resides inside the official repositories, but I decided on using \texttt{xfce-polkit\textsuperscript{\texttt{AUR}}}.

Now you just need to startup \texttt{xfce-polkit\textsuperscript{\texttt{AUR}}} before trying to execute something like \texttt{gparted} and you’ll be prompted for your password.

As I already launch it as a part of my \texttt{bspwm} configuration, I won’t have to worry about that.

\subsection{Desktop background}
\label{sec:desktop-background}

\begin{packagetable}
    \texttt{extra} & \texttt{nitrogen} \\
\end{packagetable}

You might want to consider installing \texttt{nitrogen}, in order to be able to set a background image

\subsection{Compositing software}
\label{sec:compositing-software}

\begin{packagetable}
    \texttt{community} & \texttt{picom} \\
\end{packagetable}

To get buttery smooth animation as well as e.g. smooth video playback in \texttt{brave} without screen tearing, you might want to consider using a compositor, in my case one named \texttt{picom}

\begin{WARNING}
    In order for \texttt{obs}' screen capture to work correctly, you need to kill \texttt{picom} completely before using \texttt{obs}.

    \begin{minted}{console}
dustvoice@DustArch ~
$ killall picom
    \end{minted}

    \noindent
    or

    \begin{minted}{console}
dustvoice@DustArch ~
$ ps aux | grep picom
dustvoice@DustArch ~
$ kill -9 <pid>
    \end{minted}
\end{WARNING}

\subsection{\texttt{networkmanager} applet}
\label{sec:networkmanager-applet}

\begin{packagetable}
    \texttt{extra} & \texttt{network-manager-applet} \\
\end{packagetable}

To install the \texttt{NetworkManager} applet, which lives in your tray and provides you with a quick method to connect to different networks, you have to install the \texttt{network-manager-applet} package

Now you can start the applet with

\begin{minted}{console}
dustvoice@DustArch ~
$ nm-applet &
\end{minted}

If you want to edit the network connections with a more full screen approach, you can also launch \mintinline{console}{$ nm-connection-editor}.

\begin{NOTE}
    The \texttt{nm-connection-editor} doesn’t search for available Wi-Fis.
    You would have to set up a Wi-Fi connection completely by hand, which could be desirable depending on how difficult it is to set up your Wi-Fi.
\end{NOTE}

\subsection{Show keyboard layout}
\label{sec:show-keyboard-layout}

\begin{packagetable}
    \texttt{AUR} & \texttt{xkblayout-state} \\
\end{packagetable}

To show, which keyboard layout and variant is currently in use, you can use \texttt{xkblayout-state\textsuperscript{\texttt{AUR}}}

Now simply issue the \texttt{layout} alias, provided by my custom \texttt{zsh} configuration.

\subsection{X clipboard}
\label{sec:x-clipboard}

\begin{packagetable}
    \texttt{extra} & \texttt{xclip} \\
\end{packagetable}

To copy something from the terminal to the \texttt{xorg} clipboard, use \texttt{xclip}

\subsection{Taking screen shots}
\label{sec:taking-screen-shots}

\begin{packagetable}
    \texttt{community} & \texttt{scrot} \\
\end{packagetable}

For this functionality, especially in combination with \texttt{rofi}, use \texttt{scrot}.
\mintinline{console}{$ scrot ~/Pictures/filename.png} then saves the screen shot under \mintinline{text}{~/Pictures/filename.png}.

\subsection{Image viewer}
\label{sec:image-viewer}

\begin{packagetable}
    \texttt{extra} & \texttt{ristretto} \\
\end{packagetable}

Now that we can create screen shots, we might also want to view those

\begin{minted}{console}
dustvoice@DustArch ~
$ ristretto filename.png
\end{minted}

\subsection{File manager}
\label{sec:file-manager}

\begin{packagetable}
    \texttt{extra} & \texttt{gvfs thunar} \\
    \texttt{AUR} & \texttt{gigolo} \\
\end{packagetable}

You probably also want to use a file manager.
In my case, \texttt{thunar}, the \texttt{xfce} file manager, worked best.

To also be able to mount removable drives, without being \texttt{root} or using \texttt{sudo}, and in order to have a GUI for mounting stuff, you would need to use \texttt{gigolo\textsuperscript{\texttt{AUR}}} and \texttt{gvfs}.

\subsection{Archive manager}
\label{sec:archive-manager}

\begin{packagetable}
    \texttt{extra} & \texttt{cpio unrar unzip zip} \\
    \texttt{community} & \texttt{xarchiver} \\
\end{packagetable}

As we now have a file manager, it might be annoying, to open up a terminal every time you simply want to extract an archive of some sort.
That’s why we’ll use \texttt{xarchiver}.

\subsection{Web browser}
\label{sec:web-browser}

\begin{packagetable}
    \texttt{extra} & \texttt{firefox firefox-i18n-en-us} \\
    \texttt{community} & \texttt{browserpass} \\
\end{packagetable}

As you’re already using a GUI, you also might be interested in a web browser.
In my case, I’m using \texttt{firefox}, as well as \texttt{browserpass} from the official repositories, together with the \hreffn{https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/}{uBlock Origin}, \hreffn{https://addons.mozilla.org/en-US/firefox/addon/darkreader/}{Dark Reader}, \hreffn{https://addons.mozilla.org/en-US/firefox/addon/duckduckgo-for-firefox/}{DuckDuckGo Pricacy Essentials}, \hreffn{https://addons.mozilla.org/en-US/firefox/addon/vimium-ff/}{Vimium} and finally \hreffn{https://addons.mozilla.org/en-US/firefox/addon/browserpass-ce/}{Browserpass} add-ons, in order to use my passwords in \texttt{firefox} and have best protection in regard to privacy, while browsing the web.

We still have to setup \texttt{browserpass}, after installing all of this

\begin{minted}{console}
dustvoice@DustArch ~
$ cd /usr/lib/browserpass
dustvoice@DustArch /usr/lib/browserpass
$ make hosts-firefox-user
dustvoice@DustArch /usr/lib/browserpass
$ cd ~
\end{minted}

\subsubsection{Entering the dark side}
\label{sec:entering-the-dark-side}

\begin{packagetable}
    \texttt{AUR} & \texttt{tor-browser} \\
\end{packagetable}

You might want to be completely anonymous whilst browsing the web at some point.
Although this shouldn’t be your only precaution, using \texttt{tor-browser\textsuperscript{\texttt{AUR}}} would be the first thing to do

\begin{NOTE}
    You might have to check out how to import the \texttt{gpg} keys on the \texttt{AUR} page of \texttt{tor-browser}.
\end{NOTE}

\subsection{Office utilities}
\label{sec:office-utilities}

\begin{packagetable}
    \texttt{extra} & \texttt{libreoffice-fresh} \\
\end{packagetable}

I’ll use \texttt{libreoffice-fresh} for anything that I’m not able to do with \texttt{neovim}.

\subsubsection{Printing}
\label{sec:printing}

\begin{packagetable}
    \texttt{extra} & \texttt{avahi cups cups-pdf nss-mdns print-manager system-config-printer} \\
\end{packagetable}

In order to be able to print from the \texttt{gtk} print dialog, we’ll also need \texttt{system-config-printer} and \texttt{print-manager}.

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo systemctl enable avahi-daemon.service
dustvoice@DustArch ~
$ sudo systemctl start avahi-daemon.service
\end{minted}

Now you have to edit \mintinline{text}{/etc/nsswitch.conf} and add\newline
\mintinline{text}{mdns4_minimal [NOTFOUND=return]}

\begin{mintedlisting}
    \begin{minted}{text}
hosts: files mymachines myhostname mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns
    \end{minted}

    \caption{\mintinline{text}{/etc/nsswitch.conf}}
\end{mintedlisting}

Now continue with this

\begin{minted}{console}
dustvoice@DustArch ~
$ avahi-browse --all --ignore-local --resolve --terminate
dustvoice@DustArch ~
$ sudo systemctl enable org.cups.cupsd.service
dustvoice@DustArch ~
$ sudo systemctl start org.cups.cupsd.service
\end{minted}

Just open up \texttt{system-config-printer} now and configure your printer.

To test if everything is working, you could open up \texttt{brave}, then go to \emph{Print} and then try printing.

\subsection{Communication}
\label{sec:gui-communication}

Life is all about communicating.
Here are some pieces of software to do exactly that.

\subsubsection{Email}
\label{sec:email}

\begin{packagetable}
    \texttt{extra} & \texttt{thunderbird} \\
\end{packagetable}

There is nothing better than some classical email.

\subsubsection{Telegram}
\label{sec:telegram}

\begin{packagetable}
    \texttt{community} & \texttt{telegram-desktop} \\
\end{packagetable}

You want to have your \texttt{telegram} messages on your desktop PC?

\subsubsection{TeamSpeak 3}
\label{sec:teamspeak-3}

\begin{packagetable}
    \texttt{community} & \texttt{teamspeak3} \\
\end{packagetable}

Wanna chat with your gaming friends and they have a \texttt{teamspeak3} server?

\subsubsection{Discord}
\label{sec:discord}

\begin{packagetable}
    \texttt{community} & \texttt{discord} \\
\end{packagetable}

You’d rather use \texttt{discord}?

\subsection{Video software}
\label{sec:gui-video-software}

Just some additional software related to videos.

\subsubsection{Viewing video}
\label{sec:viewing-video}

\begin{packagetable}
    \texttt{extra} & \texttt{vlc} \\
\end{packagetable}

You might consider using \texttt{vlc}

\subsubsection{Creating video}
\label{sec:creating-video}

\begin{packagetable}
    \texttt{AUR} & \texttt{obs-linuxbrowser-bin obs-glcapture-git obs-studio-git} \\
\end{packagetable}

\texttt{obs-studio-git\textsuperscript{\texttt{AUR}}} should be the right choice.

You can also make use of the plugins provided in the package list above.

\paragraph{Showing keystrokes}
\label{par:showing-keystrokes}

\begin{packagetable}
    \texttt{AUR} & \texttt{screenkey} \\
\end{packagetable}

In order to show the viewers what keystrokes you’re pressing, you can use something like \texttt{screenkey\textsuperscript{\texttt{AUR}}}

\begin{NOTE}
    For ideal use with \texttt{obs}, my \texttt{dotfiles} repository already provides you with the \mintinline{console}{$ screenkey-obs} alias for you to run with \texttt{zsh}.

\end{NOTE}

\subsubsection{Editing video}
\label{sec:editing-video}

\begin{packagetable}
    \texttt{AUR} & \texttt{davinci-resolve} \\
\end{packagetable}

In my case, I’m using \texttt{davinci-resolve\textsuperscript{\texttt{AUR}}}.

\subsubsection{Utilizing video}
\label{sec:utilizing-video}

\begin{packagetable}
    \texttt{AUR} & \texttt{teamviewer} \\
\end{packagetable}

Wanna remote control your own or another PC?
\texttt{teamviewer\textsuperscript{\texttt{AUR}}} might just be the right choice for you

\subsection{Audio Production}
\label{sec:audio-production}

You might have to edit \mintinline{text}{/etc/security/limits.conf}, to increase the allowed locked memory amount.

In my case I have 32GB of RAM and I want the \texttt{audio} group to be able to allocate most of the RAM, which is why I added the following line to the file

% TODO: Double check, how I currently use the jack setup for audio production as it really works this time!
\begin{mintedlisting}
    \begin{minted}{text}
@audio - memlock 29360128
    \end{minted}

    \caption{\mintinline{text}{/etc/security/limits.conf}}
\end{mintedlisting}

\subsubsection{Ardour}
\label{sec:ardour}

\begin{packagetable}
    \texttt{community} & \texttt{ardour} \\
\end{packagetable}

To e.g. edit and produce audio, you could use \texttt{ardour}, because it’s easy to use, stable and cross platform.

\begin{NOTE}
    \begin{packagetable}
        \texttt{extra} & \texttt{ffmpeg} \\
    \end{packagetable}

    Ardour won’t natively save in the \texttt{mp3} format, due to licensing stuff.
    In order to create \texttt{mp3} files, for sharing with other devices, because they have problems with \texttt{wav} files, for example, you can just use \texttt{ffmpeg}.

    and after that we’re going to convert \mintinline{text}{in.wav} to \mintinline{text}{out.mp3}

    \begin{minted}{console}
dustvoice@DustArch ~
$ ffmpeg -i in.wav -acodec mp3 out.mp3
    \end{minted}
\end{NOTE}

% TODO: Add how I have carla, etc. pp set up on the laptop for windows vst/lv2/etc.

\subsubsection{Reaper}
\label{sec:reaper}

\begin{packagetable}
    \texttt{AUR} & \texttt{reaper-bin} \\
\end{packagetable}

Instead of \texttt{ardour}, I’m using \texttt{reaper}, which is available for linux as a beta version, in my case more stable than \texttt{ardour} and more easy to use for me.

\subsection{Virtualization}
\label{sec:virtualization}

\begin{packagetable}
    \texttt{community} & \texttt{virtualbox virtualbox-host-modules-arch} \\
\end{packagetable}

You might need to run another OS, for example Mac OS, from within Linux, e.g. for development/testing purposes.
For that you can use \texttt{virtualbox}.

Now when you want to use \texttt{virtualbox} just load the kernel module

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo modprobe vboxdrv
\end{minted}

\noindent
and add the user which is supposed to run \mintinline{console}{$ virtualbox} to the \texttt{vboxusers} group

\begin{minted}{console}
dustvoice@DustArch ~
pass:[$ sudo usermod -a G vboxusers $]USER
\end{minted}

\noindent
and if you want to use \mintinline{text}{rawdisk} functionality, also to the \texttt{disk} group

\begin{minted}{console}
dustvoice@DustArch ~
pass:[$ sudo usermod -a G disk $]USER
\end{minted}

Now just re-login and you’re good to go.

\subsection{Gaming}
\label{sec:gaming}

\begin{packagetable}
    \texttt{extra} & \texttt{pulseaudio pulseaudio-alsa} \\
    \texttt{community} & \texttt{lutris} \\
    \texttt{multilib} & \texttt{lib32-libpulse lib32-nvidia-utils steam} \\
\end{packagetable}

The first option for native/emulated gaming on Linux is obviously \texttt{steam}.

The second option would be \texttt{lutris}, a program, that configures a wine instance correctly, etc.

\subsection{Wacom}
\label{sec:wacom}

\begin{packagetable}
    \texttt{extra} & \texttt{libwacom xf86-input-wacom} \\
\end{packagetable}

In order to use a Wacom graphics tablet, you’ll have to install some packages

You can now configure your tablet using the \texttt{xsetwacom} command.

\subsection{\texttt{VNC} \& \texttt{RDP}}
\label{sec:vnc-and-rdp}

\begin{packagetable}
    \texttt{extra} & \texttt{libvncserver} \\
    \texttt{community} & \texttt{remmina} \\
    \texttt{AUR} & \texttt{freerdp} \\
\end{packagetable}

In order to connect to a machine over \texttt{VNC} or to connect to a machine using the \texttt{Remote Desktop Protocol}, for example to connect to a Windows machine, I’ll need to install \texttt{freerdp\textsuperscript{\texttt{AUR}}}, as well as \texttt{libvncserver}, for \texttt{RDP} and \texttt{VNC} functionality respectively, as well as \texttt{remmina}, to have a GUI client for those two protocols.

Now you can set up all your connections inside \texttt{remmina}.

\chapter{Upgrading the system}
\label{sec:upgrading-the-system}

You’re probably wondering why this gets a dedicated section.

You’ll probably think that it would be just a matter of issuing

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo pacman -Syu
\end{minted}

That’s both true and false.

You have to make sure, \emph{that your boot partition is mounted at \mintinline{text}{/boot}} in order for everything to upgrade correctly.
That’s because the moment you upgrade the \texttt{linux} package without having the correct partition mounted at \mintinline{text}{/boot}, your system won’t boot.
You also might have to do \mintinline{console}{$ grub-mkconfig -o /boot/grub/grub.cfg} after you install a different kernel image.

If your system \emph{indeed doesn’t boot} and \emph{boots to a recovery console}, then double check that the issue really is the not perfectly executed kernel update by issuing

\begin{minted}{console}
root@DustArch ~
$ uname -a
\end{minted}

\noindent
and

\begin{minted}{console}
root@DustArch ~
$ pacman -Q linux
\end{minted}

\emph{The version of these two packages should be exactly the same!}

If it isn’t there is an easy fix for it.

\section{Fixing a faulty kernel upgrade}
\label{sec:fixing-a-faulty-kernel-upgrade}

First off we need to restore the old \texttt{linux} package.

For that note the version number of

\begin{minted}{console}
root@DustArch ~
$ uname -a
\end{minted}

Now we’ll make sure first that nothing is mounted at \mintinline{text}{/boot}, because the process will likely create some unwanted files.
The process will also create a new \mintinline{text}{/boot} folder, which we’re going to delete afterwards.

\begin{minted}{console}
root@DustArch ~
$ umount /boot
\end{minted}

Now \texttt{cd} into \texttt{pacman}'s package cache

\begin{minted}{console}
root@DustArch ~
$ cd /var/cache/pacman/pkg
\end{minted}

There should be a file located named something like \mintinline{text}{linux-<version>.pkg.tar.xz}, where \texttt{<version>} would be somewhat equivalent to the previously noted version number

Now downgrade the \texttt{linux} package

\begin{minted}{console}
root@DustArch ~
$ pacman -U linux-<version>.pkg.tar.xz
\end{minted}

After that remove the possibly created \mintinline{text}{/boot} directory

\begin{minted}{console}
root@DustArch ~
$ rm -rf /boot
root@DustArch ~
$ mkdir /boot
\end{minted}

Now reboot and mount the \texttt{boot} partition, in my case an EFI System partition.

Now simply rerun

\begin{minted}{console}
dustvoice@DustArch ~
$ sudo pacman -Syu
\end{minted}

\noindent
and you should be fine now.

\chapter{Additional notes}
\label{sec:additional-notes}

If you’ve printed this guide, you might want to add some additional blank pages for notes.
\end{document}
