diff --git a/.gitignore b/.gitignore index 2fa4b87..2087986 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,5 @@ /*/ !/.gitignore -!/changelog.org -!/notes.org -!/todo.org - -!/dustdoc.cls -!/Documentation.tex -!/DustArch.org !/DustArch.typ +!/dustypst diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..77b16d8 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dustypst"] + path = dustypst + url = https://git.dustvoice.de/DustVoice/dustypst diff --git a/Documentation.tex b/Documentation.tex deleted file mode 100644 index 31a39d4..0000000 --- a/Documentation.tex +++ /dev/null @@ -1,3316 +0,0 @@ -%! 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} - -\begin{NOTE} - In the following document, - I will denote a \texttt{root} shell with a preceding \mintinline{fish}{#} and a \texttt{user} shell with a preceding \mintinline{fish}{>}. -\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}{fish} -> pacman -Sy -\end{minted} - -\begin{WARNING} - Using \mintinline{fish}{> 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{fish}{> 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}{fish} -root in ~ -> pacman -S -\end{minted} - -\noindent -where you would replace \texttt{} with the actual package name. - -If you want to remove an installed package, just use - -\begin{minted}{fish} -root in ~ -> pacman -Rsu -\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}{fish} -root in ~ -> pacman -Ss -\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}{fish} -root in ~ -> pacman -Rdd - \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, in order to install the \texttt{AUR}-helper \texttt{paru}. - -\begin{enumerate} - \item Clone the package with \texttt{git} - - \begin{minted}{fish} -dustvoice in ~ -> git clone https://aur.archlinux.org/paru.git - \end{minted} - - - \begin{NOTE} - If you are on a slow PC, or don't want to compile \texttt{paru} from scratch, you can also use \hreffn{https://aur.archlinux.org/paru-bin.git}{\texttt{paru-bin}}. - \end{NOTE} - - \item Switch to the package directory - - \begin{minted}{fish} -dustvoice in ~ -> cd paru - \end{minted} - - - \item Execute \mintinline{fish}{> makepkg} - - \begin{minted}{fish} -dustvoice in ~/paru -> makepkg -si - \end{minted} - - - \item Delete all files created, as \texttt{paru} will now be handling all the \texttt{AUR} stuff. - - \begin{minted}{fish} -dustvoice in ~/paru -> cd .. - -dustvoice in ~ -> rm -rf paru - \end{minted} - -\end{enumerate} - -\begin{NOTE} - If you only install \texttt{AUR} packages the manual way, 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 a 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} - -\subsection{Software categories}% -\label{sec:software-categories} - -In this guide, software is categorized in three different categories - -\begin{itemize} - \item \texttt{Fish} software is intended to be used with either the native linux fish, 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 fish and a graphical desktop environment (e.g. \texttt{networkmanager}), or there are packages available for both fish and a graphical desktop environment (e.g. \texttt{pulseaudio} with \texttt{pulsemixer} for \texttt{Fish} 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{pkgtable} - \texttt{core} & \texttt{libutil-linux} \\ - \texttt{extra} & \texttt{git} \\ - \texttt{community} & \texttt{ardour cadence jsampler linuxsampler qsampler sample-package} \\ - \texttt{AUR} & \texttt{sbupdate} \\ -\end{pkgtable} - -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}{fish} -root in ~ -> fdisk -l -\end{minted} - -\begin{NOTE} - The output of \mintinline{fish}{> 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}{fish} -root in ~ -> mkfs.ext4 /dev/sdb2 - -root in ~ -> mkswap /dev/sdb3 -\end{minted} - -After doing that, we can turn on the \texttt{swap} and mount the root partition. - -\begin{minted}{fish} -root in ~ -> swapon /dev/sdb3 - -root in ~ -> 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}{fish} -root in ~ -> mkdir /mnt/boot - -root in ~ -> 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{pkgtable} - \texttt{core} & \texttt{dosfstools} \\ -\end{pkgtable} - -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}{fish} -root in ~ -> 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{pkgtable} - \texttt{core} & \texttt{cryptsetup} \\ -\end{pkgtable} - -First off we have to create the \texttt{LUKS} volume - -\begin{minted}{fish} -root in ~ -> cryptsetup luksFormat --type luks2 /dev/nvme0n1p2 -\end{minted} - -After that we have to open the volume - -\begin{minted}{fish} -root in ~ -> 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{pkgtable} - \texttt{core} & \texttt{lvm2} \\ -\end{pkgtable} - -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}{fish} -root in ~ -> pvcreate /dev/mapper/cryptroot - -root in ~ -> vgcreate DustArch1 /dev/mapper/cryptroot - -root in ~ -> lvcreate -l 100%FREE -n root DustArch1 - -root in ~ -> lvreduce -L -32G /dev/DustArch1/root - -root in ~ -> 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}{fish} -root in ~ -> mkfs.ext4 -L / /dev/DustArch1/root - -root in ~ -> 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}{fish} -root in ~ -> mount /dev/DustArch1/root /mnt - -root in ~ -> mkdir /mnt/efi - -root in ~ -> mount /dev/nvme0n1p1 /mnt/efi - -root in ~ -> 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}{fish} -root in ~ -> umount /mnt/efi /mnt - \end{minted} - - \item deactivate the \texttt{VG} - - \begin{minted}{fish} -root in ~ -> vgchange -a n DustArch1 - \end{minted} - - \item close the \texttt{LUKS} volume - - \begin{minted}{fish} -root in ~ -> 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 mirrors 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}{fish} -root in ~ -> curl https://archlinux.org/mirrorlist/all > /etc/pacman.d/mirrorlist -\end{minted} - -\begin{NOTE} - \begin{pkgtable} - \texttt{community} & \texttt{reflector} \\ - \end{pkgtable} - - 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}{fish} -root in ~ -> 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}{fish} -root in ~ -> 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{pkgtable} - \texttt{core} & \texttt{base linux linux-firmware} \\ -\end{pkgtable} - -\begin{NOTE} - This is the actual command used in my case - - \begin{minted}{fish} -root in ~ -> pacstrap /mnt base linux linux-firmware - \end{minted} -\end{NOTE} - -After that generate an \texttt{fstab} using \texttt{genfstab} - -\begin{minted}{fish} -root in ~ -> 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}{fish} -root in ~ -> 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{pkgtable} - \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{pkgtable} - -\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}{fish} -root in / -> 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}{fish} -root in / -> ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime - -root in / -> hwclock --systohc --utc -\end{minted} - -Now you can also enable time synchronization over network - -\begin{minted}{fish} -root in / -> timedatectl set-timezone Europe/Berlin - -root in / -> timedatectl set-ntp true -\end{minted} - -\noindent -and check that everything is alright - -\begin{minted}{fish} -root in / -> 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}{fish} -root in / -> locale-gen -\end{minted} - -\noindent -and set the locale - -\begin{minted}{fish} -root in / -> 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}{fish} -root in / -> passwd -\end{minted} - -\noindent -and choose a new password. - -\subsection{Create a personal user}% -\label{sec:create-a-personal-user} - -\begin{pkgtable} - \texttt{core} & \texttt{sudo} \\ - \texttt{extra} & \texttt{zsh} \\ -\end{pkgtable} - -We are going to create a new user and set the password, groups and shell for this user - -\begin{minted}{fish} -root in / -> 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 in / -> 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[escapeinside=||]{text}{|\%|wheel [|\ldots|]} 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{pkgtable} - \texttt{core} & \texttt{efibootmgr} \\ -\end{pkgtable} - -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}{fish} -root in / -> 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{pkgtable} - \texttt{core} & \texttt{dosfstools efibootmgr grub} \\ - \texttt{extra} & \texttt{mtools} \\ - \texttt{community} & \texttt{os-prober} \\ -\end{pkgtable} - -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}{fish} -root in / -> 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}{fish} -root in / -> 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}{fish} -root in / -> 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}{/etc/default/grub}} -\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/grub.d/40_custom}} -\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{pkgtable} - \texttt{extra} & \texttt{memtest86+} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{AUR} & \texttt{memtest86-efi} \\ -\end{pkgtable} - -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}{fish} -root in / -> 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{fish}{> grub-mkconfig} as explained in the paragraph \nameref{par:generating-the-grub-config} of the section \nameref{sec:grub-config}. -\end{NOTE} - -\paragraph{Disabling \texttt{os-prober}}% -\label{par:disabling-os-prober} - -Sometimes it makes sense to disable the \texttt{os-prober} functionality of grub, even though \texttt{os-prober} is installed on the system (which auto enables it), for example when installing arch for portability purposes. -We can disable the os-prober functionality in the \texttt{grub} default config file. - -\begin{mintedlisting} - \begin{minted}{text} -GRUB_DISABLE_OS_PROBER=true - \end{minted} - - \caption{\mintinline{text}{/etc/default/grub}} -\end{mintedlisting} - -\paragraph{Generating the \texttt{grub} config}% -\label{par:generating-the-grub-config} - -Now we can finally generate our \mintinline{text}{grub.cfg} - -\begin{minted}{fish} -root in / -> 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{fishfont} - - These two, or one, if you didn’t use one of them, need to be replaced with \texttt{sd-vfish}. - 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}{fish} -root in / -> 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{pkgtable} - \texttt{AUR} & \texttt{shim-signed} \\ -\end{pkgtable} - -\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}{fish} -root in / -> cp /usr/share/shim-signed/shimx64.efi /boot/EFI/grub/ - -root in / -> 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}{fish} -root in ~/sb -> uuidgen --random > GUID.txt -\end{minted} - -\paragraph{\texttt{PK}}% -\label{par:pk} - -We can now generate our \texttt{PK} (Platform Key) - -\begin{minted}{fish} -root in ~/sb -> openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -subj "/CN=Platform Key for DustArch/" -out PK.crt - -root in ~/sb -> openssl x509 -outform DER -in PK.crt -out PK.cer - -root in ~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl - -root in ~/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}{fish} -root in ~/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}{fish} -root in ~/sb -> openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -subj "/CN=Key Exchange Key for DustArch/" -out KEK.crt - -root in ~/sb -> openssl x509 -outform DER -in KEK.crt -out KEK.cer - -root in ~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl - -root in ~/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}{fish} -root in ~/sb -> openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -subj "/CN=Signature Database key for DustArch" -out db.crt - -root in ~/sb -> openssl x509 -outform DER -in db.crt -out db.cer - -root in ~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl - -root in ~/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}{fish} -root in ~/sb -> curl -fLo WinCert.crt https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt - -root in ~/sb -> openssl x509 -inform DER -outform PEM -in MicWinCert.crt -out MicWinCert.pem - -root in ~/sb -> cert-to-efi-sig-list -g 77fa9abd-0359-4d32-bd60-28f4e78f784b MicWinCert.pem MS_db.esl - -root in ~/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}{fish} -root in ~/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{pkgtable} - \texttt{AUR} & \texttt{sbupdate-git} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{core} & \texttt{efibootmgr} \\ -\end{pkgtable} - -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}{fish} -root in ~/sb -> efibootmgr -c -d /dev/nvme0n1 -p 1 -L "Arch Linux fallback" -l "EFI\Arch\linux-fallback-signed.efi - -root in ~/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}{fish} -dustvoice in ~ -> ip link -\end{minted} - -To make sure that you have a working \emph{Internet} connection, issue - -\begin{minted}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> sudo systemctl restart NetworkManager.service -\end{minted} - -\noindent -and then try \mintinline{fish}{> 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}{fish} -dustvoice in ~ -> nmcli radio -\end{minted} - -\noindent -and if not, enable it - -\begin{minted}{fish} -dustvoice in ~ -> nmcli radio wifi on -\end{minted} - -Now make sure your Wi-Fi interface appears under - -\begin{minted}{fish} -dustvoice in ~ -> nmcli device -\end{minted} - -Rescan for available networks - -\begin{minted}{fish} -dustvoice in ~ -> nmcli device wifi rescan -\end{minted} - -\noindent -and list all found networks - -\begin{minted}{fish} -dustvoice in ~ -> nmcli device wifi list -\end{minted} - -After that connect to the network - -\begin{minted}{fish} -dustvoice in ~ -> nmcli device wifi connect --ask -\end{minted} - -Now try \mintinline{fish}{> 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}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> 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{pkgtable} - \texttt{extra} & \texttt{git} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{core} & \texttt{gnupg} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{libusb-compat} \\ - \texttt{community} & \texttt{ccid opensc pcsclite} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> sudo systemctl enable pcscd.service - -dustvoice in ~ -> sudo systemctl start pcscd.service -\end{minted} - -After that, you should be able to see your smartcard being detected - -\begin{minted}{fish} -dustvoice in ~ -> 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{pkgtable} - core & make openssh \\ - extra & clang cmake jdk-openjdk python \\ - community & pass python-pynvim \\ -\end{pkgtable} - -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{fish}{> su} or \mintinline{fish}{> 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}{fish} -dustvoice in ~ -> git init - -dustvoice in ~ -> git remote add origin https://git.dustvoice.de/DustVoice/dotfiles.git - -dustvoice in ~ -> git fetch - -dustvoice in ~ -> git reset origin/master --hard - -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> chmod 700 .gnupg - -dustvoice in ~ -> gpg --card-status - -dustvoice in ~ -> gpg --card-edit -\end{minted} - - -\begin{minted}{fish} -(insert) gpg/card> fetch -(insert) gpg/card> q -\end{minted} - -\begin{minted}{fish} -dustvoice in ~ -> 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{fish}{> 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}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> git submodule update --recursive --init - -dustvoice in ~ -> source .zshrc - -dustvoice in ~ -> cd .config/nvim - -dustvoice in ~/.config/nvim -> echo 'let g:platform = "linux"' >> platform.vim - -dustvoice in ~/.config/nvim -> echo 'let g:use_autocomplete = 3' >> custom.vim - -dustvoice in ~/.config/nvim -> echo 'let g:use_clang_format = 1' >> custom.vim - -dustvoice in ~/.config/nvim -> echo 'let g:use_font = 0' >> custom.vim - -dustvoice in ~/.config/nvim -> nvim --headless +PlugInstall +qa - -dustvoice in ~/.config/nvim -> cd plugged/YouCompleteMe - -dustvoice in ~/.config/nvim/plugged/YouCompleteMe -> python3 install.py --clang-completer --java-completer - -dustvoice in ~/.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 - HostName - ForwardAgent yes - ForwardX11 yes - RemoteForward - RemoteForward - \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}{fish} -dustvoice in ~ -> 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 machines. - -\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 machines 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}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> 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{fish}{> 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{fish}{> sudo -iu root}. -\end{WARNING} - -\section{Audio}% -\label{sec:audio} - -Well, why wouldn’t you want audio \ldots - -\subsection{\texttt{alsa}}% -\label{sec:alsa} - -\begin{pkgtable} - \texttt{extra} & \texttt{alsa-utils} \\ -\end{pkgtable} - -\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}{fish} -dustvoice in ~ -> 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{pkgtable} - \texttt{extra} & \texttt{pavucontrol pulseaudio} \\ - \texttt{community} & \texttt{pulsemixer} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> pulseaudio --kill - -dustvoice in ~ -> pulseaudio --start -\end{minted} - - -\subsection{\texttt{jack}}% -\label{sec:jack} - -\begin{pkgtable} - \texttt{extra} & \texttt{pulseaudio-jack} \\ - \texttt{community} & \texttt{cadence jack2} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{libao libid3tag libmad libpulse opus wavpack} \\ - \texttt{community} & \texttt{sox twolame} \\ -\end{pkgtable} - -To also play audio, we need to install the mentioned packages and then simply do - -\begin{minted}{fish} -dustvoice in ~ -> play audio.wav - -dustvoice in ~ -> play audio.mp3 -\end{minted} - - -\noindent -to play audio. - -\section{Bluetooth}% -\label{sec:bluetooth} - -\begin{pkgtable} - \texttt{extra} & \texttt{bluez bluez-utils pulseaudio-bluetooth} \\ - \texttt{community} & \texttt{blueman} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> sudo lsmod | grep btusb -\end{minted} - - -After that we can enable and start the \mintinline{text}{bluetooth.service} service - -\begin{minted}{fish} -dustvoice in ~ -> sudo systemctl enable bluetooth.service - -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> 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}{fish} -(insert) [DustVoice]# list -(insert) [DustVoice]# select -\end{minted} - -After that, power on the controller - -\begin{minted}{fish} -(insert) [DustVoice]# power on -\end{minted} - -Now enter device discovery mode - -\begin{minted}{fish} -(insert) [DustVoice]# scan on -\end{minted} - -\noindent -and list found devices - -\begin{minted}{fish} -(insert) [DustVoice]# devices -\end{minted} - -\begin{NOTE} - You can turn device discovery mode off again, after your desired device has been found - - \begin{minted}{fish} -(insert) [DustVoice]# scan off - \end{minted} -\end{NOTE} - -Now turn on the agent - -\begin{minted}{fish} -(insert) [DustVoice]# agent on -\end{minted} - -\noindent -and pair with your device - -\begin{minted}{fish} -(insert) [DustVoice]# pair -\end{minted} - -\begin{NOTE} - If your device doesn’t support PIN verification you might need to manually trust the device - - \begin{minted}{fish} -(insert) [DustVoice]# trust - \end{minted} -\end{NOTE} - -Finally connect to your device - -\begin{minted}{fish} -(insert) [DustVoice]# connect -\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}{fish} -dustvoice in ~ -> pulseaudo --kill - -dustvoice in ~ -> 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{pkgtable} - \texttt{extra} & \texttt{ttf-hack xclip xorg xorg-drivers xorg-xinit} \\ - \texttt{community} & \texttt{arandr alacritty bspwm dmenu sxhkd} \\ - \texttt{AUR} & \texttt{polybar} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{nvidia nvidia-utils nvidia-settings opencl-nvidia} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> sudo nvidia-xconfig -\end{minted} - - -If you want to further tweak all settings available, you can use \texttt{nvidia-settings}. - -\begin{minted}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> 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+} to switch \texttt{tty}s. - -\subsubsection{The NVIDIA way}% -\label{sec:the-nvidia-way} - -\begin{pkgtable} - \texttt{community} & \texttt{bbswitch} \\ - \texttt{AUR} & \texttt{nvidia-xrun} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{AUR} & \texttt{nvidia-xrun-pm} \\ - \end{pkgtable} - - 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}{fish} -dustvoice in ~ -> lsmod | grep nvidia -\end{minted} - - -\noindent -and - -\begin{minted}{fish} -dustvoice in ~ -> 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}{fish} -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{fish} software}% -\label{sec:additional-fish-software} - -Software that is useful in combination with a \texttt{fish}. - -\subsection{\texttt{tmux}}% -\label{sec:tmux} - -\begin{pkgtable} - \texttt{community} & \texttt{tmux} \\ -\end{pkgtable} - -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:fish-communication} - -Life is all about communicating. -Here are some pieces of software to do exactly that. - -\subsubsection{\texttt{weechat}}% -\label{sec:weechat} - -\begin{pkgtable} - \texttt{community} & \texttt{weechat} \\ -\end{pkgtable} - -\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}{fish} -dustvoice in ~ -> 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 - \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:fish-pdf-viewer} - -\begin{pkgtable} - \texttt{extra} & \texttt{ghostscript} \\ - \texttt{community} & \texttt{fbida} \\ -\end{pkgtable} - -To use \texttt{asciidoctor-pdf}, you might be wondering how you are supposed to open the generated PDFs from the native linux fish. - -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}{fish} -dustvoice in ~ -> 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{fish} 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{pkgtable} - \texttt{extra} & \texttt{python} \\ -\end{pkgtable} - -Python has become really important for a magnitude of use cases. - -\subsection{\texttt{ruby} \& \texttt{asciidoctor}}% -\label{sec:ruby-and-asciidoctor} - -\begin{pkgtable} - \texttt{extra} & \texttt{ruby rubygems} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> gem install pygments.rb - \end{minted} - - - \item \texttt{rouge} which is a native \texttt{ruby} gem - - \begin{minted}{fish} -dustvoice in ~ -> 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{fish}{> source} the \mintinline{text}{.zshenv} file to make the changes take effect immediately - - \begin{minted}{fish} -dustvoice in ~ -> 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+=("$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}{fish} -dustvoice in ~ -> git clone https://github.com/WeAreROLI/JUCE.git - -dustvoice in ~ -> cd JUCE - -dustvoice in ~/JUCE -> git checkout develop - -dustvoice in ~/JUCE -> cd .. - -dustvoice in ~ -> git clone https://github.com/McMartin/FRUT.git -\end{minted} - - -\subsubsection{Using \texttt{JUCE}}% -\label{sec:using-juce} - -\begin{pkgtable} - \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{pkgtable} - -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{pkgtable} - \texttt{community} & \texttt{astyle} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{doxygen} \\ -\end{pkgtable} - -To generate a documentation from source code, I mostly use \texttt{doxygen} - -\subsubsection{Build tools}% -\label{sec:build-tools} - -\begin{pkgtable} - \texttt{community} & \texttt{ninja} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{gvfs-mtp libmtp} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{AUR} & \texttt{simple-mtpfs} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> simple-mtpfs -l - -dustvoice in ~ -> mkdir ~/mnt - -dustvoice in ~ -> simple-mtpfs --device ~/mnt -allow_other -\end{minted} - - -\noindent -and respectively unmount it - -\begin{minted}{fish} -dustvoice in ~ -> fusermount -u mnt - -dustvoice in ~ -> rmdir mnt -\end{minted} - - -\subsubsection{\texttt{adb}}% -\label{sec:adb} - -\begin{pkgtable} - \texttt{community} & \texttt{android-tools} \\ -\end{pkgtable} - -Kill the \texttt{adb} server, if it is running - -\begin{minted}{fish} -dustvoice in ~ -> adb kill-server -\end{minted} - - -\begin{NOTE} - If the server is currently not running, \mintinline{fish}{> 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}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> adb devices -\end{minted} - - -Now you can \texttt{push}/\texttt{pull} files. - -\begin{minted}{fish} -dustvoice in ~ -> adb pull /storage/emulated/0/DCIM/Camera/IMG.jpg . - -dustvoice in ~ -> adb push IMG.jpg /storage/emulated/0/DCIM/Camera/IMG2.jpg - -dustvoice in ~ -> 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{pkgtable} - \texttt{extra} & \texttt{gparted parted} \\ -\end{pkgtable} - -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{fish} equivalent \texttt{parted}. - -\subsection{PDF viewer}% -\label{sec:gui-pdf-viewer} - -\begin{pkgtable} - \texttt{extra} & \texttt{evince} \\ - \texttt{community} & \texttt{zathura zathura-pdf-mupdf} \\ -\end{pkgtable} - -To use \texttt{asciidoctor-pdf}, you might be wondering how you are supposed to open the generated PDFs using the GUI.\@ - -The software \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{pkgtable} - \texttt{extra} & \texttt{htop xfce4-taskmanager} \\ -\end{pkgtable} - -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:fish-video-software} - -Just some additional software related to videos. - -\subsubsection{Live streaming a terminal session}% -\label{sec:live-streaming-a-terminal-session} - -\begin{pkgtable} - \texttt{community} & \texttt{tmate} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{community} & \texttt{xsecurelock xss-lock} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> xss-lock -l -- xsecurelock & - \end{minted} - -\end{IMPORTANT} - -\subsection{\texttt{xfce-polkit\texorpdfstring{\textsuperscript{AUR}}{ (AUR)}}}% -\label{sec:xfce-polkit-aur} - -\begin{pkgtable} - \texttt{AUR} & \texttt{xfce-polkit} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{nitrogen} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{community} & \texttt{picom} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> killall picom - \end{minted} - - - \noindent - or - - \begin{minted}{fish} -dustvoice in ~ -> ps aux | grep picom - -dustvoice in ~ -> kill -9 - \end{minted} - -\end{WARNING} - -\subsection{\texttt{networkmanager} applet}% -\label{sec:networkmanager-applet} - -\begin{pkgtable} - \texttt{extra} & \texttt{network-manager-applet} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> nm-applet & -\end{minted} - - -If you want to edit the network connections with a more full screen approach, you can also launch \mintinline{fish}{> 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{pkgtable} - \texttt{AUR} & \texttt{xkblayout-state} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{xclip} \\ -\end{pkgtable} - -To copy something from the terminal to the \texttt{xorg} clipboard, use \texttt{xclip} - -\subsection{Taking screen shots}% -\label{sec:taking-screen-shots} - -\begin{pkgtable} - \texttt{community} & \texttt{scrot} \\ -\end{pkgtable} - -For this functionality, especially in combination with \texttt{rofi}, use \texttt{scrot}. - -\mintinline{fish}{> scrot $HOME/Pictures/filename.png} then saves the screen shot under \mintinline{text}{$HOME/Pictures/filename.png}. - -\subsection{Image viewer}% -\label{sec:image-viewer} - -\begin{pkgtable} - \texttt{extra} & \texttt{ristretto} \\ -\end{pkgtable} - -Now that we can create screen shots, we might also want to view those - -\begin{minted}{fish} -dustvoice in ~ -> ristretto filename.png -\end{minted} - - -\subsection{File manager}% -\label{sec:file-manager} - -\begin{pkgtable} - \texttt{extra} & \texttt{gvfs thunar} \\ - \texttt{AUR} & \texttt{gigolo} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{cpio unrar unzip zip} \\ - \texttt{community} & \texttt{xarchiver} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{firefox firefox-i18n-en-us} \\ - \texttt{community} & \texttt{browserpass} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> cd /usr/lib/browserpass - -dustvoice in /usr/lib/browserpass -> make hosts-firefox-user - -dustvoice in /usr/lib/browserpass -> cd ~ -\end{minted} - - -\subsubsection{Entering the dark side}% -\label{sec:entering-the-dark-side} - -\begin{pkgtable} - \texttt{AUR} & \texttt{tor-browser} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{libreoffice-fresh} \\ -\end{pkgtable} - -I’ll use \texttt{libreoffice-fresh} for anything that I’m not able to do with \texttt{neovim}. - -\subsubsection{Printing}% -\label{sec:printing} - -\begin{pkgtable} - \texttt{extra} & \texttt{avahi cups cups-pdf nss-mdns print-manager system-config-printer} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> sudo systemctl enable avahi-daemon.service - -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> avahi-browse --all --ignore-local --resolve --terminate - -dustvoice in ~ -> sudo systemctl enable org.cups.cupsd.service - -dustvoice in ~ -> 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{pkgtable} - \texttt{extra} & \texttt{thunderbird} \\ -\end{pkgtable} - -There is nothing better than some classical email. - -\subsubsection{Telegram}% -\label{sec:telegram} - -\begin{pkgtable} - \texttt{community} & \texttt{telegram-desktop} \\ -\end{pkgtable} - -You want to have your \texttt{telegram} messages on your desktop PC?\@ - -\subsubsection{TeamSpeak 3}% -\label{sec:teamspeak-3} - -\begin{pkgtable} - \texttt{community} & \texttt{teamspeak3} \\ -\end{pkgtable} - -Wanna chat with your gaming friends and they have a \texttt{teamspeak3} server? - -\subsubsection{Discord}% -\label{sec:discord} - -\begin{pkgtable} - \texttt{community} & \texttt{discord} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{vlc} \\ -\end{pkgtable} - -You might consider using \texttt{vlc} - -\subsubsection{Creating video}% -\label{sec:creating-video} - -\begin{pkgtable} - \texttt{AUR} & \texttt{obs-linuxbrowser-bin obs-glcapture-git obs-studio-git} \\ -\end{pkgtable} - -\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{pkgtable} - \texttt{AUR} & \texttt{screenkey} \\ -\end{pkgtable} - -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{fish}{> screenkey-obs} alias for you to run with \texttt{zsh}. - -\end{NOTE} - -\subsubsection{Editing video}% -\label{sec:editing-video} - -\begin{pkgtable} - \texttt{AUR} & \texttt{davinci-resolve} \\ -\end{pkgtable} - -In my case, I’m using \texttt{davinci-resolve\textsuperscript{\texttt{AUR}}}. - -\subsubsection{Utilizing video}% -\label{sec:utilizing-video} - -\begin{pkgtable} - \texttt{AUR} & \texttt{teamviewer} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{community} & \texttt{ardour} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{ffmpeg} \\ - \end{pkgtable} - - 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}{fish} -dustvoice in ~ -> 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{pkgtable} - \texttt{AUR} & \texttt{reaper-bin} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{community} & \texttt{virtualbox virtualbox-host-modules-arch} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> sudo modprobe vboxdrv -\end{minted} - - -\noindent -and add the user which is supposed to run \mintinline{fish}{> virtualbox} to the \texttt{vboxusers} group - -\begin{minted}{fish} -dustvoice in ~ -> 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}{fish} -dustvoice in ~ -> sudo usermod -a G disk $USER -\end{minted} - - -Now just re-login and you’re good to go. - -\subsection{Gaming}% -\label{sec:gaming} - -\begin{pkgtable} - \texttt{extra} & \texttt{pulseaudio pulseaudio-alsa} \\ - \texttt{community} & \texttt{lutris} \\ - \texttt{multilib} & \texttt{lib32-libpulse lib32-nvidia-utils steam} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{libwacom xf86-input-wacom} \\ -\end{pkgtable} - -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{pkgtable} - \texttt{extra} & \texttt{libvncserver} \\ - \texttt{community} & \texttt{remmina} \\ - \texttt{AUR} & \texttt{freerdp} \\ -\end{pkgtable} - -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}{fish} -dustvoice in ~ -> 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{fish}{> 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 fish}, then double check that the issue really is the not perfectly executed kernel update by issuing - -\begin{minted}{fish} -root in ~ -> uname -a -\end{minted} - - -\noindent -and - -\begin{minted}{fish} -root in ~ -> 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}{fish} -root in ~ -> 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}{fish} -root in ~ -> umount /boot -\end{minted} - - -Now \texttt{cd} into \texttt{pacman}'s package cache - -\begin{minted}{fish} -root in ~ -> cd /var/cache/pacman/pkg -\end{minted} - - -There should be a file located named something like \mintinline{text}{linux-.pkg.tar.xz}, where \texttt{} would be somewhat equivalent to the previously noted version number - -Now downgrade the \texttt{linux} package - -\begin{minted}{fish} -root in ~ -> pacman -U linux-.pkg.tar.xz -\end{minted} - - -After that remove the possibly created \mintinline{text}{/boot} directory - -\begin{minted}{fish} -root in ~ -> rm -rf /boot - -root in ~ -> mkdir /boot -\end{minted} - - -Now reboot and mount the \texttt{boot} partition, in my case an EFI System partition. - -Now simply rerun - -\begin{minted}{fish} -dustvoice in ~ -> 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} - -% Local Variables: -% TeX-engine: luatex -% TeX-command-extra-options: "--shell-escape" -% End: diff --git a/DustArch.org b/DustArch.org deleted file mode 100644 index 001272c..0000000 --- a/DustArch.org +++ /dev/null @@ -1,3353 +0,0 @@ -#+title: DustArch -#+subtitle: DustVoice's Arch Linux from scratch -#+author: David Holland -#+html_doctype: xhtml5 -#+options: html5-fancy -#+options: H:4 num:4 -#+options: toc:t -#+language: en - -#+latex_class: dustdoc -#+latex_compiler: lualatex - -#+begin_export html - -#+end_export - -* 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 -(=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 =archiso= doesn't have all packages available from cache, especially the ones that need to be installed from the =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 [[https://wiki.archlinux.org/][ArchWiki]], or the [[https://bbs.archlinux.org/][Arch Linux forums]]. -#+end_NOTE - -In the following document, I will denote a command execution in a shell with a preceding ~>~:\\ -(~> uname -a~). - -In a shell session block, you can infer the privilege the command was executed by looking at the prompt line above the command, where the =root= username will be denoted if it's an elevated shell, in any case together with the current working directory - -#+begin_src fish -~ -> git init - -root in /boot -> ls -la -#+end_src - -** Syncing up =pacman= - -First of all we need to sync up =pacman='s package repository, in order to be able to install the latest, as well as new packages to the =archiso= and our new system. - -#+begin_src fish -> pacman -Sy -#+end_src - -#+begin_WARNING -Using ~> pacman -Sy~ should be sufficient, in order to be able to search for packages from within the =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 ~> pacman -Syu~ instead! - -=pacstrap= uses the latest packages anyways. -#+end_WARNING - -*** Official repositories -After doing that, we can now install any software from the official repositories by issuing - -#+begin_src fish -root in / -> pacman -S -#+end_src - -where you would replace == with the actual package name. - -If you want to remove an installed package, just use - -#+begin_src fish -root in / -> pacman -Rsu -#+end_src - -If you don't know the exact package name, or if you just want to search for a keyword, for example =xfce=, to list all packages having something to do with =xfce=, use - -#+begin_src fish -root in / -> pacman -Ss -#+end_src - -If you really need to force remove a package, which you should use /with extreme caution/, you could use - -#+begin_src fish -root in / -> pacman -Rdd -#+end_src - -*** =AUR= -If you want to install a package from the [[https://aur.archlinux.org/][AUR]], I would advise proceeding in the following manner, in order to install the =AUR=-helper [[https://aur.archlinux.org/packages/paru][paru]]. - -1. Clone the package with =git= - - #+begin_src fish - ~ - > git clone https://aur.archlinux.org/paru.git - #+end_src - - If you are on a slow PC, or don't want to compile =paru= from scratch, you can also use [[https://aur.archlinux.org/packages/paru-bin][paru-bin]]. - -2. Switch to the package directory - - #+begin_src fish - ~ - > cd paru - #+end_src - -3. Execute ~> makepkg~ - - #+begin_src fish - ~/paru - > makepkg -si - #+end_src - -4. Delete all files created, as =paru= will now be handling all the - =AUR= stuff. - - #+begin_src fish - ~/paru - > cd .. - - ~ - > rm -rf paru - #+end_src - -If you only install =AUR= packages the manual way, you might have to resolve some =AUR= dependencies manually, which can't be automatically resolved by =makepkg='s =-s= option, which uses =pacman=. - -In order to install a desired =AUR= package, you /must/ switch to your normal, non-=root= user, because =makepkg= doesn't run as =root=. - -*** Software categories -In this guide, software is categorized in three different categories - -- =Console= software is intended to be used with either the native linux console, or with a terminal emulator - -- =GUI= software is intended to be used within a graphical desktop environment - -- =Hybrid= software can either be used within both a console and a graphical desktop environment (e.g. =networkmanager=), or there are packages available for both a console and a graphical desktop environment (e.g. =pulseaudio= with =pulsemixer= for =Console= and =pavucontrol= for =GUI=) - -*** 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 - -- clearly see what packages get installed / need to be installed in a specific section - -- install packages before you start with the section in order to minimize waiting time - -The packages are always the recommended packages. - -For further clarification for specific packages (e.g. =UEFI= specific packages), continue reading the section, as there is most certainly an explanation or follow-up section there. - -Of course, as always, you can and *should* adapt everything according to your needs, as this guide is, again, /no tutorial, but a guide/. - -**** Example section -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|---------------+---------+----------------+----------| -| libutil-linux | git | ardour | sbupdate | -| | | cadence | | -| | | jsampler | | -| | | linuxsampler | | -| | | qsampler | | -| | | sample-package | | - -You have to configure =sample-package=, by editing ~/etc/sample.conf~ - -#+begin_src txt -Sample.text=useful -#+end_src -#+begin_center -~/etc/sample.conf~ -#+end_center - -** Formatting the drive -First, you probably want to get a list of all available drives, together with their corresponding device name, by issuing - -#+begin_src fish -root in / -> fdisk -l -#+end_src - -The output of ~> fdisk -l~ is dependent on your system configuration and many other factors, like =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 - -*** The standard way -In my case, the partition I want to install the root file system on will be ~/dev/mapper/DustPortable~, which is an unlocked =luks2= volume which will be located on ~/dev/sda2~. For my =swap=, I will use a swapfile. - -#+begin_NOTE -A =swap= size twice the size of your RAM is recommended by a lot of people. - -To be exact, every distribution has different recommendations for =swap= sizes. Also =swap= size heavily depends on whether you want to be able to hibernate, etc. -#+end_NOTE - -**** In my opinion -You should make the =swap= size at least your RAM size and for RAM sizes over =4GB= with the intention to hibernate, at least one and a half times your RAM size. - -If you haven't yet partitioned your disk, please refer to the [[https://wiki.archlinux.org/index.php/Partitioning][general partitioning tutorial]] in the ArchWiki. - -*** Full system encryption - -#+begin_NOTE -This is only one way to do it (read: it is the way I have previously done it). -#+end_NOTE - -I'm using a =LUKS= setup, with =btrfs= and =luks2=. -For more information look into the [[https://wiki.archlinux.org/][ArchWiki]]. - -This setup has different partitions, used for the EFI System partition, =root= partition, etc. compared to the ones used in the rest of the guide. -The only part of the guide, which currently uses the drives & partitions used in this section is [[*The manual way]]. - -To start things, we first have to decide, which disk, or partition, is going to be =luks2= encrypted. - -In my case I'll be using my SSD in an USB-C enclosure to be ablet to take the system with me on the go. -For that I will use a =GPT= partition scheme. -I will then create a ~2 GiB~ EFI System partition (I have multiple kernels installed at a time), in my case ~/dev/sda1~, defined as a =EFI System= partition type in =gdisk=, as well as the main =luks2= volume, in my case ~/dev/sda2~, defined as a =Linux filesystem= partition type in =gdisk=. - -After partitioning our disk, we now have to set everything up. - -**** EFI System partition - -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|------------+---------+-------------+-------| -| dosfstools | | | | - -I won't setup my EFI System partition with =cryptsetup=, as it makes no sense in my case. - -Every =EFI= binary (or =STUB=) will have to be signed with my custom Secure Boot keys, as described in [[*The manual way]], so tempering with the EFI System partition poses no risk to my system. - -Instead I will simply format it with a =FAT32= filesystem - -#+begin_src fish -root in / -> mkfs.fat -F 32 -n EFI /dev/sda1 -#+end_src - -We will bother with mounting it later on. - -When you /do/ want to encrypt your EFI System partition, in conjunction with e.g. =grub=, please either use =LUKS 1=, or make sure to have the latest version of =grub= installed on your system, to make it work with =LUKS 2=! -I will use =limine= though, so for me all of this isn't a consideration. - -**** =LUKS= - -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|------------+---------+-------------+-------| -| cryptsetup | | | | - -First off we have to create the =LUKS= volume - -#+begin_src fish -root in / -> cryptsetup luksFormat --type luks2 /dev/sda2 -#+end_src - -In my case, I will convert the keyslot the *Password-Based Key Derivation Function* (pbkdf) =pbkdf2=, as =luks2= defaults to =argon2id=, which doesn't play well with my portable setup, namely the differing RAM sizes. - -#+begin_src fish -root in / -> cryptsetup luksConvertKey --pbkdf pbkdf2 /dev/sda2 -#+end_src - -After that we have to open the volume - -#+begin_src fish -root in / -> cryptsetup open /dev/sda2 DustPortable -#+end_src - -The volume is now accessible under =/dev/mapper/DustPortable=. - -**** =btrfs= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|-------------+---------+-------------+-------| -| btrfs-progs | | | | - -Fist off we need to create the filesystem - -#+begin_src fish -root in / -> mkfs.btrfs -L DustPortable /dev/mapper/DustPortable -#+end_src - -After that we mount the =btrfs= root under ~/mnt/meta~ - -#+begin_src fish -root in / -> mkdir /mnt/meta - -root in / -> mount /dev/mapper/DustPortable /mnt/meta -#+end_src - -Now we create the desired filesystem layout. - -We will create 5 top level subvolumes that will be mounted at the appropriate places later on. - -#+begin_src fish -root in /mnt/meta -> btrfs subvolume create @ - -root in /mnt/meta -> btrfs subvolume create @home - -root in /mnt/meta -> btrfs subvolume create @snapshots - -root in /mnt/meta -> btrfs subvolume create @var_log - -root in /mnt/meta -> btrfs subvolume create @swapfile -#+end_src - -** Preparing the =chroot= environment -As a first step it might make sense to edit =/etc/pacman.d/mirrorlist= to move the mirrors geographically closest to you to the top. - -*** =pacstrap= in -Generally we need to =pacstrap= the /minimum packages/ needed. -We will install all other packages later on. - -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|----------------+---------+-------------+-------| -| base | | | | -| base-devel | | | | -| linux | | | | -| linux-firmware | | | | - -This is the actual command used in my case - -#+begin_src fish -root in / -> pacstrap /mnt/meta/@ base base-devel linux linux-firmware -#+end_src - -*** Mounting party -Now we have to mount the subvolumes and boot partition we created earlier to the appropriate locations. - -First off, we mount the =/= subvolume =@= - -#+begin_src fish -root in / -> mkdir /mnt/DustPortable - -root in / -> mount -o subvol=@ /dev/mapper/DustPortable /mnt/DustPortable -#+end_src - -Now we can mount the =/home= subvolume =@home= - -#+begin_src fish -root in /mnt/DustPortable -> mount -o subvol=@home /dev/mapper/DustPortable home -#+end_src - -The =/.snapshots= subvolume =@snapshots= closely follows - -#+begin_src fish -root in /mnt/DustPortable -> mkdir .snapshots - -root in /mnt/DustPortable -> mount -o subvol=@snapshots /dev/mapper/DustPortable .snapshots -#+end_src - -After that we have to move the log dir =/var/log= to the appropriate subvolume =@var_log= - -#+begin_src fish -root in /mnt/DustPortable -> mv var/log var/log_bak - -root in /mnt/DustPortable -> mount -o subvol=@var_log /dev/mapper/DustPortable var/log - -root in /mnt/DustPortable -> mkdir var/log - -root in /mnt/DustPortable -> mv var/log_bak/* var/log/ - -root in /mnt/DustPortable -> rmdir var/log_bak -#+end_src - -Finally we can generate the =swapfile= - -#+begin_src fish -root in /mnt/DustPortable -> mkdir swapfile - -root in /mnt/DustPortable -> mount -o subvol=@swapfile /dev/mapper/DustPortable swapfile - -root in /mnt/DustPortable -> btrfs filesystem mkswapfile --size 128G swapfile/swapfile - -root in /mnt/DustPortable -> swapon swapfile/swapfile -#+end_src - -#+begin_IMPORTANT -I use my SSD inside a USB-C enclosure (although it is rated at 40Gbps it is *not* Thunderbolt 3!), which means that it /doesn't/ support =TRIM=. -This is why I personally need to add =nodiscard= to every =mount= command option, which would look something along the lines of this - -#+begin_src fish -root in / -> mount -o subvol=@,nodiscard /dev/mapper/DustPortable /mnt/DustPortable -#+end_src -#+end_IMPORTANT - -The only thing left to do now is mounting the boot partition, namely my /EFI System Partition/ - -#+begin_src fish -root in /mnt/DustPortable -> mv boot boot_bak - -root in /mnt/DustPortable -> mkdir boot - -root in /mnt/DustPortable -> mount /dev/sda1 boot - -root in /mnt/DustPortable -> mv boot_bak/* boot/ - -root in /mnt/DustPortable -> rmdir boot_bak -#+end_src - -After that we can generate the ~/etc/fstab~ using =genfstab= - -#+begin_src fish -root in / -> genfstab -U /mnt/DustPortable >> /mnt/DustPortable/etc/fstab -#+end_src - -and you're ready to enter the =chroot= environment. - -*** Outdated =archiso= -If you're using an older version of the =archiso=, you might want to replace the mirrorlist present on the =archiso= with the newest [[https://archlinux.org/mirrorlist/all][online one]] - -#+begin_src fish -root in / -> curl https://archlinux.org/mirrorlist/all > /etc/pacman.d/mirrorlist -#+end_src - -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+-------| -| | | reflector | | - -The best way to do this tho, is using a package from the official repositories named =reflector=. -It comes with all sorts of options, for example sorting mirrors by speed, filtering by country, etc. - -#+begin_src fish -root in / -> reflector --verbose --latest 200 --sort rate --save /etc/pacman.d/mirrorlist -#+end_src - -After that you would need to reinstall the =pacman-mirror= package and -run - -#+begin_src fish -root in / -> pacman -Syyuu -#+end_src - -for best results. - -#+begin_CAUTION -Be wary though as there could arise keyring issues etc. -Normally the =pacstrap= command takes care of syncing everything etc. -#+end_CAUTION - -*** Living behind a proxy -If you're sitting behind a proxy, you're generally in for an unpleasant time. -Generally you need to set the =http_proxy=, =https_proxy=, =ftp_proxy= variables as well as their *upper case* counterparts. - -#+begin_src fish -root in / -> export http_proxy="http://ldiproxy.lsjv.rlp.de:8080" - -root in / -> export https_proxy=$http_proxy - -root in / -> export ftp_proxy=$http_proxy - -root in / -> export HTTP_PROXY=$http_proxy - -root in / -> export HTTPS_PROXY=$http_proxy - -root in / -> export FTP_PROXY=$http_proxy -#+end_src - -If you can't =pacstrap= after that, you probaby have the issue thatthe =systemd-timesyncd=, as well as =pacman-init= service didn't execute correctly. - -#+begin_src fish -root in / -> systemctl status systemd-timesyncd.service - -root in / -> systemctl status pacman-init.service -#+end_src - -To mitigate this, you need to initialize =pacman= yourself. - -First off check whether the correct time is set. - -#+begin_src fish -root in / -> timedatectl -#+end_src - -In my case the time zone was not correctly set, why my time was off by one hour, so I had to set it manually. - -#+begin_src fish -root in / -> timedatectl set-timezone Europe/Berli -#+end_src - -After that we have to execute the =pacman-init= stuff manually - -#+begin_src fish -root in / -> pacman-key --init - -root in / -> pacman-key --populate -#+end_src - -#+begin_NOTE -You might also want to add the following lines to ~/etc/sudoers~, in order to keep the proxy environment variables alive when executing a command through =sudo= - -#+begin_src txt -Defaults env_keep += "http_proxy" -Defaults env_keep += "https_proxy" -Defaults env_keep += "ftp_proxy" -Defaults env_keep += "HTTP_PROXY" -Defaults env_keep += "HTTPS_PROXY" -Defaults env_keep += "FTP_PROXY" -#+end_src -#+begin_center -~/etc/sudoers~ -#+end_center -#+end_NOTE - -* Entering the =chroot= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+----------------------+-------------+-------| -| | arch-install-scripts | | | - -#+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 =chroot=. - -That's why we are using =arch-chroot=, provided by the =arch-install-scripts= package, which is shipped with the =archiso=. This script takes care of all the afforementioned stuff, so we can set up our system properly. -#+end_NOTE - -#+begin_src fish -root in / -> arch-chroot /mnt/DustPortable -#+end_src - -Et Voilà! You successfully =chroot=-ed inside your new system and you'll be greeted by a =bash= prompt, which is the default shell on fresh Arch Linux installations. - -** Installing additional packages -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|------------------+----------------------------+-------------+--------| -| amd-ucode | efitools | fish | limine | -| base-devel | git | neovim | | -| btrfs-progs | intel-ucode | | | -| diffutils | networkmanager | | | -| dmraid | networkmanager-openconnect | | | -| dnsmasq | networkmanager-openvpn | | | -| dosfstools | parted | | | -| efibootmgr | polkit | | | -| emacs-nativecomp | rsync | | | -| exfat-utils | zsh | | | -| iputils | | | | -| linux-headers | | | | -| openssh | | | | -| sudo | | | | -| usbutils | | | | - -There are many command line text editors available, like =nano=, =vi=, -=vim=, =emacs=, etc. - -I'll be using =neovim= as my simple text editor, until a certain point, at which I'll replace it with my doom-=emacs= setup, though it shouldn't matter what editor you choose for the rest of the guide. - -Make sure to enable the =NetworkManager.service= service, in order for the Internet connection to work correctly, upon booting into the fresh system later on. - -#+begin_src fish -root in / -> systemctl enable NetworkManager.service -#+end_src - -With =polkit= installed, create a file to enable users of the =network= group to add new networks without the need of =sudo=. - -#+begin_src txt -polkit.addRule(function(action, subject) { - if (action.id.indexOf("org.freedesktop.NetworkManager.") == 0 && subject.isInGroup("network")) { - return polkit.Result.YES; - } -}); -#+end_src -#+begin_center -~/etc/polkit-1/rules.d/50-org.freedesktop.NetworkManager.rules~ -#+end_center - -If you use =UEFI=, you'll also need the =efibootmgr=, in order to modify the =UEFI= entries. - -*** Additional kernels -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|-------------------+------------------------+-------------+-------| -| linux-lts | linux-hardened | | | -| linux-lts-headers | linux-hardened-headers | | | -| linux-zen | | | | -| linux-zen-headers | | | | - -In addition to the standard =linux= kernel, there are a couple of different options out there. -Just to name a few, there is =linux-lts=, =linux-zen= and =linux-hardened=. - -You can simply install them and then add the corresponding =initramfs= and kernel image to your bootloader entries. - -Make sure you have allocated enough space on your /EFI System Partition/ though. - -** 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 ~/usr/share/zoneinfo~. - -In my case, my timezone file resides under ~/usr/share/zoneinfo/Europe/Berlin~. - -To achieve the desired result, I will want to symlink this to ~/etc/localtime~ and set the hardware clock. - -#+begin_src fish -root in / -> ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime - -root in / -> hwclock --systohc --utc -#+end_src - -Now you can also enable time synchronization over network - -#+begin_src fish -root in / -> timedatectl set-timezone Europe/Berlin - -root in / -> timedatectl set-ntp true -#+end_src - -and check that everything is alright - -#+begin_src fish -root in / -> timedatectl status -#+end_src - -** Master of locales -Now you have to generate your locale information. - -For that you have to edit =/etc/locale.gen= and uncomment the locales -you want to enable. - -I recommend to always uncomment =en_US.UTF-8 UTF8=, even if you want to -use another language primarily. - -In my case I only uncommented the =en_US.UTF-8 UTF8= line - -#+begin_src fish -en_US.UTF-8 UTF8 -#+end_src - -After that you still have to actually generate the locales by issuing - -#+begin_src fish -root in / -> locale-gen -#+end_src - -and set the locale - -#+begin_src fish -root in / -> localectl set-locale LANG="en_US.UTF-8" -#+end_src - -After that we're done with this part. - -** Naming your machine -Now we can set the =hostname= for our new install and add =hosts= entries. - -Apart from being mentioned in your command prompt, the =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. - -*** =hostname= -To change the =hostname=, simply edit =/etc/hostname=, enter the desired name, then save and quit - -#+begin_src fish -DustArch -#+end_src - -*** =hosts= -Now we need to specify some =hosts= entries by editing =/etc/hosts= - -#+begin_src fish -# 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_src - -** User setup -Now you should probably change the default =root= password and create a new non-=root= user for yourself, as using your new system purely through the native =root= user is not recommended from a security standpoint. - -*** Give =root= a password -To change the password for the current user (the =root= user) issue - -#+begin_src fish -root in / -> passwd -#+end_src - -and choose a new password. - -*** Create a personal user -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+-------| -| sudo | | | | -| bash | | | | - -We are going to create a new user and set the password, groups and shell for this user - -#+begin_src fish -root in / -> useradd -m -p "" -G "adm,audio,disk,floppy,kvm,log,lp,network,rfkill,scanner,storage,users,optical,power,wheel" -s /bin/bash dustvoice - -root in / -> passwd dustvoice -#+end_src - -We now have to allow the =wheel= group =sudo= access. - -For that we edit =/etc/sudoers= and uncomment the =%wheel= line. - -#+begin_src fish -%wheel ALL=(ALL) ALL -#+end_src - -You could also add a new line below the =root= line - -#+begin_src fish -root ALL=(ALL) ALL -#+end_src - -with your new username - -#+begin_src fish -dustvoice ALL=(ALL) ALL -#+end_src - -to solely grant the /new/ user =sudo= privileges. - -** Boot manager -In this section different boot managers / boot methods are explained. - -*** =EFISTUB= - -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|------------+---------+-------------+-------| -| efibootmgr | | | | - -You can directly boot the system, by making use of the =EFISTUB= contained in the kernel image. To utilize this, we can use =efibootmgr= to create an entry in the =UEFI= - -#+begin_src fish -root in / -> 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_src - -This only makes sense of course, if you're using =UEFI= instead of a legacy =BIOS=. In this case it doesn't matter of course, if your machine /theoretically supports/ =UEFI=, but rather if it is the /enabled mode/! - -*** =grub= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|------------+---------+-------------+-------| -| dosfstools | mtools | os-prober | | -| efibootmgr | | | | -| grub | | | | - -Of course you can also use a boot manager to boot the system, as the name implies. - -If I can't use =EFISTUB=, e.g. either because the system has no =UEFI= support, or because I need another feature of a boot manager, I could use =grub=. - -#+begin_TIP -Currently, I mainly use =limine= as a boot manager *especially* on my portable setup, as =grub= is *such a huge pain in the butt!* - -=limine= is insanely easy to setup and configure, without all the =BIOS Boot partition= crap that I find myself mainly using this. -Refer to [[*=limine=]] for further information. -#+end_TIP - -#+begin_NOTE -You'll probably only need the =efibootmgr= package, if you plan to utilize =UEFI=. -#+end_NOTE - -**** =grub= - =BIOS= -If you chose the =BIOS - MBR= variation, you'll have to /do nothing special/. - -If you chose the =BIOS - GPT= variation, you'll have to /have a =+1M= boot partition/ created with the partition type set to =BIOS boot=. - -In both cases you'll have to /run the following comman/ now - -#+begin_src fish -root in / -> grub-install --target=i386-pc /dev/sdb -#+end_src - -It should obvious that you would need to replace =/dev/sdb= with the disk you actually want to use. Note however that you have to specify a /disk/ and /not a partition/, so /no number/. - -**** =grub= - =UEFI= -If you chose the =UEFI - GPT= variation, you'll have to /have the EFI System partition mounted/ at =/boot= (where =/dev/sda2= is the partition holding said EFI System partition in my particular setup) - -Now /install =grub= to the EFI System partition/ - -#+begin_src fish -root in / -> grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=grub --recheck -#+end_src - -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 =cmd= window as Administrator and type in - -#+begin_src fish -bcdedit /set {bootmgr} path \EFI\grub\grubx64.efi -#+end_src - -To make sure that the path is correct, you can use - -#+begin_src fish -root in / -> ls /boot/EFI/grub -#+end_src - -under Linux to make sure, that the =grubx64.efi= file is really there. - -**** =grub= config -In all cases, you now have to create the main =grub.cfg= configuration file. - -But before we actually generate it, we'll make some changes to the default =grub= settings, which the =grub.cfg= will be generated from. - -***** Adjust the timeout -First of all, I want my =grub= menu to wait indefinitely for my command to boot an OS. - -#+begin_src txt -GRUB_TIMEOUT=-1 -#+end_src -#+begin_center -~/etc/default/grub~ -#+end_center - -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 =grub= menu. - -Of course you can set this parameter to whatever you want. - -Another way of achieving what I described, would be to make =grub= remember the last selection. - -#+begin_src txt -GRUB_TIMEOUT=5 -GRUB_DEFAULT=saved -GRUB_SAVEDEFAULT="true" -#+end_src -#+begin_center -~/etc/default/grub~ -#+end_center - -***** 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_src txt -GRUB_DISABLE_RECOVERY=false -#+end_src -#+begin_center -~/etc/default/grub~ -#+end_center - -***** NVIDIA fix -Now, as I'm using the binary NVIDIA driver for my graphics card, I also want to make sure, to revert =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_src txt -GRUB_GFXPAYLOAD_LINUX=text -#+end_src -#+begin_center -~/etc/default/grub~ -#+end_center - -***** 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 =grub= menu. - -#+begin_src fish -menuentry '=> Shutdown' { - halt -} - -menuentry '=> Reboot' { - reboot -} -#+end_src - -***** Installing =memtest= -As I want all possible options to possibly troubleshoot my PC right there in my =grub= menu, without the need to boot into a live OS, I also want to have a memory tester there. - -****** =BIOS= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+------------+-------------+-------| -| | memtest86+ | | | - -For a =BIOS= setup, you'll simply need to install the =memtest86+= package, with no further configuration. - -****** =UEFI= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+---------------| -| | | | memtest86-efi | - -For a =UEFI= setup, you'll first need to install the package and then tell =memtest86-efi= ^{=AUR=} how to install itself - -#+begin_src fish -root in / -> memtest86-efi -i -#+end_src - -Now select option 3, to install it as a =grub2= menu item. - -***** Enabling hibernation -We need to add the =resume= kernel parameter to =/etc/default/grub=, containing my =swap= partition =UUID=, in my case - -#+begin_src txt -GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=097c6f11-f246-40eb-a702-ba83c92654f2" -#+end_src -#+begin_center -~/etc/default/grub~ -#+end_center - -If you have to change anything, like the =swap= partition =UUID=, inside the =grub= configuration files, you'll always have to rerun ~> grub-mkconfig~ as explained in the paragraph of the section . - -***** Disabling =os-prober= -Sometimes it makes sense to disable the =os-prober= functionality of grub, even though =os-prober= is installed on the system (which auto enables it), for example when installing arch for portability purposes. We can disable the os-prober functionality in the =grub= default config file. - -#+begin_src txt -GRUB_DISABLE_OS_PROBER=true -#+end_src -#+begin_center -~/etc/default/grub~ -#+end_center - -***** Generating the =grub= config -Now we can finally generate our =grub.cfg= - -#+begin_src fish -root in / -> grub-mkconfig -o /boot/grub/grub.cfg -#+end_src - -Now you're good to boot into your new system. -*** =limine= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+--------| -| | | | limine | - -#+begin_TIP -You will have to switch to your normal user to install the =AUR= package. - -If you're at it though, you could also already install =paru=, to make things easier. - -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+----------+-------------+----------| -| | asp | bat | paru-bin | -| | devtools | | | - -#+begin_src fish -root in / -> su dustvoice - -~ -> git clone https://aur.archlinux.org/paru-bin.git - -~/paru-bin -> makepkg -si - -~ -> rm -rf paru-bin -#+end_src -#+end_TIP - -**** =Hybrid= -To be able to boot from a =BIOS=, as well as a =UEFI= system, simply follow both of these guides. - -**** =BIOS= -For installing =limine= on a =BIOS= system, you first need to copy ~/usr/share/limine/limine.sys~ (which replaces the need for a boot partition, like =grub= uses it) to a ~/~ or ~/boot~ directory of any partition on the disk you want to try and boot from. - -#+begin_src fish -root in / -> cp /usr/share/limine/limine.sys /boot/ -#+end_src - -After that deploy =limine= using =limine-deploy= - -#+begin_src fish -root in / -> limine-deploy /dev/sda -#+end_src - -#+begin_NOTE -Don't specify any partition number when using the =limine-deploy=! -#+end_NOTE - -**** =UEFI= -Simply copy ~/usr/share/limine/BOOTX64.EFI~ to the appropriate location on your /EFI System Partition/ - -#+begin_src fish -root in / -> mkdir -p /boot/EFI/BOOT - -root in / -> cp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT/ -#+end_src - -#+begin_NOTE -In case you're using the [[*Secure Boot][Secure Boot]] method described in [[*=PreLoader=]], you would need to name it ~loader.efi~, as the =PreLoader= takes the place of the =BOOTX64.EFI= which gets auto started by most =UEFI= systems. -#+end_NOTE - -**** config -The only thing left to do is to create a ~limine.cfg~ file with all your desired boot entries in it. - -#+begin_NOTE -I usually have multiple kernels installed at a time, which is why my config file is so big. -Note that I will intall the kernels at a later time, but already specify them as boot entries. -Therefore don't be suprised if those boot entries in turn won't work yet! -#+end_NOTE - -***** Kernel =cmdline= -First off we'll define a variable which we then use throughout our boot entries, in order to reduce complexity and redundancy and increase readability. - -#+begin_NOTE -You need to replace the =[...]= part with the appropriate values for your system. - -For =[1]= the command to get the "physical" offset of the =swapfile= on =btrfs= is - -#+begin_src fish -root in / -> btrfs inspect-internal map-swapfile -r swapfile/swapfile -#+end_src - -For =[2]=, getting the =UUID= of the =LUKS= volume is achieved by using =blkid=. -#+end_NOTE - -#+begin_src txt -${root_device}=root=/dev/mapper/DustPortable rw rootflags=subvol=@ resume=/dev/mapper/DustPortable resume_offset=[1] cryptdevice=UUID=[2]:DustPortable -#+end_src -#+begin_center -~/boot/limine.cfg~ -#+end_center - -***** =limine= options -Next we configure some options for =limine= - -#+begin_src txt -TIMEOUT=no -INTERFACE_BRANDING=DustPortable -#+end_src -#+begin_center -~/boot/limine.cfg~ -#+end_center - -***** Boot entries -Finally we can specify our boot entries - -#+begin_src txt -:Arch Linux - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux.img - -:Arch Linux (Zen) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-zen -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-zen.img - -:Arch Linux (LTS) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-lts -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-lts.img - -:Arch Linux (Hardened) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-hardened -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-hardened.img - -:Arch Linux (fallback initramfs) - -::Arch Linux - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-fallback.img - -::Arch Linux (Zen) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-zen -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-zen-fallback.img - -::Arch Linux (LTS) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-lts -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-lts-fallback.img - -::Arch Linux (Hardened) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-hardened -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-hardened-fallback.img -#+end_src -#+begin_center -~/boot/limine.cfg~ -#+end_center - -** Configure the =initramfs= -We'll add some custom entries to the ~/etc/mkinitcpio.conf~. - -#+begin_IMPORTANT -It is crucial that after you're finised with editing the file, you run - -#+begin_src fish -root in / -> mkinitcpio -P -#+end_src - -to regenerate the =initramfs=! -#+end_IMPORTANT - -*** =BINARIES= -First off, we some binaries to be present in the image, so that if we drop into a recovery shell, we can use them. - -#+begin_src txt -BINARIES=(btrfs nvim zsh fish) -#+end_src -#+begin_center -~/etc/mkinitcpio.conf~ -#+end_center - -*** Hibernation -In order to use the hibernation feature, you should make sure that your =swap= partition/file is at least the size of your RAM. - -If you use a =busybox= based =ramdisk=, you need to add the =resume= hook to =/etc/mkinitcpio.conf=, before =fsck= and definetely after =block= - -#+begin_NOTE -When using =EFISTUB= without =sbupdate=, your motherboard has to support kernel parameters for boot entries. If your motherboard doesn't support this, you would need to use . -#+end_NOTE - -*** =HOOKS= -Now we will specify every hook we need. -Mentionworthy additions to the default set are the hooks =colors=, =encrypt=, =btrfs= and =resume=. - -#+begin_src txt -HOOKS=(base udev colors block keyboard keymap consolefont autodetect kms modconf encrypt btrfs resume filesystems fsck) -#+end_src -#+begin_center -~/etc/mkinitcpio.conf~ -#+end_center - -*** =colors= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+---------------+-----------------------| -| | | terminus-font | mkinitcpio-colors-git | - -By creating a file ~/etc/vconsole.conf~ we can specify a custom font and colorscheme to use - -#+begin_src txt -KEYMAP=us -FONT=ter-116n -COLOR_0=282a36 -COLOR_1=ff5555 -COLOR_2=50fa7b -COLOR_3=f1fa8c -COLOR_4=6272a4 -COLOR_5=bd93f9 -COLOR_6=8be9fd -COLOR_7=d8d8d2 -COLOR_8=44475a -COLOR_9=ff8585 -COLOR_10=80faab -COLOR_11=f1fabc -COLOR_12=92a2d4 -COLOR_13=ff79c6 -COLOR_14=bbe9fd -COLOR_15=f8f8f2 -#+end_src -#+begin_center -~/etc/vconsole.conf~ -#+end_center - -** Switch to a =systemd= based =ramdisk= -#+begin_CAUTION -I think it is worth noting that lately I didn't use a =systemd= based =ramdisk= on my portable setup anymore, as I encountered some issues. - -The underlying issue apparently were having the =block= and =keyboard= hook located after the =autodetect= hook. -Reversing this so that =block= and =keyboard= precedes =autodetect= seems to fix the issue. -In any case the =fallback initramfs= should always work. - -It is worth noting though, that with the =busybox= based one, you lose the ability to unlock multiple =LUKS= encrypted partitions / devices at once, if they share the same password. -In that case you would need to use the ~/etc/crypttab~. -#+end_CAUTION - -There is nothing particularily better about using a =systemd= based =ramdisk= instead of a =busybox= one, it's just that I prefer it. - -Some advantages, at least in my opinion, that the =systemd= based =ramidsk= has, are the included =resume= hook, as well as password caching, when decrypting encrypted volumes, which means that because I use the same =LUKS= password for both my data storage =HDD=, as well as my =cryptroot=, I only have to input the password once for my =cryptroot= and my data storage =HDD= will get decrypted too, without the need to create =/etc/crypttab= entries, etc. - -To switch to a =systemd= based =ramdisk=, you will normally need to substitute the =busybox= specific hooks for =systemd= ones. You will also need to use =systemd= hooks from now on, for example =sd-encrypt= instead of =encrypt=. - -- =base= - - In my case, I left the =base= hook untouched, to get a =busybox= recovery shell, if something goes wrong, although you wouldn't technically need it, when using =systemd=. - - Don't remove this, when using =busybox=, unless you're absolutely knowing what you're doing. - -- =udev= - - Replace this with =systemd= to switch from =busybox= to =systemd=. - -- =keymap= and/or =fishfont= - - These two, or one, if you didn't use one of them, need to be replaced with =sd-vfish=. Everything else stays the same with these. - -- =encrypt= - - Isn't used in the default =/etc/mkinitcpio.conf=, but could be important later on, for example when using . You need to substitute this with =sd-encrypt=. - -- =lvm2= - - Same thing as with =encrypt= and needs to be substituted with =sd-lvm2=. - -You can find all purposes of the individual hooks, as well as the =busybox= / =systemd= equivalent of each one in the . - - -** Secure Boot -*** =PreLoader= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+------------------| -| | | | preloader-signed | - -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, or if you want to use this installation on multiple systems, where Secure Boot could be enabled, use this method. - -If you want to actually make use of the Secure Boot feature, read [[*The manual way]]. - -I know I told you that you're now good to boot into your new system. -That is only correct, if you're /not/ using Secure Boot. -You can either proceed by disabling Secure Boot in your firmware settings, or by using =PreLoader= as kind of a pre-bootloader. - -If you decided on using Secure Boot, you will first have to install the package. -Now we just need to copy the =PreLoader= and the =HashTool=, which gets launched if the hash of the binary that is to be loaded (~loader.efi~) is not registered in the firmware yet, to our /EFI System Partition/ - -#+begin_src fish -root in / -> cp /usr/share/preloader-signed/PreLoader.efi /boot/EFI/BOOT/BOOTX64.EFI - -root in / -> cp /usr/share/preloader-signed/HashTool.efi /boot/EFI/BOOT/ -#+end_src - -#+begin_NOTE -If you have to use =bcdedit= from within Windows, as explained in section [[*=grub= - =UEFI=]], you need to adapt the command accordingly - -#+begin_src fish -root in / -> cp /usr/share/preloader-signed/PreLoader.efi /boot/EFI/BOOT/PreLoader.efi - -root in / -> cp /usr/share/preloader-signed/HashTool.efi /boot/EFI/BOOT/ -#+end_src - -and under Windows - -#+begin_src fish -bcdedit /set {bootmgr} path \EFI\BOOT\PreLoader.efi -#+end_src -#+end_NOTE - -Now you will be greeted by =HashTool= everytime you update your bootloader or kernel. - -Just choose "Enroll Hash", choose the appropriate ~loader.efi~, and also enroll the kernel (~vmlinuz-linux~). - -Reboot and your system should fire up just fine. - -*** The manual way - -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 first. - -**** File formats -In the following subsections, we will be dealing with some different file formats. - -- =.key= =PEM= format private keys for =EFI= binary and =EFI= signature list signing. - -- =.crt= =PEM= format certificates for =sbsign=. - -- =.cer= =DER= format certigficates for firmware. - -- =.esl= Certificates in =EFI= Signature List for =KeyTool= and/or firmware. - -- =.auth= Certificates in =EFI= Signature List with authentication header (i.e. a signed certificate update file) for =KeyTool= and/or firmware. - -**** 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. - -***** =GUID= -Let's create a =GUID= first to use with the next commands. - -#+begin_src fish -~/sb -> uuidgen --random > GUID.txt -#+end_src - -***** =PK= -We can now generate our =PK= (Platform Key) - -#+begin_src fish -~/sb -> openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -subj "/CN=Platform Key for DustArch/" -out PK.crt - -~/sb -> openssl x509 -outform DER -in PK.crt -out PK.cer - -~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl - -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth -#+end_src - -In order to allow deletion of the =PK=, for firmwares which do not provide this functionality out of the box, we have to sign an empty file. - -#+begin_src fish -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK /dev/null rm_PK.auth -#+end_src - -***** =KEK= -We proced in a similar fashion with the =KEK= (Key Exchange Key) - -#+begin_src fish -~/sb -> openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -subj "/CN=Key Exchange Key for DustArch/" -out KEK.crt - -~/sb -> openssl x509 -outform DER -in KEK.crt -out KEK.cer - -~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl - -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth -#+end_src - -***** =DB= -And finally the =DB= (Signature Database) key. - -#+begin_src fish -~/sb -> openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -subj "/CN=Signature Database key for DustArch" -out db.crt - -~/sb -> openssl x509 -outform DER -in db.crt -out db.cer - -~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl - -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth -#+end_src - -**** 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 =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 [[https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt][Microsoft's certificates]], convert them into a usable format, sign them and enroll them. -No need to sign the Windows boot loader. - -#+begin_src fish -root in ~/sb -> openssl x509 -inform DER -outform PEM -in MicWinCert.crt -out MicWinCert.pem - -root in ~/sb -> cert-to-efi-sig-list -g 77fa9abd-0359-4d32-bd60-28f4e78f784b MicWinCert.pem MS_db.esl - -root in ~/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_src - -**** Move the kernel & keys -In order to ensure a smooth operation, with actual security, we need to move some stuff around. - -***** Kernel, =initramfs=, microcode -=pacman= will put its unsigned and unencrypted kernel, =initramfs= and microcode images into =/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 =/efi= and modify our =fstab= accordingly. - -***** 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 =root= home directory, we will move the necessary keys. - -I personally like to create a =/etc/efi-keys= directory, =chmod=ded to =700= and place my =db.crt= and =db.key= there. All the keys will get packed into a =tar= archive and encrypted with a strong symmetric pass phrase and stored somewhere secure and safe. - -**** Signing -Signing is the process of, well, signing your =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. - -***** Manual signing -Of course, you can sign images yourself manually. In my case, I used this, to sign the boot loader, kernel and =initramfs= of my USB installation of Arch Linux. - -As always, manual signing also comes with its caveats! - -If I update my kernel, boot loader, or create an updated =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 =sbupdate=, which I will explain in the next paragraph . - -For example, if I want to sign the kernel image of my USB installation, where I mounted the boot partition to =/mnt/DustPortable/boot=, I would have to do the following - -#+begin_src fish -root in ~/sb -> sbsign --key /etc/efi-keys/db.key --cert /etc/efi-keys/db.crt --output /mnt/DustPortable/boot/vmlinuz-linux /mnt/DustPortable/boot/vmlinuz-linux -#+end_src - -***** =sbupdate= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+--------------| -| | | | sbupdate-git | - -Of course, if you're using Secure Boot productively, you would want something more practical than manual signing, especially since you need to sign - -- the boot loader - -- the kernel image - -- the =initramfs= - -Fortunately there is an easy and uncomplicated tool out there, that does all that for you, called =sbupdate=. - -It not only signs everything and also foreign =EFI= binaries, if specified, but also combines your kernel and =initramfs= into a single executable =EFI= binary, so you don't even need a boot loader, if your motherboard implementation supports booting those. - -After installing =sbupdate=, we can edit the =/etc/sbupdate.conf= file, to set everything up. - -Everything in this config should be self-explanatory. - -You will probably need to - -- set =ESP_DIR= to =/efi= - -- add any other =EFI= binary you want to have signed to =EXTRA_SIGN= - -- add your kernel parameters, for example - - - =rd.luks.name= - - - =root= - - - =rw= - - - =resume= - - - etc. - - to =CMDLINE_DEFAULT= - -After you've successfully configured =sbupdate=, you can run it as root, to create all the signed files. - -=sbupdate= will be executed upon kernel updates by =pacman=, but not if you change your =initramfs= with something like =mkinitcpio=. -In that case you will have to run =sbupdate= manually. - -**** Add =EFI= entries -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|------------+---------+-------------+-------| -| efibootmgr | | | | - -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 =NVRAM=. -You can do this with =efibootmgr=. - -#+begin_src fish -root in ~/sb -> efibootmgr -c -d /dev/sda -p 1 -L "Arch Linux fallback" -l "EFI\\Arch\\linux-fallback-signed.efi" - -root in ~/sb -> efibootmgr -c -d /dev/sda -p 1 -L "Arch Linux" -l "EFI\\Arch\\linux-signed.efi" -#+end_src - -Of course you can extend this list, with whichever entries you need. - -**** Enrolling everything -First off, copy all =.cer=, =.esl= and =.auth= files to a =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 =db=, =KEK= and =PK= certificates in sequence. - -Enroll the Platform Key last, as it sets most firmware's Secure Boot sections back into "User mode", exiting "Setup Mode". - -* 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. - -Not everything in this section is mandatory. - -This section is rather a guideline, because it is easy to forget some steps needed (for example =jack= for audio production), which only become apparent when they're needed or stuff fails. - -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. -So reader discretion advised! - -** 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_src fish -~ -> ip link -#+end_src - -To make sure that you have a working /Internet/ connection, issue - -#+begin_src fish -~ -> ping archlinux.org -#+end_src - -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 =NetworkManager= service - -#+begin_src fish -~ -> sudo systemctl restart NetworkManager.service -#+end_src - -and then try ~> ping~-ing again. - -*** Wi-Fi - -If you're trying to utilize a Wi-Fi connection, use =nmcli=, the NetworkManager's command line tool, or =nmtui=, the NetworkManager terminal user interface, to connect to a Wi-Fi network. - -I never got =nmtui= to behave like I wanted it to, in my particular case at least, which is the reason why I use =nmcli= or the GUI tools. - -First make sure, the scanning of nearby Wi-Fi networks is enabled for your Wi-Fi device - -#+begin_src fish -~ -> nmcli radio -#+end_src - -and if not, enable it - -#+begin_src fish -~ -> nmcli radio wifi on -#+end_src - -Now make sure your Wi-Fi interface appears under - -#+begin_src fish -~ -> nmcli device -#+end_src - -Rescan for available networks - -#+begin_src fish -~ -> nmcli device wifi rescan -#+end_src - -and list all found networks - -#+begin_src fish -~ -> nmcli device wifi list -#+end_src - -After that connect to the network - -#+begin_src fish -~ -> nmcli device wifi connect --ask -#+end_src - -Now try ~> ping~-ing again. - -** 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_src fish -~ -> sudo pacman -Syu -#+end_src - -** Enabling the =multilib= repository -In order to make 32-bit packages available to =pacman=, we'll need to enable the =multilib= repository in ~/etc/pacman.conf~ first. -Simply uncomment - -#+begin_src fish -[multilib] -Include = /etc/pacman.d/mirrorlist -#+end_src - -and update =pacman='s package repositories afterwards - -#+begin_src fish -~ -> sudo pacman -Syu -#+end_src - -** =fish= for president -Of course you can use any shell you want. In my case I'll be using the -=fish= shell. - -I am using =fish= because of its auto completion functionality and extensibility, as well as brilliant =vim= like navigation implementation, though that might not be what you're looking for (at least way better than something like =elvish= or =nushell= at the moment of writing). - -If you remember correctly, we set the login shell to =bash= when creating the =dustvoice= user, so you might wonder why we didn't directly set it to =fish=. -Well =fish= isn't completely =POSIX= compliant, neither does it want to be. -Therefore running =fish= as a login shell might not be the absolute best experience you ever had. - -Instead we populate our ~.bashrc~ with some scripting that will let =fish= take over any /interactive/ shell, while scripts, etc. that expect a =POSIX= compliant shell can have their way. - -#+begin_NOTE -You can replicate the following instructions directly for the =root= user, to get the same kind of experience there -#+end_NOTE - -#+begin_src text -if [​[$- == *i* && $(ps --no-header --pid=$PPID --format=comm) != "fish" && -z ${BASH_EXECUTION_STRING} ]] -then - exec fish -fi -#+end_src -#+begin_center -~~/.bashrc~ -#+end_center - -Don't worry about the looks by the way, we're gonna change all that in just a second. - -** =git= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+-------| -| | git | | | - -Install the package and you're good to go for now, as we'll care about the =.gitconfig= in just a second. - -** Security is important -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+-------| -| gnupg | | | | - -If you've followed the tutorial using a recent version of the archiso, you'll probably already have the most recent version of =gnupg= installed by default. - -*** Smartcard shenanigans -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------------+-------------+-------| -| | libusb-compat | ccid | | -| | | opensc | | -| | | pcsclite | | -| | | usbip | | - -After that you'll still have to setup =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 =pcscd.service= service - -#+begin_src fish -~ -> sudo systemctl enable pcscd.service - -~ -> sudo systemctl start pcscd.service -#+end_src - -After that, you should be able to see your smartcard being detected - -#+begin_src fish -~ -> gpg --card-status -#+end_src - -If your smartcard still isn't detected, try logging off completely or even restarting, as that sometimes is the solution to the problem. - -** Additional required tools -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|---------+-------------+---------------+-------| -| make | clang | bat | | -| openssh | cmake | exa | | -| | jdk-openjdk | pass | | -| | python | python-pynvim | | -| | | starship | | -| | | zoxide | | - -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. - -** Setting up a =home= environment -In this step we're going to setup a home environment for both the =root= and my personal =dustvoice= user. - -In my case these 2 home environments are mostly equivalent, which is why I'll execute the following commands as the =dustvoice= user first and then switch to the =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 =dustvoice= user, I would have to regularly update it for the =root= user too. - -Also, I have to register my smartcard for the root user. -This in turn is problematic, because the =gpg-agent= used for =ssh= authentication, doesn't behave well when used within a ~> su~ or ~> sudo -i~ session. -So in order to update =root='s config files I would either need to symlink everything, which I won't do, or I'll need to login as the =root= user now and then, to update everything. - -In my case, I want to access all my =git= repositories with my =gpg= key on my smartcard. -For that I have to configure the =gpg-agent= with some configuration files that reside in a =git= repository. -This means I will have to get along with using the =https= URL of the repository first and later changing the URL either in the corresponding =.git/config= file, or by issuing the appropriate command. - -*** Use =dotfiles= for a base config -To provide myself with a base configuration, which I can then extend, I maintain a =dotfiles= repository, which contains all kinds of configurations. - -The special thing about this =dotfiles= repository is that it /is/ my home folder. -By using a curated ~.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 =dotfiles= repository first - -#+begin_src fish -~ -> git init - -~ -> git remote add origin https://git.dustvoice.de/DustVoice/dotfiles.git - -~ -> git fetch - -~ -> git reset origin/master --hard - -~ -> git branch --set-upstream-to=origin/master master -#+end_src - -Now I can issue any =git= command in my ~$HOME~ directory, because it now is a =git= repository. - -*** Set up =gpg= -As I wanted to keep my =dotfiles= repository as modular as possible, I utilize =git='s =submodule= feature. -Furthermore I want to use my =nvim= repository, which contains all my configurations and plugins for =neovim=, on Windows, but without all the Linux specific configuration files. -I am also using the =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 =submodule=​s (=nvim= config files and =pass=) though, we will have to setup our =gpg= key as an =ssh= key, as I use it to authenticate - -#+begin_src fish -~ -> chmod 700 .gnupg - -~ -> gpg --card-status - -~ -> gpg --card-edit -#+end_src - -#+begin_src fish -(insert) gpg/card> fetch -(insert) gpg/card> q -#+end_src - -#+begin_src fish -~ -> gpg-connect-agent updatestartuptty /bye -#+end_src - -You would have to adapt the =keygrip= present in the ~~/.gnupg/sshcontrol~ file to your specific =keygrip=, retrieved with ~> gpg -K --with-keygrip~. - -#+begin_IMPORTANT -If you're inside a VM, you of course need to somehow pass the smartcard to said VM. - -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+---------+-------------+-------| -| | | usbip | | - -If you're inside a =Hyper-V= VM, you need to utilize =usbip=. -If you're using =fish=, there's a script under ~~/.config/fish/usbip-man.fish~ -#+end_IMPORTANT - -Now, as mentioned before, I'll switch to using =ssh= for authentication, rather than =https= - -#+begin_src fish -~ -> git remote set-url origin git@git.dustvoice.de:DustVoice/dotfiles.git -#+end_src - -As the best method to both make =fish= recognize all the configuration changes, as well as the =gpg-agent= behave properly, is to re-login. -We'll do just that - -#+begin_src fish -~ -> exit -#+end_src - -It is very important to note, that I mean /a real re-login/. - -That means that if you've used =ssh= to log into your machine, it probably won't be sufficient to login into a new =ssh= session. -You may need to restart the machine entirely. - -*** Finalize the =dotfiles= -Now log back in and continue - -#+begin_src fish -~ -> git submodule update --recursive --init -#+end_src - -**** Setup =nvim= -If you plan on utilizing =nvim= with my config, you need to setup things first - -#+begin_src fish -~ -> cd .config/nvim - -~/.config/nvim -> echo 'let g:platform = "linux"' >> platform.vim - -~/.config/nvim -> echo 'let g:use_autocomplete = 3' >> custom.vim - -~/.config/nvim -> echo 'let g:use_clang_format = 1' >> custom.vim - -~/.config/nvim -> echo 'let g:use_font = 0' >> custom.vim - -~/.config/nvim -> nvim --headless +PlugInstall +qa - -~/.config/nvim -> cd plugged/YouCompleteMe - -~/.config/nvim/plugged/YouCompleteMe -> python3 install.py --clang-completer --java-completer - -~/.config/nvim/plugged/YouCompleteMe -> cd ~ -#+end_src - -*** =gpg-agent= forwarding -Now there is only one thing left to do, in order to make the =gpg= setup complete: =gpg-agent= forwarding over =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 =gpg-agent= to my remote machine. - -First of all, I want to setup a config file for =ssh=, as I don't want to pass all parameters manually to ssh every time. - -#+begin_src fish -Host - HostName - ForwardAgent yes - ForwardX11 yes - RemoteForward - RemoteForward -#+end_src - -You would of course, need to adapt the content in between the =<= and =>= brackets. - -To get the paths needed as parameters for =RemoteForward=, issue - -#+begin_src fish -~ -> gpgconf --list-dirs -#+end_src - -An example for a valid =~/.ssh/config= would be - -#+begin_src fish -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_src - -Now you'll still need to enable some settings on the remote machines. - -#+begin_src fish -StreamLocalBindUnlink yes -AllowAgentForwarding yes -X11Forwarding yes -#+end_src - -Now just restart your remote machines and you're ready to go. - -If you use =alacritty=, to connect to your remote machine over =ssh=, you will need to install the =alacritty= package on the remote machine too, as =alacritty= uses its own =$TERM=. - -Another option would be changing that variable for the =ssh= command - -#+begin_src fish -~ -> TERM=xterm-256colors ssh remote-machine -#+end_src - -*** Back to your =root=​s -As mentioned before, you would now switch to the =root= user, either by logging in as =root=, or by using - -#+begin_src fish -~ -> sudo -iu root -#+end_src - -Now go back to to repeat all commands for the =root= user. - -A native login would be better compared to ~> sudo -iu root~, as there could be some complications, like already running =gpg-agent= instances, etc., which you would need to manually resolve, when using ~> sudo -iu root~. - -** Audio -Well, why wouldn't you want audio ... - -*** =alsa= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+------------+-------------+-------| -| | alsa-utils | | | - -#+begin_NOTE -You're probably better off using [[*=pulseaudio=][=pulseaudio=]], [[*=jack=][=jack=]] and/or [[*=pipewire=][=pipewire=]]. -#+end_NOTE - -Now choose the sound card you want to use - -#+begin_src fish -~ -> cat /proc/asound/cards -#+end_src - -and then create ~/etc/asound.conf~ - -#+begin_src fish -defaults.pcm.card 2 -defaults.ctl.card 2 -#+end_src - -It should be clear, that you would have to switch out =2= with the number corresponding to the sound card you want to use. - -*** =pulseaudio= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+-------------+-------------+-------| -| | pavucontrol | pulsemixer | | -| | pulseaudio | | | - -Some applications require =pulseaudio=, or work better with it, for example =discord=, so it might make sense to use =pulseaudio= (although [[*=pipewire=][=pipewire=]] could replace it). - -For enabling real-time priority for =pulseaudio= on Arch Linux, please make sure your user is part of the =audio= group and edit the file ~/etc/pulse/daemon.conf~, so that you uncomment the lines - -#+begin_src fish -high-priority = yes -nice-level = -11 - -realtime-scheduling = yes -realtime-priority = 5 -#+end_src - -If your system can handle the load, you can also increase the remixing quality, by changing the =resample-method= - -#+begin_src fish -resample-method = speex-float-10 -#+end_src - -Of course a restart of the =pulseaudio= daemon is necessary to reflect the changes you just made - -#+begin_src fish -~ -> pulseaudio --kill - -~ -> pulseaudio --start -#+end_src - -*** =jack= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+-----------------+-------------+-------| -| | pulseaudio-jack | cadence | | -| | | jack2 | | - -If you either want to manually control audio routing, or if you use some kind of audio application like =ardour=, you'll probably want to use =jack= and then =cadence= as a GUI to control it, as it has native support for bridging =pulseaudio= to =jack=. - -*** =pipewire= -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+----------------+-------------+-------| -| | pipewire | qpwgraph | | -| | pipewire-alsa | | | -| | pipewire-audio | | | -| | pipewire-jack | | | -| | pipewire-pulse | | | -| | wireplumber | | | - -#+begin_TIP -If you don't want to reboot, you need to stop =pulseaudio.service= and start =pipewire-pulse.service= - -#+begin_src fish -root in / -> systemctl stop pulseaudio.service - -root in / -> systemctl start pipewire-pulse.service -#+end_src - -You can check if =pipewire-pulse= is working correctly with - -#+begin_src fish -~ -> pactl info -#+end_src -#+end_TIP - -*** Audio handling -#+ATTR_LATEX: :environment pkgtblr -| | | | | -| *core* | *extra* | *community* | *AUR* | -|--------+-----------+-------------+-------| -| | libao | sox | | -| | libid3tag | twolame | | -| | libmad | | | -| | libpulse | | | -| | opus | | | -| | wavpack | | | - -To also play audio, we need to install the mentioned packages and then simply do - -#+begin_src fish -~ -> play audio.wav - -~ -> play audio.mp3 -#+end_src - -to play audio. - -** Bluetooth - -=extra= & =bluez bluez-utils pulseaudio-bluetooth=\\ -=community= & =blueman=\\ - -To set up Bluetooth, we need to install the =bluez= and =bluez-utils= -packages in order to have at least a command line utility =bluetoothctl= -to configure connections - -Now we need to check if the =btusb= kernel module was already loaded - -#+begin_src fish -~ -> sudo lsmod | grep btusb -#+end_src - -After that we can enable and start the =bluetooth.service= service - -#+begin_src fish -~ -> sudo systemctl enable bluetooth.service - -~ -> sudo systemctl start bluetooth.service -#+end_src - -To use =bluetoothctl= and get access to the Bluetooth device of your PC, -your user needs to be a member of the =lp= group. - -Now simply enter =bluetoothctl= - -#+begin_src fish -~ -> bluetoothctl -#+end_src - -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_src fish -(insert) [DustVoice]# list -(insert) [DustVoice]# select -#+end_src - -After that, power on the controller - -#+begin_src fish -(insert) [DustVoice]# power on -#+end_src - -Now enter device discovery mode - -#+begin_src fish -(insert) [DustVoice]# scan on -#+end_src - -and list found devices - -#+begin_src fish -(insert) [DustVoice]# devices -#+end_src - -You can turn device discovery mode off again, after your desired device -has been found - -#+begin_src fish -(insert) [DustVoice]# scan off -#+end_src - -Now turn on the agent - -#+begin_src fish -(insert) [DustVoice]# agent on -#+end_src - -and pair with your device - -#+begin_src fish -(insert) [DustVoice]# pair -#+end_src - -If your device doesn't support PIN verification you might need to -manually trust the device - -#+begin_src fish -(insert) [DustVoice]# trust -#+end_src - -Finally connect to your device - -#+begin_src fish -(insert) [DustVoice]# connect -#+end_src - -If your device is an audio device, of some kind you might have to -install =pulseaudio-bluetooth=. - -You will then also need to append 2 lines to =/etc/pulse/system.pa= - -#+begin_src fish -load-module module-bluetooth-policy -load-module module-bluetooth-discover -#+end_src - -and restart =pulseaudio= - -#+begin_src fish -~ -> pulseaudo --kill - -~ -> pulseaudo --start -#+end_src - -If you want a GUI to do all of this, just install =blueman= and launch -=blueman-manager= - -** Graphical desktop environment - -=extra= & =ttf-hack xclip xorg xorg-drivers xorg-xinit=\\ -=community= & =arandr alacritty bspwm dmenu sxhkd=\\ -=AUR= & =polybar=\\ - -If you decide, that you want to use a graphical desktop environment, you -have to install additional packages in order for that to work. - -=xclip= is useful, when you want to send something to the =X= clipboard. -It is also required, in order for =neovim='s clipboard to work -correctly. It is not required though. - -*** NVIDIA - -=extra= & =nvidia nvidia-utils nvidia-settings opencl-nvidia=\\ - -If you also want to utilize special NVIDIA functionality, for example -for =davinci-resolve=, you'll most likely need to install their -proprietary driver. - -To configure the =X= server correctly, one can use =nvidia-xconfig= - -#+begin_src fish -~ -> sudo nvidia-xconfig -#+end_src - -If you want to further tweak all settings available, you can use -=nvidia-settings=. - -#+begin_src fish -~ -> sudo nvidia-settings -#+end_src - -will enable you to /"Save to X Configuration File"/, which merges your -changes with =/etc/X11/xorg.conf=. - -With - -#+begin_src fish -~ -> nvidia-settings -#+end_src - -you'll only be able to save the current configuration to =~/.nvidia-settings-rc=, which you have to source after =X= startup with - -#+begin_src fish -~ -> nvidia-settings --load-config-only -#+end_src - -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. - -*** Launching the graphical environment -After that you can now do =startx= in order to launch the graphical -environment. - -If anything goes wrong in the process, remember that you can press -=Ctrl+Alt+= to switch =tty=s. - -**** The NVIDIA way - -=community= & =bbswitch=\\ -=AUR= & =nvidia-xrun=\\ - -If you're using an NVIDIA graphics card, you might want to use -=nvidia-xrun=^{=AUR=} instead of =startx=. This has the advantage, of -the =nvidia= kernel modules, as well as the =nouveau= ones not loaded at -boot time, thus saving power. =nvidia-xrun=^{=AUR=} will then load the -correct kernel modules and run the =.nvidia-xinitrc= script in your home -directory (for more file locations look into the documentation for -=nvidia-xrun=^{=AUR=}). - -At the time of writing, =nvidia-xrun=^{=AUR=} needs =sudo= permissions -before executing its task. - -=AUR= & =nvidia-xrun-pm=\\ - -If your hardware doesn't support =bbswitch=, you would need to use -=nvidia-xrun-pm=^{=AUR=} instead. - -Now we need to blacklist /both =nouveau= and =nvidia=/ kernel modules. - -To do that, we first have to find out, where our active =modprobe.d= -directory is located. There are 2 possible locations, generally -speaking: =/etc/modprobe.d= and =/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 =nvidia-xrun.conf= and write the -following into it - -#+begin_src fish -blacklist nvidia -blacklist nvidia-drm -blacklist nvidia-modeset -blacklist nvidia-uvm -blacklist nouveau -#+end_src - -With this config in place, - -#+begin_src fish -~ -> lsmod | grep nvidia -#+end_src - -and - -#+begin_src fish -~ -> lsmod | grep nouveau -#+end_src - -should return no output. Else you might have to place some additional -entries into the file. - -Of course, you'll need to reboot, after blacklisting the modules and -before issuing the 2 commands mentioned. - -If you installed =nvidia-xrun-pm= instead of =nvidia-xrun= and -=bbswitch=, you might want to also enable the =nvidia-xrun-pm= service - -#+begin_src fish -dustvoice@dustArch ~ -$ sudo systemctl enable nvidia-xrun-pm.service -#+end_src - -The required =.nvidia-xinitrc= file, mentioned previously, should -already be provided in the =dotfiles= repository. - -Now instead of =startx=, just run =nvidia-xrun=, enter your =sudo= -password and you're good to go. - -** Additional =fish= software -Software that is useful in combination with a =fish=. - -*** =tmux= - -=community= & =tmux=\\ - -I would reccommend to install =tmux= which enables you to have multiple -terminal instances (called =windows= in =tmux=) open at the same time. -This makes working with the linux terminal much easier. - -To view a list of keybinds, you just need to press =Ctrl+b= followed by -=?=. - -*** Communication -Life is all about communicating. Here are some pieces of software to do -exactly that. - -**** =weechat= - -=community= & =weechat=\\ - -=weechat= is an =IRC= client for the terminal, with the best features -and even a =vim= mode, by using a plugin - -To configure everything, open =weechat= - -#+begin_src fish -~ -> weechat -#+end_src - -and install =vimode=, as well as configure it - -#+begin_src fish -/script install vimode.py -/vimode bind_keys -/set plugins.var.python.vimode.mode_indicator_normal_color_bg "blue" -#+end_src - -Now add =mode_indicator+= in front of and =,[vi_buffer]= to the end of -=weechat.bar.input.items=, in my case - -#+begin_src fish -/set weechat.bar.input.items "mode_indicator+[input_prompt]+(away), [input_search], [input_paste], input_text, [vi_buffer]" -#+end_src - -Now add =,cmd_completion= to the end of =weechat.bar.status.items=, in -my case - -#+begin_src fish -;/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_src - -Now enable =vimode= searching - -#+begin_src fish -/set plugins.var.python.vimode.search_vim on -#+end_src - -Now you just need to add a new connection, for example -=irc.freenode.net= - -#+begin_src fish -/server add freenode irc.freenode.net -#+end_src - -and connect to it - -#+begin_src fish -/connect freenode -#+end_src - -You might need to authenticate with =NickServ=, before being able to -write in a channel - -#+begin_src fish -/msg NickServ identify -#+end_src - -Instead of directly =/set=ting the values specified above, you can also -do - -#+begin_src fish -/fset weechat.var.name -#+end_src - -after that, using the cursor, select the entry you want to modify (for -example =plugins.var.python.vimode=) and then press =s= (make sure -you're in =insert= mode) and =Return=, in order to modify the existing -value. - -*** PDF viewer - -=extra= & =ghostscript=\\ -=community= & =fbida=\\ - -To use =asciidoctor-pdf=, you might be wondering how you are supposed to -open the generated PDFs from the native linux fish. - -This =fbida= package provides the =fbgs= software, which renders a PDF -document using the native framebuffer. - -To view this PDF document (=Documentation.pdf=) for example, you would -run - -#+begin_src fish -~ -> fbgs Documentation.pdf -#+end_src - -You can view all the controls by pressing =h=. - -** Additional =hybrid= software -Some additional software providing some kind of =GUI= to work with, but -that can be useful in a =fish= only environment nevertheless. - -*** =Pass=word management -I'm using =pass= as my password manager. As we already installed it in -the step and updated the =submodule= that holds our =.password-store=, -there is nothing left to do in this step - -*** =python= - -=extra= & =python=\\ - -Python has become really important for a magnitude of use cases. - -*** =ruby= & =asciidoctor= - -=extra= & =ruby rubygems=\\ - -In order to use =asciidoctor=, we have to install =ruby= and =rubygems=. -After that we can install =asciidoctor= and all its required gems. - -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 - -- =pygments.rb=, which requires python to be installed - - #+begin_src fish - ~ - > gem install pygments.rb - #+end_src - -- =rouge= which is a native =ruby= gem - - #+begin_src fish - ~ - > gem install rouge - #+end_src - -Now the only thing left, in my case at least, is adding ~~/.gem/ruby/2.7.0/bin~ to your path. - -Please note that if you run a ruby version different from =2.7.0=, or if -you upgrade your ruby version, you have to use the =bin= path for that -version. - -For =zsh= you'll want to add a new entry inside the =.zshpath= file - -#+begin_src fish -path+=("$HOME/.gem/ruby/2.7.0/bin") -#+end_src - -which then gets sourced by the provided =.zshenv= file. An example is -provided with the =.zshpath.example= file - -You might have to re-=> source= the =.zshenv= file to make the changes -take effect immediately - -#+begin_src fish -~ -> source .zshenv -#+end_src - -If you want to add a new entry to the =path= variable, you have to -append it to the array - -#+begin_src fish -path+=("$HOME/.gem/ruby/2.7.0/bin" "$HOME/.gem/ruby/2.6.0/bin") -#+end_src - -If you use another shell than =zsh=, you might have to do something -different, to add a directory to your =PATH=. - -*** =JUCE= and =FRUT= -=JUCE= is a library for =C++= that enables you to develop cross-platform -applications with a single codebase. - -=FRUT= makes it possible to manage =JUCE= projects purely from =cmake=. - -Note that apparently in the new =JUCE= version, =cmake= support is -integrated. It remains to be seen how well this will work and if =FRUT= -will become obsolete. - -The information in this guide should be updated ASAP, if it is apparent -that =FRUT= has now become obsolete. - -#+begin_src fish -~ -> git clone https://github.com/WeAreROLI/JUCE.git - -~ -> cd JUCE - -~/JUCE -> git checkout develop - -~/JUCE -> cd .. - -~ -> git clone https://github.com/McMartin/FRUT.git -#+end_src - -**** Using =JUCE= - -=core= & =gcc gnutls=\\ -=extra= & -=alsa-lib clang freeglut freetype2 ladspa libx11 libxcomposite libxinerama libxrandr mesa webkit2gtk=\\ -=community= & =jack2 libcurl-gnutls=\\ -=multilib= & =lib32-freeglut=\\ - -In order to use =JUCE=, you'll need to have some dependency packages -installed, where =ladspa= and =lib32-freeglut= are not neccessarily -needed. - -*** Additional development tools -Here are just some examples of development tools one could install in -addition to what we already have. - -**** Code formatting - -=community= & =astyle=\\ - -We already have =clang-format= as a code formatter, but this only works -for =C=-family languages. For =java= stuff, we can use =astyle= - -**** Documentation - -=extra= & =doxygen=\\ - -To generate a documentation from source code, I mostly use =doxygen= - -**** Build tools - -=community= & =ninja=\\ - -In addition to =make=, I'll often times use =ninja= for my builds - -*** Android file transfer - -=extra= & =gvfs-mtp libmtp=\\ - -Now you should be able to see your phone inside either your preferred -filemanager, in my case =thunar=, or =gigolo=^{=AUR=}. - -If you want to access the android's file system from the command line, -you will need to either install and use =simple-mtpfs=^{=AUR=}, or =adb= - -**** =simple-mtpfs=^{=AUR=} - -=AUR= & =simple-mtpfs=\\ - -Edit =/etc/fuse.conf= to uncomment - -#+begin_src fish -user_allow_other -#+end_src - -and mount the android device - -#+begin_src fish -~ -> simple-mtpfs -l - -~ -> mkdir ~/mnt - -~ -> simple-mtpfs --device ~/mnt -allow_other -#+end_src - -and respectively unmount it - -#+begin_src fish -~ -> fusermount -u mnt - -~ -> rmdir mnt -#+end_src - -**** =adb= - -=community= & =android-tools=\\ - -Kill the =adb= server, if it is running - -#+begin_src fish -~ -> adb kill-server -#+end_src - -If the server is currently not running, ~> adb~ will output an error -with a =Connection refused= message. - -Now connect your phone, unlock it and start the =adb= server - -#+begin_src fish -~ -> adb start-server -#+end_src - -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_src fish -~ -> adb devices -#+end_src - -Now you can =push=/=pull= files. - -#+begin_src fish -~ -> adb pull /storage/emulated/0/DCIM/Camera/IMG.jpg . - -~ -> adb push IMG.jpg /storage/emulated/0/DCIM/Camera/IMG2.jpg - -~ -> adb kill-server -#+end_src - -Of course you would need to have the /developer options/ unlocked, as -well as the /USB debugging/ option enabled within them, for =adb= to -even work. - -*** Partition management - -=extra= & =gparted parted=\\ - -You may also choose to use a graphical partitioning software instead of -=fdisk= or =cfdisk=. For that you can use =gparted=. Of course there is -also the =fish= equivalent =parted=. - -*** PDF viewer - -=extra= & =evince=\\ -=community= & =zathura zathura-pdf-mupdf=\\ - -To use =asciidoctor-pdf=, you might be wondering how you are supposed to -open the generated PDFs using the GUI. - -The software =zathura= has a minimalistic design and UI with a focus on -vim keybinding, whereas =evince= is a more desktop like experience, with -things like a print dialogue, etc. - -*** Process management - -=extra= & =htop xfce4-taskmanager=\\ - -The native tool is =top=. - -The next evolutionary step would be =htop=, which is an improved version -of =top= (like =vi= and =vim= for example) - -If you prefer a GUI for that kind of task, use =xfce4-taskmanager=. - -*** Video software -Just some additional software related to videos. - -**** Live streaming a terminal session - -=community= & =tmate=\\ - -For this task, you'll need a program called =tmate=. - -** 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. - -*** Session Lock - -=community= & =xsecurelock xss-lock=\\ - -Probably the first thing you'll want to set up is a session locker, -which locks your =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 =xss-lock= to hook into the necessary =systemd= events and then -use =xsecurelock= as my locker. - -You need to make sure this command gets executed upon start of the -=X=-session, so hook it into your window manager startup script, or in a -file called by your desktop environment - -#+begin_src fish -~ -> xss-lock -l -- xsecurelock & -#+end_src - -*** =xfce-polkit=^{=AUR=} - -=AUR= & =xfce-polkit=\\ - -In order for GUI applications to acquire =sudo= permissions, we need to -install a =PolicyKit= authentication agent. - -We could use =gnome-polkit= for that purpose, which resides inside the -official repositories, but I decided on using =xfce-polkit=^{=AUR=}. - -Now you just need to startup =xfce-polkit=^{=AUR=} before trying to -execute something like =gparted= and you'll be prompted for your -password. - -As I already launch it as a part of my =bspwm= configuration, I won't -have to worry about that. - -*** Desktop background - -=extra= & =nitrogen=\\ - -You might want to consider installing =nitrogen=, in order to be able to -set a background image - -*** Compositing software - -=community= & =picom=\\ - -To get buttery smooth animation as well as e.g. smooth video playback in -=brave= without screen tearing, you might want to consider using a -compositor, in my case one named =picom= - -In order for =obs=' screen capture to work correctly, you need to kill -=picom= completely before using =obs=. - -#+begin_src fish -~ -> killall picom -#+end_src - -or - -#+begin_src fish -~ -> ps aux | grep picom - -~ -> kill -9 -#+end_src - -*** =networkmanager= applet - -=extra= & =network-manager-applet=\\ - -To install the =NetworkManager= applet, which lives in your tray and -provides you with a quick method to connect to different networks, you -have to install the =network-manager-applet= package - -Now you can start the applet with - -#+begin_src fish -~ -> nm-applet & -#+end_src - -If you want to edit the network connections with a more full screen -approach, you can also launch ~> nm-connection-editor~. - -The =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. - -*** Show keyboard layout - -=AUR= & =xkblayout-state=\\ - -To show, which keyboard layout and variant is currently in use, you can -use =xkblayout-state=^{=AUR=} - -Now simply issue the =layout= alias, provided by my custom =zsh= -configuration. - -*** X clipboard - -=extra= & =xclip=\\ - -To copy something from the terminal to the =xorg= clipboard, use =xclip= - -*** Taking screen shots - -=community= & =scrot=\\ - -For this functionality, especially in combination with =rofi=, use -=scrot=. - -~> scrot $HOME/Pictures/filename.png~ then saves the screen shot under -=$HOME/Pictures/filename.png=. - -*** Image viewer - -=extra= & =ristretto=\\ - -Now that we can create screen shots, we might also want to view those - -#+begin_src fish -~ -> ristretto filename.png -#+end_src - -*** File manager - -=extra= & =gvfs thunar=\\ -=AUR= & =gigolo=\\ - -You probably also want to use a file manager. In my case, =thunar=, the -=xfce= file manager, worked best. - -To also be able to mount removable drives, without being =root= or using -=sudo=, and in order to have a GUI for mounting stuff, you would need to -use =gigolo=^{=AUR=} and =gvfs=. - -*** Archive manager - -=extra= & =cpio unrar unzip zip=\\ -=community= & =xarchiver=\\ - -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 =xarchiver=. - -*** Web browser - -=extra= & =firefox firefox-i18n-en-us=\\ -=community= & =browserpass=\\ - -As you're already using a GUI, you also might be interested in a web -browser. In my case, I'm using =firefox=, as well as =browserpass= from -the official repositories, together with the , , , and finally add-ons, -in order to use my passwords in =firefox= and have best protection in -regard to privacy, while browsing the web. - -We still have to setup =browserpass=, after installing all of this - -#+begin_src fish -~ -> cd /usr/lib/browserpass - -/usr/lib/browserpass -> make hosts-firefox-user - -/usr/lib/browserpass -> cd ~ -#+end_src - -**** Entering the dark side - -=AUR= & =tor-browser=\\ - -You might want to be completely anonymous whilst browsing the web at -some point. Although this shouldn't be your only precaution, using -=tor-browser=^{=AUR=} would be the first thing to do - -You might have to check out how to import the =gpg= keys on the =AUR= -page of =tor-browser=. - -*** Office utilities - -=extra= & =libreoffice-fresh=\\ - -I'll use =libreoffice-fresh= for anything that I'm not able to do with -=neovim=. - -**** Printing - -=extra= & -=avahi cups cups-pdf nss-mdns print-manager system-config-printer=\\ - -In order to be able to print from the =gtk= print dialog, we'll also -need =system-config-printer= and =print-manager=. - -#+begin_src fish -~ -> sudo systemctl enable avahi-daemon.service - -~ -> sudo systemctl start avahi-daemon.service -#+end_src - -Now you have to edit =/etc/nsswitch.conf= and add -=mdns4_minimal [NOTFOUND=return]= - -#+begin_src fish -hosts: files mymachines myhostname mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns -#+end_src - -Now continue with this - -#+begin_src fish -~ -> avahi-browse --all --ignore-local --resolve --terminate - -~ -> sudo systemctl enable org.cups.cupsd.service - -~ -> sudo systemctl start org.cups.cupsd.service -#+end_src - -Just open up =system-config-printer= now and configure your printer. - -To test if everything is working, you could open up =brave=, then go to -/Print/ and then try printing. - -*** Communication -Life is all about communicating. Here are some pieces of software to do -exactly that. - -**** Email - -=extra= & =thunderbird=\\ - -There is nothing better than some classical email. - -**** Telegram - -=community= & =telegram-desktop=\\ - -You want to have your =telegram= messages on your desktop PC? - -**** TeamSpeak 3 - -=community= & =teamspeak3=\\ - -Wanna chat with your gaming friends and they have a =teamspeak3= server? - -**** Discord - -=community= & =discord=\\ - -You'd rather use =discord=? - -*** Video software -Just some additional software related to videos. - -**** Viewing video - -=extra= & =vlc=\\ - -You might consider using =vlc= - -**** Creating video - -=AUR= & =obs-linuxbrowser-bin obs-glcapture-git obs-studio-git=\\ - -=obs-studio-git=^{=AUR=} should be the right choice. - -You can also make use of the plugins provided in the package list above. - -***** Showing keystrokes - -=AUR= & =screenkey=\\ - -In order to show the viewers what keystrokes you're pressing, you can -use something like =screenkey=^{=AUR=} - -For ideal use with =obs=, my =dotfiles= repository already provides you -with the ~> screenkey-obs~ alias for you to run with =zsh=. - -**** Editing video - -=AUR= & =davinci-resolve=\\ - -In my case, I'm using =davinci-resolve=^{=AUR=}. - -**** Utilizing video - -=AUR= & =teamviewer=\\ - -Wanna remote control your own or another PC? - -=teamviewer=^{=AUR=} might just be the right choice for you - -*** Audio Production -You might have to edit =/etc/security/limits.conf=, to increase the -allowed locked memory amount. - -In my case I have 32GB of RAM and I want the =audio= group to be able to -allocate most of the RAM, which is why I added the following line to the -file - -#+begin_src fish -@audio - memlock 29360128 -#+end_src - -**** Ardour - -=community= & =ardour=\\ - -To e.g. edit and produce audio, you could use =ardour=, because it's -easy to use, stable and cross platform. - -=extra= & =ffmpeg=\\ - -Ardour won't natively save in the =mp3= format, due to licensing stuff. -In order to create =mp3= files, for sharing with other devices, because -they have problems with =wav= files, for example, you can just use -=ffmpeg=. - -and after that we're going to convert =in.wav= to =out.mp3= - -#+begin_src fish -~ -> ffmpeg -i in.wav -acodec mp3 out.mp3 -#+end_src - -**** Reaper - -=AUR= & =reaper-bin=\\ - -Instead of =ardour=, I'm using =reaper=, which is available for linux as -a beta version, in my case more stable than =ardour= and more easy to -use for me. - -*** Virtualization - -=community= & =virtualbox virtualbox-host-modules-arch=\\ - -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 -=virtualbox=. - -Now when you want to use =virtualbox= just load the kernel module - -#+begin_src fish -~ -> sudo modprobe vboxdrv -#+end_src - -and add the user which is supposed to run ~> virtualbox~ to the -=vboxusers= group - -#+begin_src fish -~ -> sudo usermod -a G vboxusers $USER -#+end_src - -and if you want to use =rawdisk= functionality, also to the =disk= group - -#+begin_src fish -~ -> sudo usermod -a G disk $USER -#+end_src - -Now just re-login and you're good to go. - -*** Gaming - -=extra= & =pulseaudio pulseaudio-alsa=\\ -=community= & =lutris=\\ -=multilib= & =lib32-libpulse lib32-nvidia-utils steam=\\ - -The first option for native/emulated gaming on Linux is obviously -=steam=. - -The second option would be =lutris=, a program, that configures a wine -instance correctly, etc. - -*** Wacom - -=extra= & =libwacom xf86-input-wacom=\\ - -In order to use a Wacom graphics tablet, you'll have to install some -packages - -You can now configure your tablet using the =xsetwacom= command. - -*** =VNC= & =RDP= - -=extra= & =libvncserver=\\ -=community= & =remmina=\\ -=AUR= & =freerdp=\\ - -In order to connect to a machine over =VNC= or to connect to a machine -using the =Remote Desktop Protocol=, for example to connect to a Windows -machine, I'll need to install =freerdp=^{=AUR=}, as well as -=libvncserver=, for =RDP= and =VNC= functionality respectively, as well -as =remmina=, to have a GUI client for those two protocols. - -Now you can set up all your connections inside =remmina=. - -* 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_src fish -~ -> sudo pacman -Syu -#+end_src - -That's both true and false. - -You have to make sure, /that your boot partition is mounted at =/boot=/ -in order for everything to upgrade correctly. That's because the moment -you upgrade the =linux= package without having the correct partition -mounted at =/boot=, your system won't boot. You also might have to do -~> grub-mkconfig -o /boot/grub/grub.cfg~ after you install a different -kernel image. - -If your system /indeed doesn't boot/ and /boots to a recovery fish/, -then double check that the issue really is the not perfectly executed -kernel update by issuing - -#+begin_src fish -root in ~ -> uname -a -#+end_src - -and - -#+begin_src fish -root in ~ -> pacman -Q linux -#+end_src - -/The version of these two packages should be exactly the same!/ - -If it isn't there is an easy fix for it. - -** Fixing a faulty kernel upgrade -First off we need to restore the old =linux= package. - -For that note the version number of - -#+begin_src fish -root in ~ -> uname -a -#+end_src - -Now we'll make sure first that nothing is mounted at =/boot=, because -the process will likely create some unwanted files. The process will -also create a new =/boot= folder, which we're going to delete -afterwards. - -#+begin_src fish -root in ~ -> umount /boot -#+end_src - -Now =cd= into =pacman='s package cache - -#+begin_src fish -root in ~ -> cd /var/cache/pacman/pkg -#+end_src - -There should be a file located named something like =linux-.pkg.tar.xz=, where == would be somewhat equivalent to the previously noted version number - -Now downgrade the =linux= package - -#+begin_src fish -root in ~ -> pacman -U linux-.pkg.tar.xz -#+end_src - -After that remove the possibly created =/boot= directory - -#+begin_src fish -root in ~ -> rm -rf /boot - -root in ~ -> mkdir /boot -#+end_src - -Now reboot and mount the =boot= partition, in my case an EFI System -partition. - -Now simply rerun - -#+begin_src fish -~ -> sudo pacman -Syu -#+end_src - -and you should be fine now. - -* Additional notes -If you've printed this guide, you might want to add some additional -blank pages for notes. diff --git a/DustArch.typ b/DustArch.typ index 0a4ac3a..f0a8c4e 100644 --- a/DustArch.typ +++ b/DustArch.typ @@ -1,114 +1,23 @@ -#let border_block(color, content) = block( - align(left, content), - stroke: .25em + rgb(color), - inset: 1em, - radius: .5em, - width: 100% -) -#let fill_block(color, content) = block( - align(left, content), - fill: rgb(color), - inset: 1em, - radius: .5em, - width: 100% -) +#import "dustypst/dustypst.typ": admindoc_project, note, important, tip, warning, caution, linkfn, filepath, terminal-root, terminal, cmd, pkg-aur, pkgtable, filesrc, codeblock, pkg -#let border_box(color, content) = box( - content, - stroke: .25em + rgb(color), - inset: .25em, - radius: .25em -) -#let fill_box(color, content) = box( - content, - fill: rgb(color), - inset: .25em, - radius: .25em -) - -#set text(font: "DejaVu Sans", size: 12pt) - -#set document( +#show: admindoc_project.with( title: "DustArch", - author: "DustVoice" + subtitle: "DustVoice's Arch Linux from scratch", ) -#set page( - paper: "a5", - header: align( - center, - block(spacing: 0pt)[ - #text(1.5em, fill: rgb("#ff79c6"))[DustArch]\ - #text(0.5em, fill: rgb("#bd93f9"))[DustVoice's Arch Linux from scratch] - ] - ), - numbering: none -) - -#set par(justify: true) - -#set figure(numbering: none) - -#set heading(numbering: "1.1.") - -#let code(lang: "", content) = raw(lang: lang, block: false, content) -#let cmd(content) = code(lang: "fish", content) - -#let _path(content) = fill_box("#8be9fd", content) -#let path(content) = _path(raw(content)) - -#let filesrc(filename, content) = figure( - caption: path(filename), - border_block("#8be9fd", content) -) - -#let pkgtable(core, extra, community, aur) = figure( - table( - columns: 4, - align: center, - [*core*], [*extra*], [*community*], [*AUR*], - core, extra, community, aur - ) -) - -#let NOTE(content) = figure()[ - #border_block("#6272a4", content) -] -#let TIP(content) = figure()[ - #border_block("#f1fa8c", content) -] -#let IMPORTANT(content) = figure()[ - #border_block("#ff5555", content) -] -#let WARNING(content) = figure()[ - #border_block("#ffb86c", content) -] -#let CAUTION(content) = figure()[ - #border_block("#ff79c6", content) -] - -// CONTENT START - -#outline(indent: true) - -#show heading: heading => { - pagebreak() - text(1.25em, heading) -} - = 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 (`archiso`). -#NOTE[ +#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 `archiso` doesn't have all packages available from cache, especially the ones that need to be installed from the `AUR`. / AUR (Arch User Repository): - A huge collection of packages, contributed and maintained by the community, which in order to install you need to download and build.\ - Accessable and browsable under #link("https://aur.archlinux.org/")[aur.archlinux.org]. + A huge collection of packages contributed and maintained by the community, which in order to install you need to download and build.\ + Accessable and browsable under #linkfn("https://aur.archlinux.org/")[aur.archlinux.org]. 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 #link("https://wiki.archlinux.org/")[ArchWiki], or the #link("https://bbs.archlinux.org/")[Arch Linux forums]. + If you encounter any problems along the way, you will either have to resolve the issue yourself or utilize the great #linkfn("https://wiki.archlinux.org/")[ArchWiki], or the #linkfn("https://bbs.archlinux.org/")[Arch Linux forums]. ] To get some explanation on how this document is formatted, look into the @glossary @@ -116,95 +25,64 @@ To get some explanation on how this document is formatted, look into the @glossa == Syncing up `pacman` -First of all we need to sync up `pacman`'s package repository, in order to be able to install the latest, as well as new packages to the `archiso` and our new system. +First of all, we need to sync up `pacman`'s package repository, in order to be able to install the latest, as well as new packages to the `archiso` and our new system. -```fish -> pacman -Sy -``` +#terminal-root("/")[`pacman -Sy`] -#WARNING[ - Using #cmd("> pacman -Sy") should be sufficient, in order to be able to search for packages from within the `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 #cmd("> pacman -Syu") instead! - - `pacstrap` uses the latest packages anyways. +#warning[ + Using #cmd[`pacman -Sy`] should be sufficient, in order to be able to search for packages from within the `archiso`, without upgrading the system, but might break your system, if you use this command on an existing installation! + + #cmd[pacstrap] uses the latest packages anyways. +] +#caution[ + To be on the safe side, it is advised to always use #cmd[`pacman -Syu`]! + + Only on the `archiso` is there an exception to be made, as #cmd[`pacman -Syu`] will probably fail due to `RAM` limitations! ] === Official repositories After doing that, we can now install any software from the official repositories by issuing -```fish -root in / -> pacman -S -``` +#terminal-root("/")[`pacman -S `] where you would replace `` with the actual package name. -If you want to remove an installed package, just use +If you want to remove an installed package, use -```fish -root in / -> pacman -Rsu -``` +#terminal-root("/")[`pacman -Rsu `] -If you don't know the exact package name, or if you just want to search for a keyword, for example `xfce`, to list all packages having something to do with `xfce`, use +If you don't know the exact package name, or if you just want to search for a keyword, for example, `xfce`, to list all packages having something to do with `xfce`, use -```fish -root in / -> pacman -Ss -``` +#terminal-root("/")[`pacman -Ss `] If you really need to force remove a package, which you should use _with extreme caution_, you could use -```fish -root in / -> pacman -Rdd -``` +#terminal-root("/")[`pacman -Rdd `] === `AUR` -If you want to install a package from the #link("https://aur.archlinux.org/")[AUR], I would advise proceeding in the following manner, in order to install the `AUR`-helper #link("https://aur.archlinux.org/packages/paru")[paru]. +If you want to install a package from the #linkfn("https://aur.archlinux.org/")[AUR], I would advise proceeding in the following manner, in order to install the `AUR`-helper #pkg-aur("paru") or alternatively #pkg-aur("paru-bin"). #enum[ Clone the package with `git` + #terminal("~")[`git clone https://aur.archlinux.org/paru.git`] -```fish -~ -> git clone https://aur.archlinux.org/paru.git + If you are on a slow PC or don't want to compile `paru` from scratch, you can also use the #linkfn("https://aur.archlinux.org/packages/paru-bin")[paru-bin]. +][ + Switch to the package directory +][ + Execute #cmd[`makepkg`] with the appropriate argments + #terminal("~/paru")[`makepkg -si`] +][ + Delete all files created, as `paru` will now be handling all the `AUR` stuff. -``` + #terminal("~/paru")[ + `cd ..` - If you are on a slow PC, or don't want to compile `paru` from scratch, you can also use #link("https://aur.archlinux.org/packages/paru-bin")[paru-bin]. - ][ - Switch to the package directory - -```fish -~ -> cd paru - -``` - ][ - Execute #cmd("> makepkg") - -```fish -~/paru -> makepkg -si - -``` - ][ - Delete all files created, as `paru` will now be handling all the - `AUR` stuff. - -```fish -~/paru -> cd .. - -~ -> rm -rf paru - -``` - ] + `rm -rf paru` + ] +] If you only install `AUR` packages the manual way, you might have to resolve some `AUR` dependencies manually, which can't be automatically resolved by `makepkg`'s `-s` option, which uses `pacman`. @@ -212,9 +90,9 @@ In order to install a desired `AUR` package, you _must_ switch to your normal, n === Software categories -In this guide, software is categorized in three different categories +In this guide, the software is categorized into three different categories -/ `console`: Intended to be used with either the native linux console, or with a terminal emulator +/ `console`: Intended to be used with either the native linux console or with a terminal emulator / `GUI`: Intended to be used within a graphical desktop environment @@ -226,7 +104,7 @@ In this guide, I'll be explicitly listing the packages installed in a specific s This allows you to -- clearly see what packages get installed / need to be installed in a specific section +- clearly see what packages get installed/need to be installed in a specific section - install packages before you start with the section in order to minimize waiting time @@ -236,54 +114,27 @@ For further clarification for specific packages (e.g. `UEFI` specific packages), Of course, as always, you can and *should* adapt everything according to your needs, as this guide is, again, _no tutorial, but a guide_. -==== Example section - -#pkgtable( - "libutil-linux", - - "git", - - "ardour - cadence - jsampler - linuxsampler - qsampler - sample-package", - - "sbupdate" -) -You have to configure `sample-package`, by editing #path("/etc/sample.conf") - -#filesrc("/etc/sample.conf")[ -``` -Sample.text=useful -``` -] - == Formatting the drive First, you probably want to get a list of all available drives, together with their corresponding device name, by issuing -```fish -root in / -> fdisk -l -``` +#terminal-root("/")[`fdisk -l`] -The output of #cmd("> fdisk -l") is dependent on your system configuration and many other factors, like `BIOS` initialization order, etc. +The output of #cmd[`fdisk -l`] is dependent on your system configuration and many other factors, like the `BIOS` initialization order, etc. -#CAUTION[ +#caution[ Don't assume the same path of a device between reboots! - Always double check! + Always double-check! There is nothing worse than formatting a drive you didn't mean to format! ] === The standard way -In my case, the partition I want to install the root file system on will be `/dev/mapper/DustPortable`, which is an unlocked `luks2` volume which will be located on `/dev/sda2`. For my `swap`, I will use a swapfile. +In my case, the partition I want to install the root file system on will be #filepath("/dev/mapper/DustPortable"), which is an unlocked `luks2` volume that will be located on #filepath("/dev/sda2"). For my `swap`, I will use a `swapfile`. -#NOTE[ +#note[ A `swap` size twice the size of your RAM is recommended by a lot of people. To be exact, every distribution has different recommendations for `swap` sizes. Also `swap` size heavily depends on whether you want to be able to hibernate, etc. @@ -293,281 +144,236 @@ In my case, the partition I want to install the root file system on will be `/de You should make the `swap` size at least your RAM size and for RAM sizes over `4GB` with the intention to hibernate, at least one and a half times your RAM size. -If you haven't yet partitioned your disk, please refer to the #link("https://wiki.archlinux.org/index.php/Partitioning")[general partitioning tutorial] in the ArchWiki. +If you haven't yet partitioned your disk, please refer to the #linkfn("https://wiki.archlinux.org/index.php/Partitioning")[general partitioning tutorial] in the ArchWiki. === Full system encryption -#NOTE[ +#note[ This is only one way to do it (read: it is the way I have previously done it). ] I'm using a `LUKS` setup, with `btrfs` and `luks2`. -For more information look into the #link("https://wiki.archlinux.org/")[ArchWiki]. +For more information look into the #linkfn("https://wiki.archlinux.org/")[ArchWiki]. This setup has different partitions, used for the `EFI System Partition`, `root` partition, etc. compared to the ones used in the rest of the guide. -The only part of the guide, which currently uses the drives & partitions used in this section is #link("*The manual way"). +The only part of the guide, which currently uses the drives & partitions used in this section is @manual-secure-boot. To start things, we first have to decide, which disk, or partition, is going to be `luks2` encrypted. -In my case I'll be using my SSD in an USB-C enclosure to be ablet to take the system with me on the go. -For that I will use a `GPT` partition scheme. -I will then create a `2 GiB` `EFI System partition` (I have multiple kernels installed at a time), in my case `/dev/sda1`, defined as a `EFI System partition` type in `gdisk`, as well as the main `luks2` volume, in my case `/dev/sda2`, defined as a `Linux filesystem` partition type in `gdisk`. +In my case, I'll be using my SSD in a USB-C enclosure to be able to take the system with me on the go. +For that, I will use a `GPT` partition scheme. +I will then create a `2 GiB` `EFI System partition` (I have multiple kernels installed at a time), in my case #filepath("/dev/sda1"), defined as an `EFI System partition` type in `gdisk`, as well as the main `luks2` volume, in my case #filepath("/dev/sda2"), defined as a `Linux filesystem` partition type in `gdisk`. After partitioning our disk, we now have to set everything up. ==== `EFI System Partition` -#pkgtable("dosfstools", "", "", "") +#pkgtable(core: "dosfstools") -I won't setup my `EFI System Partition` with `cryptsetup`, as it makes no sense in my case. +I won't set up my `EFI System Partition` with `cryptsetup`, as it makes no sense in my case. -Every `EFI` binary (or `STUB`) will have to be signed with my custom Secure Boot keys, as described in #link("*The manual way"), so tempering with the `EFI System Partition` poses no risk to my system. +Every `EFI` binary (or `STUB`) will have to be signed with my custom Secure Boot keys, as described in @manual-secure-boot, so tempering with the `EFI System Partition` poses no risk to my system. -Instead I will simply format it with a `FAT32` filesystem +Instead, I will simply format it with a `FAT32` filesystem -```fish -root in / -> mkfs.fat -F 32 -n EFI /dev/sda1 -``` +#terminal-root("/")[`mkfs.fat -F 32 -n EFI /dev/sda1`] We will bother with mounting it later on. When you _do_ want to encrypt your `EFI System Partition`, in conjunction with e.g. `grub`, please either use `LUKS 1`, or make sure to have the latest version of `grub` installed on your system, to make it work with `LUKS 2`! -I will use `limine` though, so for me all of this isn't a consideration. +I will use `limine` though, so for me, all of this isn't a consideration. ==== `LUKS` -#pkgtable("cryptsetup", "", "", "") +#pkgtable(core: "cryptsetup") First off we have to create the `LUKS` volume -```fish -root in / -> cryptsetup luksFormat --type luks2 /dev/sda2 -``` +#terminal-root("/")[`cryptsetup luksFormat --type luks2 /dev/sda2`] -In my case, I will convert the keyslot to `pbkdf2`, as `luks2` defaults to `argon2id`, which doesn't play well with my portable setup, namely the differing RAM sizes. +In my case, I will convert the key slot to `pbkdf2`, as `luks2` defaults to `argon2id`, which doesn't play well with my portable setup, namely the differing RAM sizes. -#NOTE[ - / pbkdf: Password-Based Key Derivation Function -] -```fish -root in / -> cryptsetup luksConvertKey --pbkdf pbkdf2 /dev/sda2 -``` +#terminal-root("/")[`cryptsetup luksConvertKey --pbkdf pbkdf2 /dev/sda2`] -After that we have to open the volume +/ pbkdf: Password-Based Key Derivation Function -```fish -root in / -> cryptsetup open /dev/sda2 DustPortable -``` +After that, we have to open the volume -The volume is now accessible under `/dev/mapper/DustPortable`. +#terminal-root("/")[`cryptsetup open /dev/sda2 DustPortable`] + +The volume is now accessible under #filepath("/dev/mapper/DustPortable"). ==== `btrfs` -#pkgtable("btrfs-progs", "", "", "") +#pkgtable(core: "btrfs-progs") -Fist off we need to create the filesystem +First off we need to create the filesystem -```fish -root in / -> mkfs.btrfs -L DustPortable /dev/mapper/DustPortable -``` +#terminal-root("/")[`mkfs.btrfs -L DustPortable /dev/mapper/DustPortable`] -After that we mount the `btrfs` root under `/mnt/meta` +After that, we mount the `btrfs` root under #filepath("/mnt/meta") -```fish -root in / -> mkdir /mnt/meta - -root in / -> mount /dev/mapper/DustPortable /mnt/meta -``` +#terminal-root("/")[ + ``` + mkdir /mnt/meta + + mount /dev/mapper/DustPortable /mnt/meta + ``` +] Now we create the desired filesystem layout. -We will create 5 top level subvolumes that will be mounted at the appropriate places later on. +We will create 5 top-level subvolumes that will be mounted at the appropriate places later on. -```fish -root in /mnt/meta -> btrfs subvolume create @ -root in /mnt/meta -> btrfs subvolume create @home - -root in /mnt/meta -> btrfs subvolume create @snapshots - -root in /mnt/meta -> btrfs subvolume create @var_log - -root in /mnt/meta -> btrfs subvolume create @swapfile -``` +#terminal-root("/mnt/meta")[ + ``` + btrfs subvolume create @ + + btrfs subvolume create @home + + btrfs subvolume create @snapshots + + btrfs subvolume create @var_log + + btrfs subvolume create @swapfile + ``` +] == Preparing the `chroot` environment -As a first step it might make sense to edit `/etc/pacman.d/mirrorlist` to move the mirrors geographically closest to you to the top. +As a first step, it might make sense to edit the #filepath("/etc/pacman.d/mirrorlist") to move the mirrors geographically closest to you to the top. === `pacstrap` in -Generally we need to `pacstrap` the _minimum packages_ needed. +Generally, we need to `pacstrap` the _minimum packages_ needed. We will install all other packages later on. #pkgtable( - "base - base-devel - linux - linux-firmware", - "", - "", - "" + core: "base base-devel linux linux-firmware", ) This is the actual command used in my case -```fish -root in / -> pacstrap /mnt/meta/@ base base-devel linux linux-firmware -``` +#terminal-root("/")[`pacstrap /mnt/meta/@ base base-devel linux linux-firmware`] === Mounting party Now we have to mount the subvolumes and boot partition we created earlier to the appropriate locations. -First off, we mount the `/` subvolume `@` +First off, we mount the #filepath("/") subvolume `@` -```fish -root in / -> mkdir /mnt/DustPortable +#terminal-root("/")[ + ``` + mkdir /mnt/DustPortable + + mount -o subvol=@ /dev/mapper/DustPortable /mnt/DustPortable + ``` +] -root in / -> mount -o subvol=@ /dev/mapper/DustPortable /mnt/DustPortable -``` +Now we can mount the #filepath("/home") subvolume `@home` -Now we can mount the `/home` subvolume `@home` +#terminal-root("/mnt/DustPortable")[`mount -o subvol=@home /dev/mapper/DustPortable home`] -```fish -root in /mnt/DustPortable -> mount -o subvol=@home /dev/mapper/DustPortable home -``` +The #filepath("/.snapshots") subvolume `@snapshots` closely follows -The `/.snapshots` subvolume `@snapshots` closely follows +#terminal-root("/")[ + ``` + mkdir .snapshots + + mount -o subvol=@snapshots /dev/mapper/DustPortable .snapshots + ``` +] -```fish -root in /mnt/DustPortable -> mkdir .snapshots +After that we have to move the log dir #filepath("/var/log") to the appropriate subvolume `@var_log` -root in /mnt/DustPortable -> mount -o subvol=@snapshots /dev/mapper/DustPortable .snapshots -``` +#terminal-root("/mnt/DustPortable")[ + ``` + mv var/log var/log_bak + + mount -o subvol=@var_log /dev/mapper/DustPortable var/log + + mkdir var/log + + mv var/log_bak/* var/log/ + + rmdir var/log_bak + ``` +] -After that we have to move the log dir `/var/log` to the appropriate subvolume `@var_log` +Finally, we can generate the `swapfile` -```fish -root in /mnt/DustPortable -> mv var/log var/log_bak +#terminal-root("/mnt/DustPortable")[ + ``` + mkdir swapfile + + mount -o subvol=@swapfile /dev/mapper/DustPortable swapfile + + btrfs filesystem mkswapfile --size 128G swapfile/swapfile + + swapon swapfile/swapfile + ``` +] -root in /mnt/DustPortable -> mount -o subvol=@var_log /dev/mapper/DustPortable var/log - -root in /mnt/DustPortable -> mkdir var/log - -root in /mnt/DustPortable -> mv var/log_bak/* var/log/ - -root in /mnt/DustPortable -> rmdir var/log_bak -``` - -Finally we can generate the `swapfile` - -```fish -root in /mnt/DustPortable -> mkdir swapfile - -root in /mnt/DustPortable -> mount -o subvol=@swapfile /dev/mapper/DustPortable swapfile - -root in /mnt/DustPortable -> btrfs filesystem mkswapfile --size 128G swapfile/swapfile - -root in /mnt/DustPortable -> swapon swapfile/swapfile -``` - -#IMPORTANT[ +#important[ I use my SSD inside a USB-C enclosure (although it is rated at 40Gbps it is *not* Thunderbolt 3!), which means that it _doesn't_ support `TRIM`. This is why I personally need to add `nodiscard` to every `mount` command option, which would look something along the lines of this -```fish -root in / -> mount -o subvol=@,nodiscard /dev/mapper/DustPortable /mnt/DustPortable -``` + #terminal-root("/")[ + `mount -o subvol=@,nodiscard /dev/mapper/DustPortable /mnt/DustPortable` + ] ] -The only thing left to do now is mounting the boot partition, namely my `EFI System Partition` +The only thing left to do now is mount the boot partition, namely my `EFI System Partition` -```fish -root in /mnt/DustPortable -> mv boot boot_bak +#terminal-root("/mnt/DustPortable")[ + ``` + mv boot boot_bak + + mkdir boot + + mount /dev/sda1 boot + + mv boot_bak/* boot/ + + rmdir boot_bak + ``` +] -root in /mnt/DustPortable -> mkdir boot +After that we can generate the #filepath("/etc/fstab") using `genfstab` -root in /mnt/DustPortable -> mount /dev/sda1 boot - -root in /mnt/DustPortable -> mv boot_bak/* boot/ - -root in /mnt/DustPortable -> rmdir boot_bak -``` - -After that we can generate the `/etc/fstab` using `genfstab` - -```fish -root in / -> genfstab -U /mnt/DustPortable >> /mnt/DustPortable/etc/fstab -``` +#terminal-root("/")[ + `genfstab -U /mnt/DustPortable >> /mnt/DustPortable/etc/fstab` +] and you're ready to enter the `chroot` environment. === Outdated `archiso` -If you're using an older version of the `archiso`, you might want to replace the mirrorlist present on the `archiso` with the newest #link("https://archlinux.org/mirrorlist/all")[online one] +If you're using an older version of the `archiso`, you might want to replace the `mirrorlist` present on the `archiso` with the newest #linkfn("https://archlinux.org/mirrorlist/all")[online one] -```fish -root in / -> curl https://archlinux.org/mirrorlist/all > /etc/pacman.d/mirrorlist -``` +#terminal-root("/")[ + `curl https://archlinux.org/mirrorlist/all > /etc/pacman.d/mirrorlist` +] -#pkgtable("", "", "reflector", "") +#pkgtable(extra: "reflector") -The best way to do this tho, is using a package from the official repositories named `reflector`. +The best way to do this tho is using a package from the official repositories named `reflector`. It comes with all sorts of options, for example sorting mirrors by speed, filtering by country, etc. -```fish -root in / -> reflector --verbose --latest 200 --sort rate --save /etc/pacman.d/mirrorlist -``` +#terminal-root("/")[ + `reflector --verbose --latest 200 --sort rate --save /etc/pacman.d/mirrorlist` +] -After that you would need to reinstall the `pacman-mirror` package and +After that, you would need to reinstall the `pacman-mirror` package and run -```fish -root in / -> pacman -Syyuu -``` +#terminal-root("/")[`pacman -Syyuu`] for best results. -#CAUTION[ +#caution[ Be wary though as there could arise keyring issues etc. Normally the `pacstrap` command takes care of syncing everything etc. ] @@ -575,155 +381,118 @@ for best results. === Living behind a proxy If you're sitting behind a proxy, you're generally in for an unpleasant time. -Generally you need to set the `http_proxy`, `https_proxy`, `ftp_proxy` variables as well as their *upper case* counterparts. +Generally, you need to set the `http_proxy`, `https_proxy`, `ftp_proxy` variables as well as their *upper case* counterparts. -```fish -root in / -> export http_proxy="http://ldiproxy.lsjv.rlp.de:8080" +#terminal-root("/")[ + ``` + export http_proxy="http://ldiproxy.lsjv.rlp.de:8080" + + export https_proxy=$http_proxy + + export ftp_proxy=$http_proxy + + export HTTP_PROXY=$http_proxy + + export HTTPS_PROXY=$http_proxy + + export FTP_PROXY=$http_proxy + ``` +] -root in / -> export https_proxy=$http_proxy +If you can't `pacstrap` after that, you probably have the issue that the `systemd-timesyncd`, as well as the `pacman-init` service didn't execute correctly. -root in / -> export ftp_proxy=$http_proxy - -root in / -> export HTTP_PROXY=$http_proxy - -root in / -> export HTTPS_PROXY=$http_proxy - -root in / -> export FTP_PROXY=$http_proxy -``` - -If you can't `pacstrap` after that, you probaby have the issue thatthe `systemd-timesyncd`, as well as `pacman-init` service didn't execute correctly. - -```fish -root in / -> systemctl status systemd-timesyncd.service - -root in / -> systemctl status pacman-init.service -``` +#terminal-root("/")[ + ``` + systemctl status systemd-timesyncd.service + + systemctl status pacman-init.service + ``` +] To mitigate this, you need to initialize `pacman` yourself. First off check whether the correct time is set. -```fish -root in / -> timedatectl -``` +#terminal-root("/")[`timedatectl`] In my case the time zone was not correctly set, why my time was off by one hour, so I had to set it manually. -```fish -root in / -> timedatectl set-timezone Europe/Berli -``` +#terminal-root("/")[`timedatectl set-timezone Europe/Berlin`] -After that we have to execute the `pacman-init` stuff manually +After that, we have to execute the `pacman-init` stuff manually -```fish -root in / -> pacman-key --init +#terminal-root("/")[ + ``` + pacman-key --init + + pacman-key --populate + ``` +] -root in / -> pacman-key --populate -``` +#note[ + You might also want to add the following lines to #filepath("/etc/sudoers"), in order to keep the proxy environment variables alive when executing a command through `sudo` -#NOTE[ - You might also want to add the following lines to `/etc/sudoers`, in order to keep the proxy environment variables alive when executing a command through `sudo` - - #filesrc("/etc/sudoers")[ -``` -Defaults env_keep += "http_proxy" -Defaults env_keep += "https_proxy" -Defaults env_keep += "ftp_proxy" -Defaults env_keep += "HTTP_PROXY" -Defaults env_keep += "HTTPS_PROXY" -Defaults env_keep += "FTP_PROXY" -``` + #filesrc(part: true, "/etc/sudoers")[ + ``` + Defaults env_keep += "http_proxy" + + Defaults env_keep += "https_proxy" + + Defaults env_keep += "ftp_proxy" + + Defaults env_keep += "HTTP_PROXY" + + Defaults env_keep += "HTTPS_PROXY" + + Defaults env_keep += "FTP_PROXY" + ``` ] ] -// #+end_NOTE = Entering the `chroot` -#pkgtable("", "arch-install-scripts", "", "") +#pkgtable(extra: "arch-install-scripts") -#NOTE[ +#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 `chroot`. - That's why we are using `arch-chroot`, provided by the `arch-install-scripts` package, which is shipped with the `archiso`. This script takes care of all the afforementioned stuff, so we can set up our system properly. + That's why we are using `arch-chroot`, provided by the `arch-install-scripts` package, which is shipped with the `archiso`. This script takes care of all the aforementioned stuff, so we can set up our system properly. ] -```fish -root in / -> arch-chroot /mnt/DustPortable -``` +#terminal-root("/")[`arch-chroot /mnt/DustPortable`] -Et Voil ! You successfully `chroot`-ed inside your new system and you'll be greeted by a `bash` prompt, which is the default shell on fresh Arch Linux installations. +Et Voila! You successfully `chroot`-ed inside your new system and you'll be greeted by a `bash` prompt, which is the default shell on fresh Arch Linux installations. == Installing additional packages #pkgtable( - "amd-ucode - base-devel - btrfs-progs - diffutils - dmraid - dnsmasq - dosfstools - efibootmgr - emacs-nativecomp - exfat-utils - iputils - linux-headers - openssh - sudo - usbutils", - - "efitools - git - intel-ucode - networkmanager - networkmanager-openconnect - networkmanager-openvpn - parted - polkit - rsync - zsh", - - "fish - neovim", - - "limine" + core: "amd-ucode base-devel btrfs-progs diffutils dmraid dnsmasq dosfstools efibootmgr emacs-nativecomp exfat-utils iputils linux-headers openssh sudo usbutils", + extra: "efitools fish git intel-ucode neovim networkmanager networkmanager-openconnect networkmanager-openvpn nushell parted polkit rsync zsh", + aur: "limine", ) -There are many command line text editors available, like `nano`, `vi`, -`vim`, `emacs`, etc. +#note[ + There are many command line text editors available, like `nano`, `vi`, `vim`, `emacs`, etc. -I'll be using `neovim` as my simple text editor, until a certain point, at which I'll replace it with my doom-`emacs` setup, though it shouldn't matter what editor you choose for the rest of the guide. + I'll be using `neovim` as my simple text editor, until a certain point, at which I'll replace it with my doom-`emacs` setup, though it shouldn't matter what editor you choose for the rest of the guide. +] Make sure to enable the `NetworkManager.service` service, in order for the Internet connection to work correctly, upon booting into the fresh system later on. -```fish -root in / -> systemctl enable NetworkManager.service -``` +#terminal-root("/")[`systemctl enable NetworkManager.service`] -With `polkit` installed, create a file to enable users of the `network` group to add new networks without the need of `sudo`. +With `polkit` installed, create a file to enable users of the `network` group to add new networks without the need for `sudo`. #filesrc("/etc/polkit-1/rules.d/50-org.freedesktop.NetworkManager.rules")[ -``` -polkit.addRule(function(action, subject) { - if (action.id.indexOf("org.freedesktop.NetworkManager.") `` 0 && subject.isInGroup("network")) { - return polkit.Result.YES; - } -}); -``` + ``` + polkit.addRule(function(action, subject) { + if (action.id.indexOf( + "org.freedesktop.NetworkManager." + ) == 0 && subject.isInGroup("network")) { + return polkit.Result.YES; + } + }); + ``` ] If you use `UEFI`, you'll also need the `efibootmgr`, in order to modify the `UEFI` entries. @@ -731,20 +500,12 @@ If you use `UEFI`, you'll also need the `efibootmgr`, in order to modify the `UE === Additional kernels #pkgtable( - "linux-lts - linux-lts-headers - linux-zen - linux-zen-headers", - - "linux-hardened - linux-hardened-headers", - - "", - "" + core: "linux-lts linux-lts-headers linux-zen linux-zen-headers", + extra: "linux-hardened linux-hardened-headers", ) In addition to the standard `linux` kernel, there are a couple of different options out there. -Just to name a few, there is `linux-lts`, `linux-zen` and `linux-hardened`. +Just to name a few, there are `linux-lts`, `linux-zen`, and `linux-hardened`. You can simply install them and then add the corresponding `initramfs` and kernel image to your bootloader entries. @@ -754,197 +515,202 @@ Make sure you have allocated enough space on your `EFI System Partition` though. After that, you have to set your timezone and update the system clock. -Generally speaking, you can find all the different timezones under `/usr/share/zoneinfo`. +Generally speaking, you can find all the different timezones under #filepath("/usr/share/zoneinfo"). -In my case, my timezone file resides under `/usr/share/zoneinfo/Europe/Berlin`. +In my case, my timezone file resides under #filepath("/usr/share/zoneinfo/Europe/Berlin"). -To achieve the desired result, I will want to symlink this to `/etc/localtime` and set the hardware clock. +To achieve the desired result, I will want to symlink this to the #filepath("/etc/localtime") and set the hardware clock. -```fish -root in / -> ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime +#terminal-root("/")[ + ``` + ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime + + hwclock --systohc --utc + ``` +] -root in / -> hwclock --systohc --utc -``` +Now you can also enable time synchronization over the network -Now you can also enable time synchronization over network - -```fish -root in / -> timedatectl set-timezone Europe/Berlin - -root in / -> timedatectl set-ntp true -``` +#terminal-root("/")[ + ``` + timedatectl set-timezone Europe/Berlin + + timedatectl set-ntp true + ``` +] and check that everything is alright -```fish -root in / -> timedatectl status -``` +#terminal-root("/")[`timedatectl status`] == Master of locales Now you have to generate your locale information. -For that you have to edit `/etc/locale.gen` and uncomment the locales +For that you have to edit #filepath("/etc/locale.gen") and uncomment the locales you want to enable. -I recommend to always uncomment `en_US.UTF-8 UTF8`, even if you want to +I recommend always uncomment `en_US.UTF-8 UTF8`, even if you want to use another language primarily. -In my case I only uncommented the `en_US.UTF-8 UTF8` line +In my case, I only uncommented the `en_US.UTF-8 UTF8` line -```fish -en_US.UTF-8 UTF8 -``` +#filesrc(part: true, "/etc/locale.gen")[ + ``` + en_US.UTF-8 UTF8 + ``` +] -After that you still have to actually generate the locales by issuing +After that, you still have to actually generate the locales by issuing -```fish -root in / -> locale-gen -``` +#terminal-root("/")[`locale-gen`] and set the locale -```fish -root in / -> localectl set-locale LANG="en_US.UTF-8" -``` +#terminal-root("/")[ + `localectl set-locale LANG="en_US.UTF-8"` +] -After that we're done with this part. +After that, we're done with this part. == Naming your machine Now we can set the `hostname` for our new install and add `hosts` entries. -Apart from being mentioned in your command prompt, the `hostname` also serves the purpose of identifying, or naming your machine locally, as well as in a networked scenario. +Apart from being mentioned in your command prompt, the `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. === `hostname` -To change the `hostname`, simply edit `/etc/hostname`, enter the desired name, then save and quit +To change the `hostname`, simply edit #filepath("/etc/hostname"), enter the desired name, then save and quit -```fish -DustArch -``` +#filesrc("/etc/hostname")[ + ``` + DustArch + ``` +] === `hosts` -Now we need to specify some `hosts` entries by editing `/etc/hosts` +Now we need to specify some `hosts` entries by editing #filepath("/etc/hosts") -```fish -// # Static table lookup for hostnames. -// # See hosts(5) for details. - -127.0.0.1 localhost . -::1 localhost . -127.0.1.1 DustArch.localhost DustArch -``` +#filesrc("/etc/hosts")[ + ``` + // # Static table lookup for hostnames. + // # See hosts(5) for details. + + 127.0.0.1 localhost . + ::1 localhost . + 127.0.1.1 DustArch.localhost DustArch + ``` +] == User setup -Now you should probably change the default `root` password and create a new non-`root` user for yourself, as using your new system purely through the native `root` user is not recommended from a security standpoint. +Now you should probably change the default `root` password and create a new non-`root` user, as using your new system purely through the native `root` user is not recommended from a security standpoint. === Give `root` a password To change the password for the current user (the `root` user) issue -```fish -root in / -> passwd -``` +#terminal-root("/")[`passwd`] and choose a new password. === Create a personal user #pkgtable( - "sudo - bash", - "", - "", - "" + core: "sudo bash", ) -We are going to create a new user and set the password, groups and shell for this user +We are going to create a new user and set the password, groups, and shell for this user -```fish -root in / -> useradd -m -p "" -G "adm,audio,disk,floppy,kvm,log,lp,network,rfkill,scanner,storage,users,optical,power,wheel" -s /bin/bash dustvoice +#terminal-root("/")[ + ``` + useradd -m -p "" -G "adm,audio,disk,floppy,kvm, + log,lp,network,rfkill,scanner,storage, + users,optical,power,wheel" -s /bin/bash dustvoice + passwd dustvoice + ``` +] -root in / -> passwd dustvoice -``` +We must now allow the `wheel` group `sudo` access. -We now have to allow the `wheel` group `sudo` access. +We edit the #filepath("/etc/sudoers") file and uncomment the `%wheel` line. -For that we edit `/etc/sudoers` and uncomment the `%wheel` line. - -```fish -%wheel ALL=(ALL) ALL -``` +#filesrc(part: true, "/etc/sudoers")[ + ``` + %wheel ALL=(ALL) ALL + ``` +] You could also add a new line below the `root` line -```fish -root ALL=(ALL) ALL -``` +#filesrc(part: true, "/etc/sudoers")[ + ``` + root ALL=(ALL) ALL + ``` +] with your new username -```fish -dustvoice ALL=(ALL) ALL -``` +#filesrc(part: true, "/etc/sudoers")[ + ``` + dustvoice ALL=(ALL) ALL + ``` +] to solely grant the _new_ user `sudo` privileges. -== Boot manager +== Boot manager -In this section different boot managers / boot methods are explained. +In this section, different boot managers/boot methods are explained. === `EFISTUB` -#pkgtable("efibootmgr ", "", "", "") +#pkgtable(core: "efibootmgr ") You can directly boot the system, by making use of the `EFISTUB` contained in the kernel image. To utilize this, we can use `efibootmgr` to create an entry in the `UEFI` -```fish -root in / -> 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 -``` +#terminal-root("/")[ + ``` + efibootmgr + --disk /dev/sda + --part 2 + --create + --label "Arch Linux" + --loader /vmlinuz-linux + --unicode + 'root= rw initrd=\initramfs-linux.img resume=UUID=' + --verbose + ``` +] -This only makes sense of course, if you're using `UEFI` instead of a legacy `BIOS`. In this case it doesn't matter of course, if your machine _theoretically supports_ `UEFI`, but rather if it is the /enabled mode/! +#warning[ + You need to replace the `<[...]-partition-uuid>` parts with your corresponding values! +] + +This only makes sense of course, if you're using `UEFI` instead of a legacy `BIOS`. In this case, it doesn't matter of course, if your machine _theoretically supports_ `UEFI`, but rather if it is the /enabled mode/! === `grub` #pkgtable( - "dosfstools - efibootmgr - grub", - - "mtools", - - "os-prober", - - "" + core: "dosfstools efibootmgr grub", + extra: "mtools os-prober", ) -Of course you can also use a boot manager to boot the system, as the name implies. +Of course, you can also use a boot manager to boot the system, as the name implies. If I can't use `EFISTUB`, e.g. either because the system has no `UEFI` support, or because I need another feature of a boot manager, I could use `grub`. -#TIP[ +#tip[ Currently, I mainly use `limine` as a boot manager *especially* on my portable setup, as `grub` is *such a huge pain in the butt!* - `limine` is insanely easy to setup and configure, without all the `BIOS Boot partition` crap that I find myself mainly using this. - Refer to #link("*`limine`")" for further information. + `limine` is insanely easy to set up and configure, without all the `BIOS Boot partition` crap that I find myself mainly using this. + Refer to @limine for further information. ] -#NOTE[ +#note[ You'll probably only need the `efibootmgr` package, if you plan to utilize `UEFI`. ] @@ -954,40 +720,37 @@ If you chose the `BIOS - MBR` variation, you'll have to _do nothing special_. If you chose the `BIOS - GPT` variation, you'll have to _have a `+1M` boot partition_ created with the partition type set to `BIOS boot`. -In both cases you'll have to _run the following comman_ now +In both cases, you'll have to _run the following comman_ now -```fish -root in / -> grub-install --target=i386-pc /dev/sdb -``` +#terminal-root("/")[`grub-install --target=i386-pc /dev/sdb`] -It should obvious that you would need to replace `/dev/sdb` with the disk you actually want to use. Note however that you have to specify a _disk_ and _not a partition_, so _no number_. +It should obvious that you would need to replace #filepath("/dev/sdb") with the disk you actually want to use. Note however that you have to specify a _disk_ and _not a partition_, so _no number_. ==== `grub` - `UEFI` -If you chose the `UEFI - GPT` variation, you'll have to _have the `EFI System Partition` mounted_ at `/boot` (where `/dev/sda2` is the partition holding said `EFI System Partition` in my particular setup) +If you chose the `UEFI - GPT` variation, you'd have to _have the `EFI System Partition` mounted_ at #filepath("/boot") (where #filepath("/dev/sda2") is the partition holding said `EFI System Partition` in my particular setup) Now _install `grub` to the `EFI System Partition`_ -```fish -root in / -> grub-install --target x86_64-efi --efi-directory /boot --bootloader-id=grub --recheck -``` +#terminal-root("/")[ + ``` + grub-install + --target x86_64-efi + --efi-directory /boot + --bootloader-id=grub + --recheck + ``` +] -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. +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 `cmd` window as Administrator and type in +In this case, boot into Windows, open a `cmd` window as Administrator, and type in -```fish -bcdedit /set {bootmgr} path \EFI\grub\grubx64.efi -``` +#terminal-root(windows: true, "C:\\Windows\\System32")[`bcdedit /set {bootmgr} path \EFI\grub\grubx64.efi`] To make sure that the path is correct, you can use -```fish -root in / -> ls /boot/EFI/grub -``` +#terminal-root("/")[`ls /boot/EFI/grub`] under Linux to make sure, that the `grubx64.efi` file is really there. @@ -999,46 +762,46 @@ But before we actually generate it, we'll make some changes to the default `grub ===== Adjust the timeout -First of all, I want my `grub` menu to wait indefinitely for my command to boot an OS. +First of all I want my `grub` menu to wait indefinitely for my command to boot an OS. -#filesrc("/etc/default/grub")[ -``` -GRUB_TIMEOUT=-1 -``` +#filesrc(part: true, "/etc/default/grub")[ + ``` + GRUB_TIMEOUT=-1 + ``` ] -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 `grub` menu. +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 `grub` menu. -Of course you can set this parameter to whatever you want. +Of course, you can set this parameter to whatever you want. Another way of achieving what I described, would be to make `grub` remember the last selection. -#filesrc("/etc/default/grub")[ -``` -GRUB_TIMEOUT=5 -GRUB_DEFAULT=saved -GRUB_SAVEDEFAULT="true" -``` +#filesrc(part: true, "/etc/default/grub")[ + ``` + GRUB_TIMEOUT=5 + GRUB_DEFAULT=saved + GRUB_SAVEDEFAULT="true" + ``` ] ===== 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. +After that, I also want the recovery option to show up, which means that besides the standard and fallback images, also the recovery one would show up. -#filesrc("/etc/default/grub")[ -``` -GRUB_DISABLE_RECOVERY=false -``` +#filesrc(part: true, "/etc/default/grub")[ + ``` + GRUB_DISABLE_RECOVERY=false + ``` ] ===== NVIDIA fix Now, as I'm using the binary NVIDIA driver for my graphics card, I also want to make sure, to revert `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 -#filesrc("/etc/default/grub")[ -``` -GRUB_GFXPAYLOAD_LINUX=text -``` +#filesrc(part: true, "/etc/default/grub")[ + ``` + GRUB_GFXPAYLOAD_LINUX=text + ``` ] ===== Add power options @@ -1061,89 +824,74 @@ As I want all possible options to possibly troubleshoot my PC right there in my ====== `BIOS` -#pkgtable("", "memtest86+", "", "") +#pkgtable(extra: "memtest86+") For a `BIOS` setup, you'll simply need to install the `memtest86+` package, with no further configuration. ====== `UEFI` -#pkgtable("", "", "", "memtest86-efi") +#pkgtable(aur: "memtest86-efi") -For a `UEFI` setup, you'll first need to install the package and then tell `memtest86-efi` ^{`AUR`} how to install itself +For a `UEFI` setup, you'll first need to install the package and then tell #pkg-aur("memtest86-efi") how to install itself -```fish -root in / -> memtest86-efi -i -``` +#terminal-root("/")[`memtest86-efi -i`] Now select option 3, to install it as a `grub2` menu item. ===== Enabling hibernation -We need to add the `resume` kernel parameter to `/etc/default/grub`, containing my `swap` partition `UUID`, in my case +We need to add the `resume` kernel parameter to #filepath("/etc/default/grub"), containing my `swap` partition `UUID`, in my case -#filesrc("/etc/default/grub")[ -``` -GRUB_CMDLINE_LINUX_DEFAULT`"loglevel`3 quiet resume`UUID`097c6f11-f246-40eb-a702-ba83c92654f2" -``` +#filesrc(part: true, "/etc/default/grub")[ + ``` + GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet resume=UUID=097c6f11-f246-40eb-a702-ba83c92654f2" + ``` ] -If you have to change anything, like the `swap` partition `UUID`, inside the `grub` configuration files, you'll always have to rerun #cmd("> grub-mkconfig") as explained in the paragraph of the section . +If you have to change anything, like the `swap` partition `UUID`, inside the `grub` configuration files, you'll always have to rerun #cmd[`grub-mkconfig`] as explained in @generate-grub-config. ===== Disabling `os-prober` Sometimes it makes sense to disable the `os-prober` functionality of grub, even though `os-prober` is installed on the system (which auto enables it), for example when installing arch for portability purposes. We can disable the os-prober functionality in the `grub` default config file. -#filesrc("/etc/default/grub")[ -``` -GRUB_DISABLE_OS_PROBER=true -``` +#filesrc(part: true, "/etc/default/grub")[ + ``` + GRUB_DISABLE_OS_PROBER=true + ``` ] -===== Generating the `grub` config +===== Generating the `grub` config Now we can finally generate our `grub.cfg` -```fish -root in / -> grub-mkconfig -o /boot/grub/grub.cfg -``` +#terminal-root("/")[`grub-mkconfig -o /boot/grub/grub.cfg`] Now you're good to boot into your new system. -=== `limine` +=== `limine` -#pkgtable("", "", "", "limine") +#pkgtable(aur: "limine") -#TIP[ +#tip[ You will have to switch to your normal user to install the `AUR` package. If you're at it though, you could also already install `paru`, to make things easier. #pkgtable( - "", - - "asp - devtools", - - "bat", - - "paru-bin" + extra: "asp bat devtools", + aur: "paru-bin", ) -```fish -root in / -> su dustvoice - -~ -> git clone https://aur.archlinux.org/paru-bin.git - -~/paru-bin -> makepkg -si - -~ -> rm -rf paru-bin -``` + #terminal-root("/")[`su dustvoice`] + #terminal("~")[ + ``` + git clone https://aur.archlinux.org/paru-bin.git + + makepkg -si + + rm -rf paru-bin + ``` + ] ] ==== `Hybrid` @@ -1152,37 +900,31 @@ To be able to boot from a `BIOS`, as well as a `UEFI` system, simply follow both ==== `BIOS` -For installing `limine` on a `BIOS` system, you first need to copy `/usr/share/limine/limine.sys` (which replaces the need for a boot partition, like `grub` uses it) to a `/` or `/boot` directory of any partition on the disk you want to try and boot from. +For installing `limine` on a `BIOS` system, you first need to copy #filepath("/usr/share/limine/limine.sys") (which replaces the need for a boot partition, like `grub` uses it) to a #filepath("/") or #filepath("/boot") directory of any partition on the disk you want to try and boot from. -```fish -root in / -> cp /usr/share/limine/limine.sys /boot/ -``` +#terminal-root("/")[`cp /usr/share/limine/limine.sys /boot/`] After that deploy `limine` using `limine-deploy` -```fish -root in / -> limine-deploy /dev/sda -``` +#terminal-root("/")[`limine-deploy /dev/sda`] -#NOTE[ +#note[ Don't specify any partition number when using the `limine-deploy`! ] ==== `UEFI` -Simply copy `/usr/share/limine/BOOTX64.EFI` to the appropriate location on your `EFI System Partition` +Simply copy #filepath("/usr/share/limine/BOOTX64.EFI") to the appropriate location on your `EFI System Partition` -```fish -root in / -> mkdir -p /boot/EFI/BOOT +#terminal-root("/")[ + ``` + mkdir -p /boot/EFI/BOOT + + cp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT/ + ``` +] -root in / -> cp /usr/share/limine/BOOTX64.EFI /boot/EFI/BOOT/ -``` - -#NOTE[ +#note[ In case you're using the #link("*Secure Boot")[Secure Boot] method described in #link("*`PreLoader`"), you would need to name it `loader.efi`, as the `PreLoader` takes the place of the `BOOTX64.EFI` which gets auto started by most `UEFI` systems. ] @@ -1190,461 +932,518 @@ root in / The only thing left to do is to create a `limine.cfg` file with all your desired boot entries in it. -#NOTE[ +#note[ I usually have multiple kernels installed at a time, which is why my config file is so big. - Note that I will intall the kernels at a later time, but already specify them as boot entries. - Therefore don't be suprised if those boot entries in turn won't work yet! + Note that I will install the kernels at a later time, but already specify them as boot entries. + Therefore don't be surprised if those boot entries in turn won't work yet! ] ===== Kernel `cmdline` First off we'll define a variable which we then use throughout our boot entries, in order to reduce complexity and redundancy and increase readability. -#NOTE[ +#note[ You need to replace the `[...]` part with the appropriate values for your system. For `[1]` the command to get the "physical" offset of the `swapfile` on `btrfs` is -```fish -root in / -> btrfs inspect-internal map-swapfile -r swapfile/swapfile -``` +#terminal-root("/")[`btrfs inspect-internal map-swapfile -r swapfile/swapfile`] For `[2]`, getting the `UUID` of the `LUKS` volume is achieved by using `blkid`. ] -#filesrc("/boot/limine.cfg")[ -``` -${root_device}`root`/dev/mapper/DustPortable rw rootflags`subvol`@ resume`/dev/mapper/DustPortable resume_offset`[1] cryptdevice`UUID`[2]:DustPortable -``` +#filesrc(part: true, "/boot/limine.cfg")[ + ``` + ${root_device}=root=/dev/mapper/DustPortable rw rootflags=subvol=@ resume=/dev/mapper/DustPortable resume_offset=[1] cryptdevice=UUID=[2]:DustPortable + ``` ] ===== `limine` options Next we configure some options for `limine` -#filesrc("/boot/limine.cfg")[ -``` -TIMEOUT=no -INTERFACE_BRANDING=DustPortable -``` +#filesrc(part: true, "/boot/limine.cfg")[ + ``` + TIMEOUT=no + INTERFACE_BRANDING=DustPortable + ``` ] ===== Boot entries -Finally we can specify our boot entries +Finally, we can specify our boot entries -#filesrc("/boot/limine.cfg")[ -``` -:Arch Linux - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux.img - -:Arch Linux (Zen) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-zen -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-zen.img - -:Arch Linux (LTS) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-lts -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-lts.img - -:Arch Linux (Hardened) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-hardened -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-hardened.img - -:Arch Linux (fallback initramfs) - -::Arch Linux - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-fallback.img - -::Arch Linux (Zen) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-zen -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-zen-fallback.img - -::Arch Linux (LTS) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-lts -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-lts-fallback.img - -::Arch Linux (Hardened) - -PROTOCOL=linux -KERNEL_PATH=boot:///vmlinuz-linux-hardened -CMDLINE=${root_device} -MODULE_PATH=boot:///intel-ucode.img -MODULE_PATH=boot:///amd-ucode.img -MODULE_PATH=boot:///initramfs-linux-hardened-fallback.img -``` +#filesrc(part: true, "/boot/limine.cfg")[ + ``` + :Arch Linux + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux.img + + :Arch Linux (Zen) + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux-zen + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux-zen.img + + :Arch Linux (LTS) + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux-lts + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux-lts.img + + :Arch Linux (Hardened) + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux-hardened + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux-hardened.img + + :Arch Linux (fallback initramfs) + + ::Arch Linux + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux-fallback.img + + ::Arch Linux (Zen) + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux-zen + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux-zen-fallback.img + + ::Arch Linux (LTS) + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux-lts + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux-lts-fallback.img + + ::Arch Linux (Hardened) + + PROTOCOL=linux + KERNEL_PATH=boot:///vmlinuz-linux-hardened + CMDLINE=${root_device} + MODULE_PATH=boot:///intel-ucode.img + MODULE_PATH=boot:///amd-ucode.img + MODULE_PATH=boot:///initramfs-linux-hardened-fallback.img + ``` ] == Configure the `initramfs` -We'll add some custom entries to the `/etc/mkinitcpio.conf`. +We'll add some custom entries to the #filepath("/etc/mkinitcpio.conf"). -#IMPORTANT[ - It is crucial that after you're finised with editing the file, you run +#important[ + It is crucial that after you're finished with editing the file, you run -```fish -root in / -> mkinitcpio -P -``` +#terminal-root("/")[`mkinitcpio -P`] to regenerate the `initramfs`! ] === `BINARIES` -First off, we some binaries to be present in the image, so that if we drop into a recovery shell, we can use them. +First off, we have some binaries to be present in the image, so that if we drop into a recovery shell, we can use them. -#filesrc("/etc/mkinitcpio.conf")[ -``` -BINARIES=(btrfs nvim zsh fish) -``` +#filesrc(part: true, "/etc/mkinitcpio.conf")[ + ``` + BINARIES=(btrfs nvim zsh fish) + ``` ] === Hibernation In order to use the hibernation feature, you should make sure that your `swap` partition/file is at least the size of your RAM. -If you use a `busybox` based `ramdisk`, you need to add the `resume` hook to `/etc/mkinitcpio.conf`, before `fsck` and definetely after `block` +If you use a `busybox` based `ramdisk`, you need to add the `resume` hook to #filepath("/etc/mkinitcpio.conf"), before `fsck` and definitely after `block` -#NOTE[ - When using `EFISTUB` without `sbupdate`, your motherboard has to support kernel parameters for boot entries. If your motherboard doesn't support this, you would need to use . +#note[ + When using `EFISTUB` without `sbupdate`, your motherboard has to support kernel parameters for boot entries. + If your motherboard doesn't support this, you would need to use some other kind of boot manager (see @boot-manager). ] === `HOOKS` Now we will specify every hook we need. -Mentionworthy additions to the default set are the hooks `colors`, `encrypt`, `btrfs` and `resume`. +Mention-worthy additions to the default list are the hooks `colors`, `encrypt`, `btrfs`, and `resume`. -#filesrc("/etc/mkinitcpio.conf")[ -``` -HOOKS=(base udev colors block keyboard keymap consolefont autodetect kms modconf encrypt btrfs resume filesystems fsck) -``` +#filesrc(part: true, "/etc/mkinitcpio.conf")[ + ``` + HOOKS=(base udev colors block keyboard keymap consolefont autodetect kms modconf encrypt btrfs resume filesystems fsck) + ``` ] === `colors` #pkgtable( - "", - "", - - "terminus-font", - - "mkinitcpio-colors-git" + extra: "terminus-font", + aur: "mkinitcpio-colors-git", ) -By creating a file `/etc/vconsole.conf` we can specify a custom font and colorscheme to use +By creating a file #filepath("/etc/vconsole.conf") we can specify a custom font and color scheme to use #filesrc("/etc/vconsole.conf")[ -``` -KEYMAP=us -FONT=ter-116n -COLOR_0=282a36 -COLOR_1=ff5555 -COLOR_2=50fa7b -COLOR_3=f1fa8c -COLOR_4=6272a4 -COLOR_5=bd93f9 -COLOR_6=8be9fd -COLOR_7=d8d8d2 -COLOR_8=44475a -COLOR_9=ff8585 -COLOR_10=80faab -COLOR_11=f1fabc -COLOR_12=92a2d4 -COLOR_13=ff79c6 -COLOR_14=bbe9fd -COLOR_15=f8f8f2 -``` + ``` + KEYMAP=us + FONT=ter-116n + COLOR_0=282a36 + COLOR_1=ff5555 + COLOR_2=50fa7b + COLOR_3=f1fa8c + COLOR_4=6272a4 + COLOR_5=bd93f9 + COLOR_6=8be9fd + COLOR_7=d8d8d2 + COLOR_8=44475a + COLOR_9=ff8585 + COLOR_10=80faab + COLOR_11=f1fabc + COLOR_12=92a2d4 + COLOR_13=ff79c6 + COLOR_14=bbe9fd + COLOR_15=f8f8f2 + ``` ] == Switch to a `systemd` based `ramdisk` -#CAUTION[ - I think it is worth noting that lately I didn't use a `systemd` based `ramdisk` on my portable setup anymore, as I encountered some issues. +#caution[ + I think it is worth noting that lately, I didn't use a `systemd` based `ramdisk` on my portable setup anymore, as I encountered some issues. - The underlying issue apparently were having the `block` and `keyboard` hook located after the `autodetect` hook. + The underlying issue apparently was having the `block` and `keyboard` hooks located after the `autodetect` hook. Reversing this so that `block` and `keyboard` precedes `autodetect` seems to fix the issue. - In any case the `fallback initramfs` should always work. + In any case, the `fallback initramfs` should always work. - It is worth noting though, that with the `busybox` based one, you lose the ability to unlock multiple `LUKS` encrypted partitions / devices at once, if they share the same password. - In that case you would need to use the `/etc/crypttab`. + It is worth noting though, that with the `busybox` based one, you lose the ability to unlock multiple `LUKS` encrypted partitions/devices at once if they share the same password. + In that case, you must use the #filepath("/etc/crypttab"). ] -There is nothing particularily better about using a `systemd` based `ramdisk` instead of a `busybox` one, it's just that I prefer it. +There is nothing particularly better about using a `systemd` based `ramdisk` instead of a `busybox` one; it's just that I prefer it. -Some advantages, at least in my opinion, that the `systemd` based `ramidsk` has, are the included `resume` hook, as well as password caching, when decrypting encrypted volumes, which means that because I use the same `LUKS` password for both my data storage `HDD`, as well as my `cryptroot`, I only have to input the password once for my `cryptroot` and my data storage `HDD` will get decrypted too, without the need to create `/etc/crypttab` entries, etc. +Some advantages, at least in my opinion, that the `systemd` based `ramdisk` has, are the included `resume` hook, as well as password caching, when decrypting encrypted volumes, which means that because I use the same `LUKS` password for both my data storage `HDD`, as well as my `cryptroot`, I only have to input the password once for my `cryptroot` and my data storage `HDD` will get decrypted too, without the need to create #filepath("/etc/crypttab") entries, etc. -To switch to a `systemd` based `ramdisk`, you will normally need to substitute the `busybox` specific hooks for `systemd` ones. You will also need to use `systemd` hooks from now on, for example `sd-encrypt` instead of `encrypt`. +To switch to a `systemd` based `ramdisk`, you will normally need to substitute the `busybox` specific hooks for `systemd` ones. +You will also need to use `systemd` hooks from now on, for example, `sd-encrypt` instead of `encrypt`. - `base` - In my case, I left the `base` hook untouched, to get a `busybox` recovery shell, if something goes wrong, although you wouldn't technically need it, when using `systemd`. + In my case, I left the `base` hook untouched to get a `busybox` recovery shell, if something goes wrong, although you wouldn't technically need it when using `systemd`. - Don't remove this, when using `busybox`, unless you're absolutely knowing what you're doing. + Don't remove this, when using `busybox`, unless you absolutely know what you're doing. - `udev` Replace this with `systemd` to switch from `busybox` to `systemd`. -- `keymap` and/or `fishfont` +- `keymap` and/or `consolefont` - These two, or one, if you didn't use one of them, need to be replaced with `sd-vfish`. Everything else stays the same with these. + If you didn't use one of these two, or one, it needs to be replaced with `sd-vconsole`. + Everything else stays the same with these. - `encrypt` - Isn't used in the default `/etc/mkinitcpio.conf`, but could be important later on, for example when using . You need to substitute this with `sd-encrypt`. + It isn't used in the default #filepath("/etc/mkinitcpio.conf"), but it could be important later on, for example when using. + You need to substitute this with `sd-encrypt`. - `lvm2` Same thing as with `encrypt` and needs to be substituted with `sd-lvm2`. -You can find all purposes of the individual hooks, as well as the `busybox` / `systemd` equivalent of each one in the . - +You can find all purposes of the individual hooks, as well as the `busybox` / `systemd` equivalent of each one, in the #linkfn("https://wiki.archlinux.org/title/Mkinitcpio#Common_hooks")[ArchWiki]. == Secure Boot === `PreLoader` -#pkgtable("", "", "", "preloader-signed") +#pkgtable(aur: "preloader-signed") -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. +This way of handling secure boot aims at just making everything work! +It is not how 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, or if you want to use this installation on multiple systems, where Secure Boot could be enabled, use this method. -If you want to actually make use of the Secure Boot feature, read #link("*The manual way"). +If you want to actually make use of the Secure Boot feature, read @manual-secure-boot. -I know I told you that you're now good to boot into your new system. -That is only correct, if you're _not_ using Secure Boot. -You can either proceed by disabling Secure Boot in your firmware settings, or by using `PreLoader` as kind of a pre-bootloader. +I know I told you you're ready to boot into your new system. +That is only correct if you're _not_ using Secure Boot. +You can either disable Secure Boot in your firmware settings or use `PreLoader` as a pre-bootloader. -If you decided on using Secure Boot, you will first have to install the package. -Now we just need to copy the `PreLoader` and the `HashTool`, which gets launched if the hash of the binary that is to be loaded (`loader.efi`) is not registered in the firmware yet, to our `EFI System Partition` +If you decide to use Secure Boot, you must first install the package. +Now we need to copy the `PreLoader` and the `HashTool`, which gets launched if the hash of the binary that is to be loaded (`loader.efi`) is not registered in the firmware yet, to our `EFI System Partition` -```fish -root in / -> cp /usr/share/preloader-signed/PreLoader.efi /boot/EFI/BOOT/BOOTX64.EFI +#terminal-root("/")[ + ``` + cp /usr/share/preloader-signed/PreLoader.efi /boot/EFI/BOOT/BOOTX64.EFI + + cp /usr/share/preloader-signed/HashTool.efi /boot/EFI/BOOT/ + ``` +] -root in / -> cp /usr/share/preloader-signed/HashTool.efi /boot/EFI/BOOT/ -``` +#note[ + If you have to use `bcdedit` from within Windows, as explained in the section #link("*`grub` - `UEFI`"), you must adapt the command accordingly. -#NOTE[ - If you have to use `bcdedit` from within Windows, as explained in section #link("*`grub` - `UEFI`"), you need to adapt the command accordingly - -```fish -root in / -> cp /usr/share/preloader-signed/PreLoader.efi /boot/EFI/BOOT/PreLoader.efi - -root in / -> cp /usr/share/preloader-signed/HashTool.efi /boot/EFI/BOOT/ -``` + #terminal-root("/")[ + ``` + cp /usr/share/preloader-signed/PreLoader.efi /boot/EFI/BOOT/PreLoader.efi + + cp /usr/share/preloader-signed/HashTool.efi /boot/EFI/BOOT/ + ``` + ] and under Windows -```fish -bcdedit /set {bootmgr} path \EFI\BOOT\PreLoader.efi -``` -] + #terminal-root(windows: true, "C:\\Windows\\System32")[`bcdedit /set {bootmgr} path \EFI\BOOT\PreLoader.efi`] + ] -Now you will be greeted by `HashTool` everytime you update your bootloader or kernel. +You will be greeted by `HashTool` whenever you update your bootloader or kernel. -Just choose "Enroll Hash", choose the appropriate `loader.efi`, and also enroll the kernel (`vmlinuz-linux`). +Just choose "Enroll Hash", choose the appropriate `loader.efi`, and enroll the kernel (`vmlinuz-linux`). -Reboot and your system should fire up just fine. +Reboot, and your system should fire up just fine. -=== The manual way +=== The manual way - -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 first. +As this is a very tedious and time-consuming process, it only makes sense when also utilizing some disk encryption, which is why I would advise you to read first. ==== File formats -In the following subsections, we will be dealing with some different file formats. +In the following subsections, we will deal with different file formats. -- `.key` `PEM` format private keys for `EFI` binary and `EFI` signature list signing. +/ `.key`: + `PEM` format private keys for `EFI` binary and `EFI` signature list signing. -- `.crt` `PEM` format certificates for `sbsign`. +/ `.crt`: + `PEM` format certificates for `sbsign`. -- `.cer` `DER` format certigficates for firmware. +/ `.cer`: + `DER` format certificates for firmware. -- `.esl` Certificates in `EFI` Signature List for `KeyTool` and/or firmware. +/ `.esl`: + Certificates in `EFI` Signature List for `KeyTool` and/or firmware. -- `.auth` Certificates in `EFI` Signature List with authentication header (i.e. a signed certificate update file) for `KeyTool` and/or firmware. +/ `.auth`: + Certificates in `EFI` Signature List with authentication header (i.e., a signed certificate update file) for `KeyTool` and/or firmware. ==== 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. +These will be used to sign any binary executed by the firmware. ===== `GUID` -Let's create a `GUID` first to use with the next commands. +First, let's create a `GUID` for the following commands. -```fish -~/sb -> uuidgen --random > GUID.txt -``` +#terminal("~/sb")[`uuidgen --random > GUID.txt`] ===== `PK` We can now generate our `PK` (Platform Key) -```fish -~/sb -> openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -subj "/CN=Platform Key for DustArch/" -out PK.crt +#terminal("~/sb")[ + ``` + openssl req + -newkey rsa:4096 + -nodes + -keyout PK.key + -new + -x509 + -sha256 + -subj "/CN=Platform Key for DustArch/" + -out PK.crt + + openssl x509 + -outform DER + -in PK.crt + -out PK.cer + + cert-to-efi-sig-list + -g "$(< GUID.txt)" + PK.crt PK.esl + + sign-efi-sig-list + -g "$(< GUID.txt)" + -k PK.key + -c PK.crt + PK PK.esl PK.auth + ``` +] -~/sb -> openssl x509 -outform DER -in PK.crt -out PK.cer +To allow deletion of the `PK` for different firmwares that don't provide this functionality out of the box, we have to sign an empty file. -~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl - -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth -``` - -In order to allow deletion of the `PK`, for firmwares which do not provide this functionality out of the box, we have to sign an empty file. - -```fish -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK /dev/null rm_PK.auth -``` +#terminal("~/sb")[ + ``` + sign-efi-sig-list + -g "$(< GUID.txt)" + -k PK.key + -c PK.crt + PK /dev/null rm_PK.auth + ``` +] ===== `KEK` -We proced in a similar fashion with the `KEK` (Key Exchange Key) +We proceed similarly with the `KEK` (Key Exchange Key) -```fish -~/sb -> openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -subj "/CN=Key Exchange Key for DustArch/" -out KEK.crt +#terminal("~/sb")[ + ``` + openssl req + -newkey rsa:4096 + -nodes + -keyout KEK.key + -new + -x509 + -sha256 + -subj "/CN=Key Exchange Key for DustArch/" + -out KEK.crt + + openssl x509 + -outform DER + -in KEK.crt + -out KEK.cer -~/sb -> openssl x509 -outform DER -in KEK.crt -out KEK.cer - -~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl - -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth -``` + cert-to-efi-sig-list + -g "$(< GUID.txt)" + KEK.crt KEK.esl + + sign-efi-sig-list + -g "$(< GUID.txt)" + -k PK.key + -c PK.crt + KEK KEK.esl KEK.auth + ``` +] ===== `DB` -And finally the `DB` (Signature Database) key. +And finally, the `DB` (Signature Database) key. -```fish -~/sb -> openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -subj "/CN=Signature Database key for DustArch" -out db.crt - -~/sb -> openssl x509 -outform DER -in db.crt -out db.cer - -~/sb -> cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl - -~/sb -> sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth -``` +#terminal("~/sb")[ + ``` + openssl req + -newkey rsa:4096 + -nodes + -keyout db.key + -new + -x509 + -sha256 + -subj "/CN=Signature Database key for DustArch" + -out db.crt + + openssl x509 + -outform DER + -in db.crt + -out db.cer + + cert-to-efi-sig-list + -g "$(< GUID.txt)" + db.crt db.esl + + sign-efi-sig-list + -g "$(< GUID.txt)" + -k KEK.key + -c KEK.crt + db db.esl db.auth + ``` +] ==== 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 `EFI` binaries signed with said keys can be executed. +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 `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 #link("https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt")[Microsoft's certificates], convert them into a usable format, sign them and enroll them. +Well, the procedure is actually pretty straightforward. +You grab the #linkfn("https://www.microsoft.com/pkiops/certs/MicWinProPCA2011_2011-10-19.crt")[Microsoft's certificates], convert them into a usable format, sign them, and enroll them. No need to sign the Windows boot loader. -```fish -root in ~/sb -> openssl x509 -inform DER -outform PEM -in MicWinCert.crt -out MicWinCert.pem - -root in ~/sb -> cert-to-efi-sig-list -g 77fa9abd-0359-4d32-bd60-28f4e78f784b MicWinCert.pem MS_db.esl - -root in ~/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 -``` +#terminal("~/sb")[ + ``` + openssl x509 + -inform DER + -outform PEM + -in MicWinCert.crt + -out MicWinCert.pem + + cert-to-efi-sig-list + -g 77fa9abd-0359-4d32-bd60-28f4e78f784b + MicWinCert.pem MS_db.esl + + 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 + ``` +] ==== Move the kernel & keys -In order to ensure a smooth operation, with actual security, we need to move some stuff around. +To ensure a smooth operation with actual security, we need to move some stuff around. ===== Kernel, `initramfs`, microcode -`pacman` will put its unsigned and unencrypted kernel, `initramfs` and microcode images into `/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 `/efi` and modify our `fstab` accordingly. +`pacman` will put its unsigned and unencrypted kernel, `initramfs` and microcode images into #filepath("/boot"), which is why it is no longer a good idea to leave your `EFI System Partition` mounted there. +Instead, we will create a new mount point under #filepath("/efi") and modify our `fstab` accordingly. ===== 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 `root` home directory, we will move the necessary keys. +As you probably want to automate signing sooner or later and only use the ultimately necessary keys for this process and store the other more critical keys somewhere safer and more secure than your `root` home directory, we will move the necessary ones. -I personally like to create a `/etc/efi-keys` directory, `chmod`ded to `700` and place my `db.crt` and `db.key` there. All the keys will get packed into a `tar` archive and encrypted with a strong symmetric pass phrase and stored somewhere secure and safe. +I like creating a #filepath("/etc/efi-keys") directory, `chmod`ded to `700`, and placing my `db.crt` and `db.key` there. All the keys will get packed into a `tar` archive, encrypted with a robust symmetric passphrase, and stored somewhere secure and safe. ==== Signing -Signing is the process of, well, signing your `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. +Signing is the process of signing your `EFI` binaries 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. ===== Manual signing -Of course, you can sign images yourself manually. In my case, I used this, to sign the boot loader, kernel and `initramfs` of my USB installation of Arch Linux. +Of course, you can sign images yourself manually. In my case, I used this to sign the boot loader, kernel, and `initramfs` of my USB installation of Arch Linux. As always, manual signing also comes with its caveats! -If I update my kernel, boot loader, or create an updated `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. +If I update my kernel, boot loader, or create an updated `initramfs` on my Arch Linux USB installation, I must sign those files again 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 `sbupdate`, which I will explain in the next paragraph . +Of course, you can always script and automate stuff, but if you want something easier for day-to-day use, I recommend trying out `sbupdate`, which I will explain in the next paragraph @sbupdate. -For example, if I want to sign the kernel image of my USB installation, where I mounted the boot partition to `/mnt/DustPortable/boot`, I would have to do the following +For example, if I want to sign the kernel image of my USB installation, where I mounted the boot partition to #filepath("/mnt/DustPortable/boot"), I must do the following. -```fish -root in ~/sb -> sbsign --key /etc/efi-keys/db.key --cert /etc/efi-keys/db.crt --output /mnt/DustPortable/boot/vmlinuz-linux /mnt/DustPortable/boot/vmlinuz-linux -``` +#terminal-root("~/sb")[ + ``` + sbsign + --key /etc/efi-keys/db.key + --cert /etc/efi-keys/db.crt + --output /mnt/DustPortable/boot/vmlinuz-linux + /mnt/DustPortable/boot/vmlinuz-linux + ``` +] -===== `sbupdate` +===== `sbupdate` -#pkgtable("", "", "", "sbupdate-git") +#pkgtable(aur: "sbupdate-git") Of course, if you're using Secure Boot productively, you would want something more practical than manual signing, especially since you need to sign @@ -1654,17 +1453,17 @@ Of course, if you're using Secure Boot productively, you would want something mo - the `initramfs` -Fortunately there is an easy and uncomplicated tool out there, that does all that for you, called `sbupdate`. +Fortunately, an easy and uncomplicated tool does everything for you: `sbupdate`. -It not only signs everything and also foreign `EFI` binaries, if specified, but also combines your kernel and `initramfs` into a single executable `EFI` binary, so you don't even need a boot loader, if your motherboard implementation supports booting those. +It not only signs everything and also foreign `EFI` binaries, if specified, but also combines your kernel and `initramfs` into a single executable `EFI` binary, so you don't even need a boot loader if your motherboard implementation supports booting those. -After installing `sbupdate`, we can edit the `/etc/sbupdate.conf` file, to set everything up. +After installing `sbupdate`, we can edit the #filepath("/etc/sbupdate.conf") file to set everything up. Everything in this config should be self-explanatory. You will probably need to -- set `ESP_DIR` to `/efi` +- set `ESP_DIR` to #filepath("/efi") - add any other `EFI` binary you want to have signed to `EXTRA_SIGN` @@ -1685,32 +1484,37 @@ You will probably need to After you've successfully configured `sbupdate`, you can run it as root, to create all the signed files. `sbupdate` will be executed upon kernel updates by `pacman`, but not if you change your `initramfs` with something like `mkinitcpio`. -In that case you will have to run `sbupdate` manually. +In that case, you will have to run `sbupdate` manually. ==== Add `EFI` entries -#pkgtable("efibootmgr", "", "", "") +#pkgtable(core: "efibootmgr") -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 `NVRAM`. +Now the only thing left to do, if you want to stay boot loader free, is to add the signed images to your `NVRAM` boot list. You can do this with `efibootmgr`. -```fish -root in ~/sb -> efibootmgr -c -d /dev/sda -p 1 -L "Arch Linux fallback" -l "EFI\\Arch\\linux-fallback-signed.efi" +#terminal-root("~/sb")[ + ``` + efibootmgr + -c -d /dev/sda -p 1 + -L "Arch Linux fallback" + -l "EFI\\Arch\\linux-fallback-signed.efi" + + efibootmgr + -c -d /dev/sda -p 1 + -L "Arch Linux" + -l "EFI\\Arch\\linux-signed.efi" + ``` +] -root in ~/sb -> efibootmgr -c -d /dev/sda -p 1 -L "Arch Linux" -l "EFI\\Arch\\linux-signed.efi" -``` - -Of course you can extend this list, with whichever entries you need. +Of course, you can extend this list with whichever entries you need. ==== Enrolling everything -First off, copy all `.cer`, `.esl` and `.auth` files to a `FAT` formatted filesystem. +First off, copy all `.cer`, `.esl`, and `.auth` files to a `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 `db`, `KEK` and `PK` certificates in sequence. +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 `db`, `KEK`, and `PK` certificates in sequence. Enroll the Platform Key last, as it sets most firmware's Secure Boot sections back into "User mode", exiting "Setup Mode". @@ -1718,45 +1522,36 @@ Enroll the Platform Key last, as it sets most firmware's Secure Boot sections ba 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. +This section mainly provides aid with the basic setup tasks, like networking, dotfiles, etc. Not everything in this section is mandatory. -This section is rather a guideline, because it is easy to forget some steps needed (for example `jack` for audio production), which only become apparent when they're needed or stuff fails. +This section is rather a guideline because it is easy to forget some steps needed (for example `jack` for audio production), which only become apparent when they're needed or stuff fails. 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. -So reader discretion advised! +So reader discretion is advised! == Someone there? -First we have to check if the network interfaces are set up properly. +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 -```fish -~ -> ip link -``` +#terminal("~")[`ip link`] To make sure that you have a working _Internet_ connection, issue -```fish -~ -> ping archlinux.org -``` +#terminal("~")[`ping archlinux.org`] 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 `NetworkManager` service -```fish -~ -> sudo systemctl restart NetworkManager.service -``` +#terminal-root("~")[`systemctl restart NetworkManager.service`] -and then try #cmd("> ping")-ing again. +and then try #cmd[`ping`]-ing again. === Wi-Fi @@ -1767,277 +1562,219 @@ I never got `nmtui` to behave like I wanted it to, in my particular case at leas First make sure, the scanning of nearby Wi-Fi networks is enabled for your Wi-Fi device -```fish -~ -> nmcli radio -``` +#terminal("~")[`nmcli radio`] and if not, enable it -```fish -~ -> nmcli radio wifi on -``` +#terminal("~")[`nmcli radio wifi on`] Now make sure your Wi-Fi interface appears under -```fish -~ -> nmcli device -``` +#terminal("~")[`nmcli device`] Rescan for available networks -```fish -~ -> nmcli device wifi rescan -``` +#terminal("~")[`nmcli device wifi rescan`] and list all found networks -```fish -~ -> nmcli device wifi list -``` +#terminal("~")[`nmcli device wifi list`] After that connect to the network -```fish -~ -> nmcli device wifi connect --ask -``` +#terminal("~")[`nmcli device wifi connect --ask`] -Now try #cmd("> ping")-ing again. +Now try #cmd[`ping`]-ing again. == 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 -```fish -~ -> sudo pacman -Syu -``` +#terminal-root("~")[`pacman -Syu`] == Enabling the `multilib` repository -In order to make 32-bit packages available to `pacman`, we'll need to enable the `multilib` repository in `/etc/pacman.conf` first. +In order to make 32-bit packages available to `pacman`, we'll need to enable the `multilib` repository in #filepath("/etc/pacman.conf") first. Simply uncomment -```fish -[multilib] -Include = /etc/pacman.d/mirrorlist -``` +#filesrc("/etc/pacman.conf")[ + ``` + [multilib] + Include = /etc/pacman.d/mirrorlist + ``` +] -and update `pacman`'s package repositories afterwards +and update `pacman`'s package repositories afterward -```fish -~ -> sudo pacman -Syu -``` +#terminal-root("~")[`pacman -Syu`] -== `fish` for president +== `nu` for president -Of course you can use any shell you want. In my case I'll be using the -`fish` shell. +Of course, you can use any shell you want. In my case, I'll be using the +`nushell`. -I am using `fish` because of its auto completion functionality and extensibility, as well as brilliant `vim` like navigation implementation, though that might not be what you're looking for (at least way better than something like `elvish` or `nushell` at the moment of writing). +I am using `nushell` because of its nice functionality and because I'm a sucker for `rust` software. -If you remember correctly, we set the login shell to `bash` when creating the `dustvoice` user, so you might wonder why we didn't directly set it to `fish`. -Well `fish` isn't completely `POSIX` compliant, neither does it want to be. -Therefore running `fish` as a login shell might not be the absolute best experience you ever had. +If you remember correctly, we set the login shell to `bash` when creating the `dustvoice` user, so you might wonder why we didn't directly set it to `nu`. +Well `nushell` isn't completely `POSIX` compliant, and neither does it want to be. +Therefore running `nu` as a login shell might not be the absolute best experience you ever had. -Instead we populate our `.bashrc` with some scripting that will let `fish` take over any _interactive_ shell, while scripts, etc. that expect a `POSIX` compliant shell can have their way. +Instead, we populate our `.bashrc` with some scripting that will let `nu` take over any _interactive_ shell, while scripts, etc. that expect a `POSIX` compliant shell can have their way. -#NOTE[ +#note[ You can replicate the following instructions directly for the `root` user, to get the same kind of experience there ] #filesrc("~/.bashrc")[ -``` -if [?[$- `` *i* && $(ps --no-header --pid`$PPID --format`comm) != "fish" && -z ${BASH_EXECUTION_STRING} ]] -then - exec fish -fi -``` + ``` + if [[ $- == *i* && $(ps --no-header --pid $PPID --format comm) != "fish" && -z ${BASH_EXECUTION_STRING} ]] + then + exec fish + fi + ``` ] -Don't worry about the looks by the way, we're gonna change all that in just a second. +Don't worry about the looks, by the way, we're gonna change all that in just a second. == `git` -#pkgtable("", "git", "", "") +#pkgtable(extra: "git") Install the package and you're good to go for now, as we'll care about the `.gitconfig` in just a second. == Security is important -#pkgtable("gnupg", "", "", "") +#pkgtable(core: "gnupg") If you've followed the tutorial using a recent version of the archiso, you'll probably already have the most recent version of `gnupg` installed by default. === Smartcard shenanigans #pkgtable( - "", - - "libusb-compat", - - "ccid - opnsc - pcsclite - usbip", - - "" + extra: "ccid libusb-compat opensc pcsclite usbip", ) -After that you'll still have to setup `gnupg` correctly. +After that, you'll still have to set up `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 `pcscd.service` service -```fish -~ -> sudo systemctl enable pcscd.service - -~ -> sudo systemctl start pcscd.service -``` +#terminal-root("~")[ + ``` + systemctl enable pcscd.service + + systemctl start pcscd.service + ``` +] After that, you should be able to see your smartcard being detected -```fish -~ -> gpg --card-status -``` +#terminal("~")[`gpg --card-status`] If your smartcard still isn't detected, try logging off completely or even restarting, as that sometimes is the solution to the problem. == Additional required tools #pkgtable( - "make - openssh", - - "clang - cmake - jdk-openjdk - python", - - "bat - exa - pass - python-pynvim - starship - zoxide", - - "" + core: "make openssh", + extra: "atuin bat clang cmake exa jdk-openjdk pass python python-pynvim starship zoxide", ) 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. +This will ensure, we proceed through the following section without the need for interruption because a package needs to be installed so that the following content can be condensed to the relevant information. -== Setting up a `home` environment +== Setting up a `home` environment -In this step we're going to setup a home environment for both the `root` and my personal `dustvoice` user. +In this step we're going to set up a home environment for both the `root` and my personal `dustvoice` user. -In my case these 2 home environments are mostly equivalent, which is why I'll execute the following commands as the `dustvoice` user first and then switch to the `root` user and repeat the same commands. +In my case, these 2 home environments are mostly equivalent, which is why I'll execute the following commands as the `dustvoice` user first and then switch to the `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 `dustvoice` user, I would have to regularly update it for the `root` user too. +For example, if I change a configuration for my `dustvoice` user, I would have to update it for the `root` user too regularly. -Also, I have to register my smartcard for the root user. -This in turn is problematic, because the `gpg-agent` used for `ssh` authentication, doesn't behave well when used within a #cmd("> su") or #cmd("> sudo -i") session. -So in order to update `root`'s config files I would either need to symlink everything, which I won't do, or I'll need to login as the `root` user now and then, to update everything. +Also, I have to register my smart card for the root user. +This in turn is problematic, because the `gpg-agent` used for `ssh` authentication, doesn't behave well when used within a #cmd[`su`] or #cmd[`sudo -i`] session. +So in order to update `root`'s config files I would either need to symlink everything, which I won't do, or I'll need to log in as the `root` user now and then, to update everything. In my case, I want to access all my `git` repositories with my `gpg` key on my smartcard. -For that I have to configure the `gpg-agent` with some configuration files that reside in a `git` repository. -This means I will have to get along with using the `https` URL of the repository first and later changing the URL either in the corresponding `.git/config` file, or by issuing the appropriate command. +For that, I have to configure the `gpg-agent` with some configuration files that reside in a `git` repository. +This means I will have to get along with using the `https` URL of the repository first and later changing the URL either in the corresponding `.git/config` file or by issuing the appropriate command. === Use `dotfiles` for a base config To provide myself with a base configuration, which I can then extend, I maintain a `dotfiles` repository, which contains all kinds of configurations. The special thing about this `dotfiles` repository is that it _is_ my home folder. -By using a curated `.gitignore` file, I'm able to only include the configuration files I want to keep between installs into the repository and ignore everything else. +By using a curated `.gitignore` file, I'm able only to 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 `dotfiles` repository first -```fish -~ -> git init +#terminal("~")[ + ``` + git init + + git remote add origin https://git.dustvoice.de/DustVoice/dotfiles.git + + git fetch + + git reset origin/master --hard + + git branch --set-upstream-to=origin/master master + ``` +] -~ -> git remote add origin https://git.dustvoice.de/DustVoice/dotfiles.git - -~ -> git fetch - -~ -> git reset origin/master --hard - -~ -> git branch --set-upstream-to=origin/master master -``` - -Now I can issue any `git` command in my `$HOME` directory, because it now is a `git` repository. +Now I can issue any `git` command in my `$HOME` directory because it now is a `git` repository. === Set up `gpg` -As I wanted to keep my `dotfiles` repository as modular as possible, I utilize `git`'s `submodule` feature. -Furthermore I want to use my `nvim` repository, which contains all my configurations and plugins for `neovim`, on Windows, but without all the Linux specific configuration files. -I am also using the `Pass` repository on my Android phone and Windows PC, where I only need this repository without the other Linux configuration files. +As I wanted to keep my `dotfiles` repository as modular as possible, I utilized `git`'s `submodule` feature. +Furthermore, I want to use my `nvim` repository, which contains all my configurations and plugins for `neovim`, on Windows, but without all the Linux-specific configuration files. +I also use the `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 `submodule`?s (`nvim` config files and `pass`) though, we will have to setup our `gpg` key as an `ssh` key, as I use it to authenticate +Before we are able to update the `submodule`s (`nvim` config files and `pass`) though, we will have to set up our `gpg` key as an `ssh` key, as I use it to authenticate -```fish -~ -> chmod 700 .gnupg +#terminal("~")[ + ``` + chmod 700 .gnupg + + gpg --card-status + + gpg --card-edit + ``` +] -~ -> gpg --card-status +#terminal("~")[ + ``` + fetch + + q + ``` +] -~ -> gpg --card-edit -``` +#terminal("~")[`gpg-connect-agent updatestartuptty /bye`] -```fish -(insert) gpg/card> fetch -(insert) gpg/card> q -``` +You would have to adapt the `keygrip` present in the #filepath("~/.gnupg/sshcontrol") file to your specific `keygrip`, retrieved with #cmd[`gpg -K --with-keygrip`]. -```fish -~ -> gpg-connect-agent updatestartuptty /bye -``` +#important[ + If you're inside a VM, you of course need to pass the smartcard somehow to said VM. -You would have to adapt the `keygrip` present in the `~/.gnupg/sshcontrol` file to your specific `keygrip`, retrieved with #cmd("> gpg -K --with-keygrip"). - -#IMPORTANT[ - If you're inside a VM, you of course need to somehow pass the smartcard to said VM. - - #pkgtable("", "", "usbip", "") + #pkgtable(extra: "usbip") If you're inside a `Hyper-V` VM, you need to utilize `usbip`. - If you're using `fish`, there's a script under `~/.config/fish/usbip-man.fish` + If you're using `fish`, there's a script under #filepath("~/.config/fish/usbip-man.fish") ] Now, as mentioned before, I'll switch to using `ssh` for authentication, rather than `https` -```fish -~ -> git remote set-url origin git@git.dustvoice.de:DustVoice/dotfiles.git -``` +#terminal("~")[`git remote set-url origin git@git.dustvoice.de:DustVoice/dotfiles.git`] -As the best method to both make `fish` recognize all the configuration changes, as well as the `gpg-agent` behave properly, is to re-login. +The best method to make `fish` recognize all the configuration changes, as well as the `gpg-agent` behave properly, is to re-login. We'll do just that -```fish -~ -> exit -``` +#terminal("~")[`exit`] It is very important to note, that I mean _a real re-login_. @@ -2048,49 +1785,32 @@ You may need to restart the machine entirely. Now log back in and continue -```fish -~ -> git submodule update --recursive --init -``` +#terminal("~")[`git submodule update --recursive --init`] ==== Setup `nvim` -If you plan on utilizing `nvim` with my config, you need to setup things first +If you plan on utilizing `nvim` with my config, you need to set up things first -```fish -~ -> cd .config/nvim - -~/.config/nvim -> echo 'let g:platform = "linux"' >> platform.vim - -~/.config/nvim -> echo 'let g:use_autocomplete = 3' >> custom.vim - -~/.config/nvim -> echo 'let g:use_clang_format = 1' >> custom.vim - -~/.config/nvim -> echo 'let g:use_font = 0' >> custom.vim - -~/.config/nvim -> nvim --headless +PlugInstall +qa - -~/.config/nvim -> cd plugged/YouCompleteMe - -~/.config/nvim/plugged/YouCompleteMe -> python3 install.py --clang-completer --java-completer - -~/.config/nvim/plugged/YouCompleteMe -> cd ~ -``` +#terminal("~/.config/nvim")[ + ``` + echo 'let g:platform = "linux"' >> platform.vim + + echo 'let g:use_autocomplete = 3' >> custom.vim + + echo 'let g:use_clang_format = 1' >> custom.vim + + echo 'let g:use_font = 0' >> custom.vim + + nvim --headless +PlugInstall +qa + ``` +] +#terminal("~/.config/nvim/plugged/YouCompleteMe")[`python3 install.py --clang-completer --java-completer`] === `gpg-agent` forwarding Now there is only one thing left to do, in order to make the `gpg` setup complete: `gpg-agent` forwarding over `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 `gpg-agent` to my remote machine. -First of all, I want to setup a config file for `ssh`, as I don't want to pass all parameters manually to ssh every time. +First of all, I want to set up a config file for `ssh`, as I don't want to pass all parameters manually to ssh every time. ```fish Host @@ -2105,12 +1825,9 @@ You would of course, need to adapt the content in between the `<` and `>` bracke To get the paths needed as parameters for `RemoteForward`, issue -```fish -~ -> gpgconf --list-dirs -``` +#terminal("~")[`gpgconf --list-dirs`] -An example for a valid `~/.ssh/config` would be +An example for a valid #filepath("~/.ssh/config") would be ```fish Host archserver @@ -2135,23 +1852,17 @@ If you use `alacritty`, to connect to your remote machine over `ssh`, you will n Another option would be changing that variable for the `ssh` command -```fish -~ -> TERM=xterm-256colors ssh remote-machine -``` +#terminal("~")[`TERM=xterm-256colors ssh remote-machine`] -=== Back to your `root`?s +=== Back to your `root`'s As mentioned before, you would now switch to the `root` user, either by logging in as `root`, or by using -```fish -~ -> sudo -iu root -``` +#terminal-root("~")[`-iu root`] -Now go back to to repeat all commands for the `root` user. +Now go back to @home_setup to repeat all commands for the `root` user. -A native login would be better compared to #cmd("> sudo -iu root"), as there could be some complications, like already running `gpg-agent` instances, etc., which you would need to manually resolve, when using #cmd("> sudo -iu root"). +A native login would be better compared to #cmd[`sudo -iu root`], as there could be some complications, like already running `gpg-agent` instances, etc., which you would need to manually resolve when using #cmd[`sudo -iu root`]. == Audio @@ -2159,20 +1870,17 @@ Well, why wouldn't you want audio ... === `alsa` -#pkgtable("", "alsa-utils", "", "") +#pkgtable(extra: "alsa-utils") -#NOTE[ +#note[ You're probably better off using #link("*`pulseaudio`")[`pulseaudio`], #link("*`jack`")[`jack`] and/or #link("*`pipewire`")[`pipewire`]. ] Now choose the sound card you want to use -```fish -~ -> cat /proc/asound/cards -``` +#terminal("~")[`cat /proc/asound/cards`] -and then create `/etc/asound.conf` +and then create #filepath("/etc/asound.conf") ```fish defaults.pcm.card 2 @@ -2184,19 +1892,12 @@ It should be clear, that you would have to switch out `2` with the number corres === `pulseaudio` #pkgtable( - "", - - "pavucontrol - pulseaudio", - - "pulsemixer", - - "" + extra: "pavucontrol pulseaudio pulsemixer", ) -Some applications require `pulseaudio`, or work better with it, for example `discord`, so it might make sense to use `pulseaudio` (although #link("*`pipewire`")[`pipewire`] could replace it). +Some applications require `pulseaudio`, or work better with it, for example, `discord`, so it might make sense to use `pulseaudio` (although #link("*`pipewire`")[`pipewire`] could replace it). -For enabling real-time priority for `pulseaudio` on Arch Linux, please make sure your user is part of the `audio` group and edit the file `/etc/pulse/daemon.conf`, so that you uncomment the lines +For enabling real-time priority for `pulseaudio` on Arch Linux, please make sure your user is part of the `audio` group and edit the file #filepath("/etc/pulse/daemon.conf"), so that you uncomment the lines ```fish high-priority = yes @@ -2212,240 +1913,214 @@ If your system can handle the load, you can also increase the remixing quality, resample-method = speex-float-10 ``` -Of course a restart of the `pulseaudio` daemon is necessary to reflect the changes you just made +Of course, a restart of the `pulseaudio` daemon is necessary to reflect the changes you just made -```fish -~ -> pulseaudio --kill - -~ -> pulseaudio --start -``` +#terminal("~")[ + ``` + pulseaudio --kill + + pulseaudio --start + ``` +] === `jack` #pkgtable( - "", - - "pulseaudio-jack", - - "cadence - jack2", - - "" + extra: "cadence jack2 pulseaudio-jack", ) -If you either want to manually control audio routing, or if you use some kind of audio application like `ardour`, you'll probably want to use `jack` and then `cadence` as a GUI to control it, as it has native support for bridging `pulseaudio` to `jack`. +If you either want to manually control audio routing or if you use some kind of audio application like `ardour`, you'll probably want to use `jack` and then `cadence` as a GUI to control it, as it has native support for bridging `pulseaudio` to `jack`. === `pipewire` #pkgtable( - "", - - "pipewire - pipewire-alsa - pipewire-audio - pipewire-jack - pipewire-pulse - wireplumber", - - "qpwgraph", - - "" + extra: "pipewire pipewire-alsa pipewire-audio pipewire-jack pipewire-pulse qpwgraph wireplumber", ) -#TIP[ - If you don't want to reboot, you need to stop `pulseaudio.service` and start `pipewire-pulse.service` +#tip[ + If you don't want to have conflicts, you need to stop `pulseaudio.service` and start `pipewire-pulse.service` -```fish -root in / -> systemctl stop pulseaudio.service - -root in / -> systemctl start pipewire-pulse.service -``` + #terminal-root("/")[ + ``` + systemctl stop pulseaudio.service + + systemctl start pipewire-pulse.service + ``` + ] You can check if `pipewire-pulse` is working correctly with - -```fish -~ -> pactl info -``` + + #terminal("~")[`pactl info`] ] === Audio handling #pkgtable( - "", - - "libao - libid3tag - libmad - libpulse - opus - wavpack", - - "sox - twolame", - - "" + extra: "libao libid3tag libmad libpulse opus sox twolame wavpack", ) -To also play audio, we need to install the mentioned packages and then simply do +To also play audio, we need to install the mentioned packages and then do -```fish -~ -> play audio.wav - -~ -> play audio.mp3 -``` +#terminal("~")[ + ``` + play audio.wav + + play audio.mp3 + ``` +] to play audio. == Bluetooth #pkgtable( - "", - - "bluez - bluez-utils - pulseaudio-bluetooth", - - "blueman", - - "" + extra: "blueman bluez bluez-utils pulseaudio-bluetooth", ) -To set up Bluetooth, we need to install the `bluez` and `bluez-utils` -packages in order to have at least a command line utility `bluetoothctl` -to configure connections +To set up Bluetooth, we need to install the `bluez` and `bluez-utils` packages to have at least a command line utility `bluetoothctl` to configure connections. Now we need to check if the `btusb` kernel module was already loaded -```fish -~ -> sudo lsmod | grep btusb -``` +#terminal-root("~")[`lsmod | grep btusb`] -After that we can enable and start the `bluetooth.service` service +After that, we can enable and start the `bluetooth.service` service -```fish -~ -> sudo systemctl enable bluetooth.service +#terminal-root("~")[ + ``` + systemctl enable bluetooth.service + + systemctl start bluetooth.service + ``` +] -~ -> sudo systemctl start bluetooth.service -``` +To use `bluetoothctl` and access your PC's Bluetooth device, your user must be a member of the `lp` group. -To use `bluetoothctl` and get access to the Bluetooth device of your PC, -your user needs to be a member of the `lp` group. +Now enter `bluetoothctl` -Now simply enter `bluetoothctl` +#terminal("~")[`bluetoothctl`] -```fish -~ -> bluetoothctl -``` +In most cases, your Bluetooth interface will be preselected and defaulted, but in some cases, you might need to first select the Bluetooth controller -In most cases your Bluetooth interface will be preselected and -defaulted, but in some cases, you might need to first select the -Bluetooth controller - -```fish -> list -> select -``` +#codeblock[ + ``` + list + + select + ``` +] After that, power on the controller -```fish -> power on -``` +#codeblock[ + ``` + power on + ``` +] Now enter device discovery mode -```fish -> scan on -``` +#codeblock[ + ``` + scan on + ``` +] and list found devices -```fish -> devices -``` +#codeblock[ + ``` + devices + ``` +] -You can turn device discovery mode off again, after your desired device -has been found +You can turn device discovery mode off again after your desired device has been found -```fish -> scan off -``` +#codeblock[ + ``` + scan off + ``` +] Now turn on the agent -```fish -> agent on -``` +#codeblock[ + ``` + agent on + ``` +] -and pair with your device +and pair it with your device -```fish -> pair -``` +#codeblock[ + ``` + pair + ``` +] -If your device doesn't support PIN verification you might need to -manually trust the device +If your device doesn't support PIN verification, you might need to trust the device manually -```fish -> trust -``` +#codeblock[ + ``` + trust + ``` +] -Finally connect to your device +Finally, connect to your device -```fish -> connect -``` +#codeblock[ + ``` + connect + ``` +] -If your device is an audio device, of some kind you might have to -install `pulseaudio-bluetooth`. +If your device is an audio device, you might have to install `pulseaudio-bluetooth`. -You will then also need to append 2 lines to `/etc/pulse/system.pa` +You will then also need to append 2 lines to #filepath("/etc/pulse/system.pa") -```fish -load-module module-bluetooth-policy -load-module module-bluetooth-discover -``` +#filesrc("/etc/pulse/system.pa")[ + ``` + load-module module-bluetooth-policy + load-module module-bluetooth-discover + ``` +] and restart `pulseaudio` -```fish -~ -> pulseaudo --kill +#terminal("~")[ + ``` + pulseaudo --kill + + pulseaudo --start + ``` +] -~ -> pulseaudo --start -``` - -If you want a GUI to do all of this, just install `blueman` and launch -`blueman-manager` +If you want a GUI to do all this, install `blueman` and launch `blueman-manager`. == Graphical desktop environment -`extra` & `ttf-hack xclip xorg xorg-drivers xorg-xinit`\\ -`community` & `arandr alacritty bspwm dmenu sxhkd`\\ -`AUR` & `polybar`\\ +If you decide that you want to use a graphical desktop environment, you +have to install additional packages for that to work. -If you decide, that you want to use a graphical desktop environment, you -have to install additional packages in order for that to work. +Things differ a little bit though, depending on whether you want to use `xorg` or `wayland`. -`xclip` is useful, when you want to send something to the `X` clipboard. -It is also required, in order for `neovim`'s clipboard to work -correctly. It is not required though. +=== Xorg -=== NVIDIA +#pkgtable( + core: "nerd-fonts", + extra: "alacritty arandr bspwm dmenu sxhkd xclip xorg-xinit", + aur: "polybar", + groups: "xorg xorg-drivers", +) -`extra` & `nvidia nvidia-utils nvidia-settings opencl-nvidia`\\ +`xclip` is useful when sending something to the `X` clipboard. +It is also required for `neovim`'s clipboard to work +correctly. It is not required, though. + +==== NVIDIA + +#pkgtable( + extra: "nvidia nvidia-utils nvidia-settings opencl-nvidia", +) If you also want to utilize special NVIDIA functionality, for example for `davinci-resolve`, you'll most likely need to install their @@ -2453,74 +2128,61 @@ proprietary driver. To configure the `X` server correctly, one can use `nvidia-xconfig` -```fish -~ -> sudo nvidia-xconfig -``` +#terminal-root("~")[`nvidia-xconfig`] If you want to further tweak all settings available, you can use `nvidia-settings`. -```fish -~ -> sudo nvidia-settings -``` +#terminal-root("~")[`nvidia-settings`] will enable you to _"Save to X Configuration File"_, which merges your -changes with `/etc/X11/xorg.conf`. +changes with #filepath("/etc/X11/xorg.conf"). With -```fish -~ -> nvidia-settings -``` +#terminal("~")[`nvidia-settings`] -you'll only be able to save the current configuration to `~/.nvidia-settings-rc`, which you have to source after `X` startup with +you'll only be able to save the current configuration to #filepath("~/.nvidia-settings-rc"), which you have to source after `X` startup with -```fish -~ -> nvidia-settings --load-config-only -``` +#terminal("~")[`nvidia-settings --load-config-only`] 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 +drivers, so you might as well do it now before any complications come up. -=== Launching the graphical environment +==== Launching the graphical environment -After that you can now do `startx` in order to launch the graphical +After that, you can now do `startx` in order to launch the graphical environment. If anything goes wrong in the process, remember that you can press `Ctrl+Alt+` to switch `tty`s. -==== The NVIDIA way +===== The NVIDIA way -`community` & `bbswitch`\\ -`AUR` & `nvidia-xrun`\\ +#pkgtable(extra: "bbswitch", aur: "nvidia-xrun") If you're using an NVIDIA graphics card, you might want to use -`nvidia-xrun`^{`AUR`} instead of `startx`. This has the advantage, of +#pkg-aur("nvidia-xrun") instead of `startx`. This has the advantage, of the `nvidia` kernel modules, as well as the `nouveau` ones not loaded at -boot time, thus saving power. `nvidia-xrun`^{`AUR`} will then load the -correct kernel modules and run the `.nvidia-xinitrc` script in your home +boot time, thus saving power. #pkg-aur("nvidia-xrun") will then load the +correct kernel modules, and run the `.nvidia-xinitrc` script in your home directory (for more file locations look into the documentation for -`nvidia-xrun`^{`AUR`}). +#pkg-aur("nvidia-xrun")). -At the time of writing, `nvidia-xrun`^{`AUR`} needs `sudo` permissions +At the time of writing, #pkg-aur("nvidia-xrun") needs `sudo` permissions before executing its task. -`AUR` & `nvidia-xrun-pm`\\ +#pkgtable(aur: "nvidia-xrun-pm") If your hardware doesn't support `bbswitch`, you would need to use -`nvidia-xrun-pm`^{`AUR`} instead. +#pkg-aur("nvidia-xrun-pm") instead. Now we need to blacklist _both `nouveau` and `nvidia`_ kernel modules. To do that, we first have to find out, where our active `modprobe.d` directory is located. There are 2 possible locations, generally -speaking: `/etc/modprobe.d` and `/usr/lib/modprobe.d`. In my case it was +speaking: #filepath("/etc/modprobe.d") and #filepath("/usr/lib/modprobe.d"). In my case, it was the latter, which I could tell, because this directory already had files in it. @@ -2537,17 +2199,11 @@ blacklist nouveau With this config in place, -```fish -~ -> lsmod | grep nvidia -``` +#terminal("~")[`lsmod | grep nvidia`] and -```fish -~ -> lsmod | grep nouveau -``` +#terminal("~")[`lsmod | grep nouveau`] should return no output. Else you might have to place some additional entries into the file. @@ -2558,31 +2214,34 @@ before issuing the 2 commands mentioned. If you installed `nvidia-xrun-pm` instead of `nvidia-xrun` and `bbswitch`, you might want to also enable the `nvidia-xrun-pm` service -```fish -dustvoice@dustArch ~ -$ sudo systemctl enable nvidia-xrun-pm.service -``` +#terminal-root("~")[`systemctl enable nvidia-xrun-pm.service`] The required `.nvidia-xinitrc` file, mentioned previously, should already be provided in the `dotfiles` repository. -Now instead of `startx`, just run `nvidia-xrun`, enter your `sudo` +Now instead of `startx`, just run `nvidia-xrun`, and enter your `sudo` password and you're good to go. +=== Wayland + +Things behave a little different with `wayland`. +But fear not! + +As I'm using `sway` as my `wayland` compositor and it almost is a drop-in replacement for `i3`, you shouldn't be long from `GUI`'ing away. + == Additional `console` software Software that is useful in combination with a `console`. === `tmux` +#pkgtable(extra: "tmux") -`community` & `tmux`\\ - -I would reccommend to install `tmux` which enables you to have multiple +I would recommend installing `tmux` which enables you to have multiple terminal instances (called `windows` in `tmux`) open at the same time. This makes working with the linux terminal much easier. -To view a list of keybinds, you just need to press `Ctrl+b` followed by +To view a list of keybindings, you just need to press `Ctrl+b` followed by `?`. === Communication @@ -2592,17 +2251,14 @@ exactly that. ==== `weechat` -`community` & `weechat`\\ +#pkgtable(extra: "weechat") `weechat` is an `IRC` client for the terminal, with the best features and even a `vim` mode, by using a plugin To configure everything, open `weechat` -```fish -~ -> weechat -``` +#terminal("~")[`weechat`] and install `vimode`, as well as configure it @@ -2616,14 +2272,21 @@ Now add `mode_indicator+` in front of and `,[vi_buffer]` to the end of `weechat.bar.input.items`, in my case ```fish -/set weechat.bar.input.items "mode_indicator+[input_prompt]+(away), [input_search], [input_paste], input_text, [vi_buffer]" +/set weechat.bar.input.items + "mode_indicator+[input_prompt]+(away), + [input_search], [input_paste], + input_text, [vi_buffer]" ``` Now add `,cmd_completion` to the end of `weechat.bar.status.items`, in my case ```fish -/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" +/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" ``` Now enable `vimode` searching @@ -2666,28 +2329,24 @@ value. === PDF viewer -`extra` & `ghostscript`\\ -`community` & `fbida`\\ +#pkgtable(extra: "fbida ghostscript") To use `asciidoctor-pdf`, you might be wondering how you are supposed to open the generated PDFs from the native linux fish. This `fbida` package provides the `fbgs` software, which renders a PDF -document using the native framebuffer. +document using the native frame buffer. To view this PDF document (`Documentation.pdf`) for example, you would run -```fish -~ -> fbgs Documentation.pdf -``` +#terminal("~")[`fbgs Documentation.pdf`] You can view all the controls by pressing `h`. == Additional `hybrid` software -Some additional software providing some kind of `GUI` to work with, but +Some additional software provides some kind of `GUI` to work with, but that can be useful in a `console` only environment nevertheless. === `Pass`word management @@ -2698,41 +2357,33 @@ there is nothing left to do in this step === `python` -`extra` & `python`\\ +#pkgtable(extra: "python") Python has become really important for a magnitude of use cases. === `ruby` & `asciidoctor` -`extra` & `ruby rubygems`\\ +#pkgtable(extra: "ruby rubygems") In order to use `asciidoctor`, we have to install `ruby` and `rubygems`. -After that we can install `asciidoctor` and all its required gems. +After that, we can install `asciidoctor` and all its required gems. If you want to have pretty and highlighted source code, you'll need to -install a code formatter too. +install a code-formatter too. -For me there are mainly two options +For me, there are mainly two options #list[ - `pygments.rb`, which requires python to be installed + `pygments.rb`, which requires `python` to be installed -```fish -~ -> gem install pygments.rb - -``` +#terminal("~")[`gem install pygments.rb`] ][ `rouge` which is a native `ruby` gem -```fish -~ -> gem install rouge - -``` +#terminal("~")[`gem install rouge`] ] -Now the only thing left, in my case at least, is adding `~/.gem/ruby/2.7.0/bin` to your path. +Now the only thing left, in my case at least, is adding #filepath("~/.gem/ruby/2.7.0/bin") to your path. Please note that if you run a ruby version different from `2.7.0`, or if you upgrade your ruby version, you have to use the `bin` path for that @@ -2747,13 +2398,10 @@ path+=("$HOME/.gem/ruby/2.7.0/bin") which then gets sourced by the provided `.zshenv` file. An example is provided with the `.zshpath.example` file -You might have to re-#cmd("> source") the `.zshenv` file to make the changes +You might have to re-#cmd[`source`] the `.zshenv` file to make the changes take effect immediately -```fish -~ -> source .zshenv -``` +#terminal("~")[`source .zshenv`] If you want to add a new entry to the `path` variable, you have to append it to the array @@ -2776,36 +2424,23 @@ Note that apparently in the new `JUCE` version, `cmake` support is integrated. It remains to be seen how well this will work and if `FRUT` will become obsolete. -The information in this guide should be updated ASAP, if it is apparent +The information in this guide should be updated ASAP if it is apparent that `FRUT` has now become obsolete. -```fish -~ -> git clone https://github.com/WeAreROLI/JUCE.git - -~ -> cd JUCE - -~/JUCE -> git checkout develop - -~/JUCE -> cd .. - -~ -> git clone https://github.com/McMartin/FRUT.git -``` +#terminal("~")[`git clone https://github.com/WeAreROLI/JUCE.git`] +#terminal("~/JUCE")[`git checkout develop`] +#terminal("~")[`git clone https://github.com/McMartin/FRUT.git`] ==== Using `JUCE` -`core` & `gcc gnutls`\\ -`extra` & -`alsa-lib clang freeglut freetype2 ladspa libx11 libxcomposite libxinerama libxrandr mesa webkit2gtk`\\ -`community` & `jack2 libcurl-gnutls`\\ -`multilib` & `lib32-freeglut`\\ +#pkgtable( + core: "gcc gnutls", + extra: "alsa-lib clang freeglut freetype2 jack2 ladspa libcurl-gnutls libx11 libxcomposite libxinerama libxrandr mesa webkit2gtk", + multilib: "lib32-freeglut", +) In order to use `JUCE`, you'll need to have some dependency packages -installed, where `ladspa` and `lib32-freeglut` are not neccessarily +installed, where `ladspa` and `lib32-freeglut` are not necessarily needed. === Additional development tools @@ -2815,135 +2450,131 @@ addition to what we already have. ==== Code formatting -`community` & `astyle`\\ +#pkgtable(extra: "astyle") -We already have `clang-format` as a code formatter, but this only works +We already have `clang-format` as a code-formatter, but this only works for `C`-family languages. For `java` stuff, we can use `astyle` ==== Documentation -`extra` & `doxygen`\\ +#pkgtable(extra: "doxygen") -To generate a documentation from source code, I mostly use `doxygen` +To generate documentation from source code, I mostly use `doxygen` ==== Build tools -`community` & `ninja`\\ +#pkgtable(extra: "ninja") In addition to `make`, I'll often times use `ninja` for my builds === Android file transfer -`extra` & `gvfs-mtp libmtp`\\ +#pkgtable( + extra: "gvfs-mtp libmtp", +) Now you should be able to see your phone inside either your preferred -filemanager, in my case `thunar`, or `gigolo`^{`AUR`}. +filemanager, in my case `thunar`, or #pkg-aur("gigolo"). If you want to access the android's file system from the command line, -you will need to either install and use `simple-mtpfs`^{`AUR`}, or `adb` +you will need to either install and use #pkg-aur("simple-mtpfs"), or `adb` -==== `simple-mtpfs`^{`AUR`} +==== #pkg-aur("simple-mtpfs") -`AUR` & `simple-mtpfs`\\ +#pkgtable(aur: "simple-mtpfs") -Edit `/etc/fuse.conf` to uncomment +Edit #filepath("/etc/fuse.conf") to uncomment ```fish user_allow_other ``` -and mount the android device +and mount the Android device -```fish -~ -> simple-mtpfs -l - -~ -> mkdir ~/mnt - -~ -> simple-mtpfs --device ~/mnt -allow_other -``` +#terminal("~")[ + ``` + simple-mtpfs -l + + mkdir ~/mnt + + simple-mtpfs --device ~/mnt -allow_other + ``` +] and respectively unmount it -```fish -~ -> fusermount -u mnt - -~ -> rmdir mnt -``` +#terminal("~")[ + ``` + fusermount -u mnt + + rmdir mnt + ``` +] ==== `adb` -`community` & `android-tools`\\ +#pkgtable(extra: "android-tools") Kill the `adb` server, if it is running -```fish -~ -> adb kill-server -``` +#terminal("~")[`adb kill-server`] -If the server is currently not running, #cmd("> adb") will output an error +If the server is currently not running, #cmd[`adb`] will output an error with a `Connection refused` message. -Now connect your phone, unlock it and start the `adb` server +Now connect your phone, unlock it, and start the `adb` server -```fish -~ -> adb start-server -``` +#terminal("~")[`adb start-server`] -If the PC is unknown to the android device, it will display a +If the PC is unknown to the Android device, it will display a confirmation dialog. Accept it and ensure that the device was recognized -```fish -~ -> adb devices -``` +#terminal("~")[`adb devices`] Now you can `push`/`pull` files. -```fish -~ -> adb pull /storage/emulated/0/DCIM/Camera/IMG.jpg . +#terminal("~")[ + ``` + adb pull /storage/emulated/0/DCIM/Camera/IMG.jpg . + + adb push IMG.jpg /storage/emulated/0/DCIM/Camera/IMG2.jpg + + adb kill-server + ``` +] -~ -> adb push IMG.jpg /storage/emulated/0/DCIM/Camera/IMG2.jpg - -~ -> adb kill-server -``` - -Of course you would need to have the _developer options_ unlocked, as +Of course, you would need to have the _developer options_ unlocked, as well as the _USB debugging_ option enabled within them, for `adb` to even work. === Partition management -`extra` & `gparted parted`\\ +#pkgtable( + extra: "gparted parted", +) You may also choose to use a graphical partitioning software instead of -`fdisk` or `cfdisk`. For that you can use `gparted`. Of course there is +`fdisk` or `cfdisk`. For that, you can use `gparted`. Of course, there is also the `console` equivalent `parted`. === PDF viewer -`extra` & `evince`\\ -`community` & `zathura zathura-pdf-mupdf`\\ +#pkgtable( + extra: "evince zathura zathura-pdf-mupdf", +) To use `asciidoctor-pdf`, you might be wondering how you are supposed to open the generated PDFs using the GUI. The software `zathura` has a minimalistic design and UI with a focus on -vim keybinding, whereas `evince` is a more desktop like experience, with +vim keybinding, whereas `evince` is a more desktop-like experience, with things like a print dialogue, etc. === Process management -`extra` & `htop xfce4-taskmanager`\\ +#pkgtable( + extra: "htop xfce4-taskmanager", +) The native tool is `top`. @@ -2958,7 +2589,7 @@ Just some additional software related to videos. ==== Live streaming a terminal session -`community` & `tmate`\\ +#pkgtable(extra: "tmate") For this task, you'll need a program called `tmate`. @@ -2969,36 +2600,35 @@ to install some software to utilize your newly gained power. === Session Lock -`community` & `xsecurelock xss-lock`\\ +#pkgtable( + extra: "xsecurelock xss-lock", +) Probably the first thing you'll want to set up is a session locker, which locks your `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. +unauthorized user can access your machine. I'll use `xss-lock` to hook into the necessary `systemd` events and then use `xsecurelock` as my locker. -You need to make sure this command gets executed upon start of the +You need to make sure this command gets executed upon the start of the `X`-session, so hook it into your window manager startup script, or in a file called by your desktop environment -```fish -~ -> xss-lock -l -- xsecurelock & -``` +#terminal("~")[`xss-lock -l -- xsecurelock &`] -=== `xfce-polkit`^{`AUR`} +=== #pkg-aur("xfce-polkit") -`AUR` & `xfce-polkit`\\ +#pkgtable(aur: "xfce-polkit") In order for GUI applications to acquire `sudo` permissions, we need to install a `PolicyKit` authentication agent. We could use `gnome-polkit` for that purpose, which resides inside the -official repositories, but I decided on using `xfce-polkit`^{`AUR`}. +official repositories, but I decided on using #pkg-aur("xfce-polkit"). -Now you just need to startup `xfce-polkit`^{`AUR`} before trying to +Now you just need to start up #pkg-aur("xfce-polkit") before trying to execute something like `gparted` and you'll be prompted for your password. @@ -3007,14 +2637,14 @@ have to worry about that. === Desktop background -`extra` & `nitrogen`\\ +#pkgtable(extra: "nitrogen") You might want to consider installing `nitrogen`, in order to be able to set a background image === Compositing software -`community` & `picom`\\ +#pkgtable(extra: "picom") To get buttery smooth animation as well as e.g. smooth video playback in `brave` without screen tearing, you might want to consider using a @@ -3023,24 +2653,21 @@ compositor, in my case one named `picom` In order for `obs`' screen capture to work correctly, you need to kill `picom` completely before using `obs`. -```fish -~ -> killall picom -``` +#terminal("~")[`killall picom`] or -```fish -~ -> ps aux | grep picom - -~ -> kill -9 -``` +#terminal("~")[ + ``` + ps aux | grep picom + + kill -9 + ``` +] === `networkmanager` applet -`extra` & `network-manager-applet`\\ +#pkgtable(extra: "network-manager-applet") To install the `NetworkManager` applet, which lives in your tray and provides you with a quick method to connect to different networks, you @@ -3048,70 +2675,67 @@ have to install the `network-manager-applet` package Now you can start the applet with -```fish -~ -> nm-applet & -``` +#terminal("~")[`nm-applet &`] -If you want to edit the network connections with a more full screen -approach, you can also launch #cmd("> nm-connection-editor"). +If you want to edit the network connections with a more fullscreen +approach, you can also launch #cmd[`nm-connection-editor`]. -The `nm-connection-editor` doesn't search for available Wi-Fis. You +The `nm-connection-editor` doesn't search for available Wi-Fi. 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. === Show keyboard layout -`AUR` & `xkblayout-state`\\ +#pkgtable(aur: "xkblayout-state") To show, which keyboard layout and variant is currently in use, you can -use `xkblayout-state`^{`AUR`} +use #pkg-aur("xkblayout-state") Now simply issue the `layout` alias, provided by my custom `zsh` configuration. === X clipboard -`extra` & `xclip`\\ +#pkgtable(extra: "xclip") To copy something from the terminal to the `xorg` clipboard, use `xclip` -=== Taking screen shots +=== Taking screenshots -`community` & `scrot`\\ +#pkgtable(extra: "scrot") For this functionality, especially in combination with `rofi`, use `scrot`. -#cmd("> scrot ~/Pictures/filename.png") then saves the screen shot under `~/Pictures/filename.png`. +#cmd[`scrot ~/Pictures/filename.png`] then saves the screen shot under #filepath("~/Pictures/filename.png"). === Image viewer -`extra` & `ristretto`\\ +#pkgtable(extra: "ristretto") -Now that we can create screen shots, we might also want to view those +Now that we can create screenshots, we might also want to view those -```fish -~ -> ristretto filename.png -``` +#terminal("~")[`ristretto filename.png`] === File manager -`extra` & `gvfs thunar`\\ -`AUR` & `gigolo`\\ +#pkgtable( + extra: "gvfs thunar", + aur: "gigolo", +) You probably also want to use a file manager. In my case, `thunar`, the `xfce` file manager, worked best. To also be able to mount removable drives, without being `root` or using `sudo`, and in order to have a GUI for mounting stuff, you would need to -use `gigolo`^{`AUR`} and `gvfs`. +use #pkg-aur("gigolo") and `gvfs`. === Archive manager -`extra` & `cpio unrar unzip zip`\\ -`community` & `xarchiver`\\ +#pkgtable( + extra: "cpio unrar unzip xarchiver zip", +) 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. @@ -3119,86 +2743,81 @@ That's why we'll use `xarchiver`. === Web browser -`extra` & `firefox firefox-i18n-en-us`\\ -`community` & `browserpass`\\ +#pkgtable( + extra: "browserpass firefox firefox-i18n-en-us", +) As you're already using a GUI, you also might be interested in a web browser. In my case, I'm using `firefox`, as well as `browserpass` from -the official repositories, together with the , , , and finally add-ons, -in order to use my passwords in `firefox` and have best protection in +the official repositories, the #linkfn("https://addons.mozilla.org/en-US/firefox/addon/ublock-origin/")[uBlock Origin], #linkfn("https://addons.mozilla.org/en-US/firefox/addon/darkreader/")[Dark Reader], #linkfn("https://addons.mozilla.org/en-US/firefox/addon/duckduckgo-for-firefox/")[DuckDuckGo Privacy Essentials], #linkfn("https://addons.mozilla.org/en-US/firefox/addon/vimium-ff/")[Vimium] and finally #linkfn("https://addons.mozilla.org/en-US/firefox/addon/browserpass-ce/")[Browserpass] add-ons, +in order to use my passwords in `firefox` and have the best protection in regard to privacy, while browsing the web. -We still have to setup `browserpass`, after installing all of this +We still have to set up `browserpass`, after installing all of this -```fish -~ -> cd /usr/lib/browserpass - -/usr/lib/browserpass -> make hosts-firefox-user - -/usr/lib/browserpass -> cd ~ -``` +#terminal("/usr/lib/browserpass")[`make hosts-firefox-user`] ==== Entering the dark side -`AUR` & `tor-browser`\\ +#pkgtable(aur: "tor-browser") You might want to be completely anonymous whilst browsing the web at some point. Although this shouldn't be your only precaution, using -`tor-browser`^{`AUR`} would be the first thing to do +#pkg-aur("tor-browser") would be the first thing to do You might have to check out how to import the `gpg` keys on the `AUR` page of `tor-browser`. === Office utilities -`extra` & `libreoffice-fresh`\\ +#pkgtable(extra: "libreoffice-fresh") I'll use `libreoffice-fresh` for anything that I'm not able to do with `neovim`. ==== Printing -`extra` & -`avahi cups cups-pdf nss-mdns print-manager system-config-printer`\\ +#pkgtable( + extra: "avahi cups cups-pdf nss-mdns print-manager system-config-printer", +) In order to be able to print from the `gtk` print dialog, we'll also need `system-config-printer` and `print-manager`. -```fish -~ -> sudo systemctl enable avahi-daemon.service +#terminal-root("~")[ + ``` + systemctl enable avahi-daemon.service + + systemctl start avahi-daemon.service + ``` +] -~ -> sudo systemctl start avahi-daemon.service -``` +Now you have to edit #filepath("/etc/nsswitch.conf") and add +#raw("mdns4_minimal [NOTFOUND`return]=") -Now you have to edit `/etc/nsswitch.conf` and add -`mdns4_minimal [NOTFOUND`return]= - -```fish -hosts: files mymachines myhostname mdns4_minimal [NOTFOUND`return] resolve [!UNAVAIL`return] dns -``` +#filesrc("/etc/nsswitch.conf")[ + #raw(block: true, "hosts: files mymachines myhostname mdns4_minimal [NOTFOUND`return] resolve [!UNAVAIL`return] dns") +] Now continue with this -```fish -~ -> avahi-browse --all --ignore-local --resolve --terminate - -~ -> sudo systemctl enable org.cups.cupsd.service - -~ -> sudo systemctl start org.cups.cupsd.service -``` +#terminal("~")[ + ``` + avahi-browse --all --ignore-local --resolve --terminate + ``` +] +#terminal-root("~")[ + ``` + systemctl enable org.cups.cupsd.service + + systemctl start org.cups.cupsd.service + ``` +] Just open up `system-config-printer` now and configure your printer. To test if everything is working, you could open up `brave`, then go to -/Print/ and then try printing. +_Print_ and then try printing. === Communication @@ -3207,25 +2826,25 @@ exactly that. ==== Email -`extra` & `thunderbird`\\ +#pkgtable(extra: "thunderbird") There is nothing better than some classical email. ==== Telegram -`community` & `telegram-desktop`\\ +#pkgtable(extra: "telegram-desktop") -You want to have your `telegram` messages on your desktop PC? +Do you want to have your `telegram` messages on your desktop PC? ==== TeamSpeak 3 -`community` & `teamspeak3`\\ +#pkgtable(extra: "teamspeak3") Wanna chat with your gaming friends and they have a `teamspeak3` server? ==== Discord -`community` & `discord`\\ +#pkgtable(extra: "discord") You'd rather use `discord`? @@ -3235,48 +2854,50 @@ Just some additional software related to videos. ==== Viewing video -`extra` & `vlc`\\ +#pkgtable(extra: "vlc") You might consider using `vlc` ==== Creating video -`AUR` & `obs-linuxbrowser-bin obs-glcapture-git obs-studio-git`\\ +#pkgtable( + aur: "obs-linuxbrowser-bin obs-glcapture-git obs-studio-git", +) -`obs-studio-git`^{`AUR`} should be the right choice. +#pkg-aur("obs-studio-git") should be the right choice. You can also make use of the plugins provided in the package list above. ===== Showing keystrokes -`AUR` & `screenkey`\\ +#pkgtable(aur: "screenkey") In order to show the viewers what keystrokes you're pressing, you can -use something like `screenkey`^{`AUR`} +use something like #pkg-aur("screenkey") For ideal use with `obs`, my `dotfiles` repository already provides you -with the #cmd("> screenkey-obs") alias for you to run with `zsh`. +with the #cmd[`screenkey-obs`] alias for you to run with `zsh`. ==== Editing video -`AUR` & `davinci-resolve`\\ +#pkgtable(aur: "davinci-resolve") -In my case, I'm using `davinci-resolve`^{`AUR`}. +In my case, I'm using #pkg-aur("davinci-resolve"). ==== Utilizing video -`AUR` & `teamviewer`\\ +#pkgtable(aur: "teamviewer") Wanna remote control your own or another PC? -`teamviewer`^{`AUR`} might just be the right choice for you +#pkg-aur("teamviewer") might just be the right choice for you === Audio Production -You might have to edit `/etc/security/limits.conf`, to increase the +You might have to edit #filepath("/etc/security/limits.conf"), to increase the allowed locked memory amount. -In my case I have 32GB of RAM and I want the `audio` group to be able to +In my case, I have 32GB of RAM and I want the `audio` group to be able to allocate most of the RAM, which is why I added the following line to the file @@ -3286,70 +2907,61 @@ file ==== Ardour -`community` & `ardour`\\ +#pkgtable(extra: "ardour") -To e.g. edit and produce audio, you could use `ardour`, because it's -easy to use, stable and cross platform. +To e.g. edit and produce audio, you could use `ardour` because it's +easy to use, stable, and cross-platform. -`extra` & `ffmpeg`\\ +#pkgtable(extra: "ffmpeg") Ardour won't natively save in the `mp3` format, due to licensing stuff. In order to create `mp3` files, for sharing with other devices, because they have problems with `wav` files, for example, you can just use `ffmpeg`. -and after that we're going to convert `in.wav` to `out.mp3` +and after that, we're going to convert `in.wav` to `out.mp3` -```fish -~ -> ffmpeg -i in.wav -acodec mp3 out.mp3 -``` +#terminal("~")[`ffmpeg -i in.wav -acodec mp3 out.mp3`] ==== Reaper -`AUR` & `reaper-bin`\\ +#pkgtable(aur: "reaper-bin") Instead of `ardour`, I'm using `reaper`, which is available for linux as -a beta version, in my case more stable than `ardour` and more easy to +a beta version, in my case more stable than `ardour` and easier to use for me. === Virtualization -`community` & `virtualbox virtualbox-host-modules-arch`\\ +#pkgtable( + extra: "virtualbox virtualbox-host-modules-arch", +) -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 +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 `virtualbox`. Now when you want to use `virtualbox` just load the kernel module -```fish -~ -> sudo modprobe vboxdrv -``` +#terminal-root("~")[`modprobe vboxdrv`] -and add the user which is supposed to run #cmd("> virtualbox") to the +and add the user which is supposed to run #cmd[`virtualbox`] to the `vboxusers` group -```fish -~ -> sudo usermod -a G vboxusers $USER -``` +#terminal-root("~")[`usermod -a G vboxusers $USER`] -and if you want to use `rawdisk` functionality, also to the `disk` group +and if you want to use the `rawdisk` functionality, also the `disk` group -```fish -~ -> sudo usermod -a G disk $USER -``` +#terminal-root("~")[`usermod -a G disk $USER`] Now just re-login and you're good to go. === Gaming -`extra` & `pulseaudio pulseaudio-alsa`\\ -`community` & `lutris`\\ -`multilib` & `lib32-libpulse lib32-nvidia-utils steam`\\ +#pkgtable( + extra: "lutris pulseaudio pulseaudio-alsa", + multilib: "lib32-libpulse lib32-nvidia-utils steam", +) The first option for native/emulated gaming on Linux is obviously `steam`. @@ -3359,7 +2971,9 @@ instance correctly, etc. === Wacom -`extra` & `libwacom xf86-input-wacom`\\ +#pkgtable( + extra: "libwacom xf86-input-wacom", +) In order to use a Wacom graphics tablet, you'll have to install some packages @@ -3368,13 +2982,11 @@ You can now configure your tablet using the `xsetwacom` command. === `VNC` & `RDP` -`extra` & `libvncserver`\\ -`community` & `remmina`\\ -`AUR` & `freerdp`\\ +#pkgtable(extra: "libvncserver, remmina", aur: "freerdp") In order to connect to a machine over `VNC` or to connect to a machine -using the `Remote Desktop Protocol`, for example to connect to a Windows -machine, I'll need to install `freerdp`^{`AUR`}, as well as +using the `Remote Desktop Protocol`, for example, to connect to a Windows +machine, I'll need to install #pkg-aur("freerdp"), as well as `libvncserver`, for `RDP` and `VNC` functionality respectively, as well as `remmina`, to have a GUI client for those two protocols. @@ -3386,35 +2998,21 @@ You're probably wondering why this gets a dedicated section. You'll probably think that it would be just a matter of issuing -```fish -~ -> sudo pacman -Syu -``` +#terminal-root("~")[`pacman -Syu`] That's both true and false. -You have to make sure, /that your boot partition is mounted at `/boot`/ -in order for everything to upgrade correctly. That's because the moment -you upgrade the `linux` package without having the correct partition -mounted at `/boot`, your system won't boot. You also might have to do -#cmd("> grub-mkconfig -o /boot/grub/grub.cfg") after you install a different -kernel image. +You have to make sure, _that your boot partition is mounted at #filepath("/boot")_ in order for everything to upgrade correctly. That's because the moment you upgrade the `linux` package without having the correct partition mounted at #filepath("/boot"), your system won't boot. You also might have to do #cmd[`grub-mkconfig -o /boot/grub/grub.cfg`] after you install a different kernel image. -If your system _indeed doesn't boot_ and _boots to a recovery fish_, -then double check that the issue really is the not perfectly executed -kernel update by issuing +If your system _indeed doesn't boot_ and _boots to a recovery fish_, then double check that the issue really is the not perfectly executed kernel update by issuing -```fish -root in ~ -> uname -a -``` - -and - -```fish -root in ~ -> pacman -Q linux -``` +#terminal("~")[ + ``` + uname -a + + pacman -Q linux + ``` +] _The version of these two packages should be exactly the same!_ @@ -3426,147 +3024,237 @@ First off we need to restore the old `linux` package. For that note the version number of -```fish -root in ~ -> uname -a -``` +#terminal-root("~")[`uname -a`] -Now we'll make sure first that nothing is mounted at `/boot`, because +Now we'll make sure first that nothing is mounted at #filepath("/boot"), because the process will likely create some unwanted files. The process will -also create a new `/boot` folder, which we're going to delete -afterwards. +also create a new #filepath("/boot") folder, which we're going to delete +afterward. -```fish -root in ~ -> umount /boot -``` +#terminal-root("~")[`umount /boot`] Now `cd` into `pacman`'s package cache -```fish -root in ~ -> cd /var/cache/pacman/pkg -``` +#terminal-root("~")[`cd /var/cache/pacman/pkg`] There should be a file located named something like `linux-.pkg.tar.xz`, where `` would be somewhat equivalent to the previously noted version number Now downgrade the `linux` package -```fish -root in ~ -> pacman -U linux-.pkg.tar.xz -``` +#terminal-root("~")[`pacman -U linux-.pkg.tar.xz`] -After that remove the possibly created `/boot` directory +After that remove the possibly created #filepath("/boot") directory -```fish -root in ~ -> rm -rf /boot - -root in ~ -> mkdir /boot -``` +#terminal-root("/")[ + ``` + rm -rf /boot + + mkdir /boot + ``` +] Now reboot and mount the `boot` partition, in my case an EFI System partition. Now simply rerun -```fish -~ -> sudo pacman -Syu -``` +#terminal-root("~")[`pacman -Syu`] and you should be fine now. = Glossary This documentation is structured in a way that allows you to keep a printed version up to date without the need to reprint the whole thing. -This is why every section starts on a new page and page numbers are absent. +This is why every section starts on a new page and page numbers are omitted. + +In the following sections, I will quickly describe the meaning of a handfull of special markup, which hopefully makes the whole document more readable and structured. + +== Blocks + +There are special blocks that are supposed to draw your attention and seperate their contents: + +#note[ + This is a *note*. + This annotates some special edge cases, some #emph[gotcha]s, noteworthy stuff, etc. +] + +#tip[ + This is a *tip*. + This will often be employed if there is a scenario I often times struggled with, or if some special or unusual procedure is needed. +] + +#important[ + This is *important*. + Should probably be read and adhered to unless you know what you're doing. +] + +#warning[ + This gives you a *warning*. + In general, this includes big #emph[gotcha]s, problems, potentially breaking stuff, etc. +] + +#caution[ + This gives you the hint to proceed with *caution* and double-check! +] + == Programs, tools & terms Terms denoted by a `monospaced font` are mostly commands/programs or specific terms that are generally accepted to be a universal name for what they describe. + For example when I say that you need to `cd` into the directory, `cd` denotes the program/command I intend you to use. If I say you need to read the `PKGBUILD` or that you need to create an `EFI System Partition`, that in turn is the universally accepted name for both of those things. -== Commands +#note[ + Note however that in case of the mentioned programs, _`cd` into the direcory_, or reading the _`PKGBUILD`_, this is just the lowest level / highest abstraction version. I could instead use: + + - #pkg-aur("sbupdate-git") instead of e.g. `sbupdate-git`, if I assume you don't have the program yet and need the package / repository link _(explained in @packages)_ + - #cmd[`rm -rf folder/*.txt`], instead of the simple `rm -rf folder/*.txt` _(explained in @commands)_ + - #filepath("PKGBUILD") as a filepath descriptor, in place of `PKGBUILD` _(explained in @files)_ +] + +== Links + +Normally, you would simply embed a #link("https://archlinux.org")[link] into the document. + +But a reader of this guide who uses `Dead-Tree-Format`#emoji.tm aka. paper, will neither be able to distinguish the link from the rest of the text, nor be able to get any information regarding the target of the link. + +This is why I try and provide every link as a #linkfn("https://archlinux.org")[footnote-link], which works exactly like a regular link with the big difference that the link target is fully written out in the footnotes of the page. + +#note[ + The footnote numbering resets for each page, to ensure the `hot-swap`-ability of the pages as mentioned in @glossary. +] + +== Packages + +In order to +- not clutter the pages with install instructions / packages required for specific sections, +- group packages together so you can install everything in one go, +- and make them visibly stand out +I use two different markups for packages. + +If a package is simply mentioned within a paragprah, e.g. #pkg("alacritty"), it will be visually separated from the rest of the content and a link provided in the footnotes (see @links). + +This way you can also easily tell a normal package #pkg("alacritty") apart from an `AUR` package #pkg-aur("sbupdate-git"). +Both the packge name and the footnote-link are clickable and lead you to the generated URL. +#pagebreak() +The second option is a package-table which categorizes the packages into repositories. + +#pkgtable( + core: "base linux", + extra: "neovim pulseaudio", + multilib: "lib32-libpulse", +) + +In this case, you can click the globe symbol #emoji.globe.eu.af to get to the repository overview, or the package itself to get to the package. +The packages are, as you can see, also grouped together by repository. + +#important[ + As of _May 21st, 2023_, ArchLinux migrated to `git` packaging and in the process merged the `community` repository into `extra`. + This change will also be reflected in this document. + + Read #linkfn("https://archlinux.org/news/git-migration-completed/")[the announcment] for further information on how to proceed and update your system. +] + +== Commands + +Furthermore, I will denote a command execution in a shell with syntax highlighting and a different background: #cmd[`uname -a`]. +If a root shell is needed, I will denote it with a preceding #emoji.lock: #cmd(root: true)[`touch /root/testfile`]. -Furthermore I will denote a command execution in a shell with a preceding #cmd(">"): #cmd("> uname -a"). This then mostly includes any needed command line arguments. -== Commandblocks +== Console blocks -Multiple commands, where the execution user, or rather the privilege needed, as well as the current working directory are of interested, are displayed in a command execution block. -You can infer the privilege the command was executed by looking at the prompt line above the command, where the `root` username will be denoted if it's an elevated shell. -In any case the first line always contains the current working directory and the next line the prompt. +Multiple commands, where the execution user or rather the privilege needed, as well as the current working directory, are of interest, are displayed in a command execution block. +You can infer the privilege the command was executed by looking at the #emoji.lock symbol before the path. -```fish -~ -> git init +#note[ + Even when the command is executed in a root shell, the path #filepath("~") always refers to the local, _normal_ user's home directory (usually #filepath("/home/username")). -root in /boot -> ls -la -``` + Technically #filepath("~") #sym.eq.def #filepath("/root") is true, when in a root shell, but to reduce visual clutter, I decided to use this convention instead. +] -== Files +In any case, the first line always contains the current working directory and the next line is the prompt: -If the content of a file is of interest a file listing is used, which shows the (partial) content of the file together with the filename / the filepath. +#terminal("~")[`git init`] +#terminal-root("/etc")[`rm fstab`] +#pagebreak(weak: true) + +In case of a windows `cmd` command, you can easily distinguish it from the `linux` shell commands by the filepath descriptor, which of course uses Windows syntax, as well as a #emph("Window")s #emoji.window symbol: + +#terminal(windows: true, "C:\\Program Files (x86)\Common Files")[`dir`] + +== Files + +For the content of a file, a file listing is used, showing the content of the file as well as the full filepath: #filesrc("~/test.sh")[ -``` -#!/bin/bash - -echo test -``` + ```sh + #!/bin/bash + export var="value" + ``` ] -If the file is only partially displayed, or the listing is supposed to show an addition to a specific file, it is denoted by `[...]` being appended to the filepath - -#filesrc("~/test.sh [...]")[ -``` -echo appendage -``` +If the file is only partially displayed, or only an addition is shown, it is denoted by three dots #sym.dots being appended to the file path: +#filesrc(part: true, "~/test.sh")[ + ```sh + echo "appendage" + ``` ] -If I only want to _mention_ a file or path, I will denote it like this #path("~/test.sh"). - -== Blocks - -For special cases, noteworthy mentions, warning, etc. there are special text blocks that are supposed to draw your attention. - -#NOTE[ - This is a *note*. - This annotates some special edge case, some #text(style: "italic")[gotcha]s etc., in other words some useful information. +In case the file is _readonly_, I will use the glasses symbol #emoji.glasses, if you need elevated or specific permissions, the lock symbol #emoji.lock and if the file needs to be executable, the joystick symbol #emoji.joystick: +#filesrc(part: true, readonly: true, perm: true, "/etc/sudoers")[ + ``` + %wheel ALL=(ALL:ALL) ALL + ``` +] +#filesrc(exec: true, perm: true, "/root/prank.sh")[ + ```sh + #!/bin/bash + echo "It's just a prank" + ``` ] -#TIP[ - This is a *tip*. - This will often be employed if there is a scenario I often times struggled with, or if some special or unusual procedure is needed. - It just wants to give you a tip. -] - -#IMPORTANT[ - This is *important*. - Should probably be read and adhered to unless you know what you're doing. - I think this is self explanatory -] - -#WARNING[ - This gives you a *warning*. - I mean this is pretty self explanatory too. - In general this includes big #text(style: "italic")[gotcha]s, problems, potentially breaking stuff, etc. -] - -#CAUTION[ - This gives you the hint to proceed with *caution* and double check! -] +If I only want to _mention_ a file or path, I will denote it like this #filepath("~/test.sh"). == Explanations -If any term needs an explanation, I will explain it briefly in the following form. +If any term needs an explanation, I will explain it briefly in the following form: -/ term: Short explanation +/ Term: Short explanation +/ 2#super[nd] Term: + This is a long explanation.\ + With multiple lines and everything.\ + +There is also a variant with more space between the items: + +/ Term: Short explanation + +/ Another term: Another short explanation + +== Example section + +#pkgtable( + core: "base-devel", + extra: "ardour cadence git jsampler linuxsampler qsampler", + aur: "sbupdate-git", +) + +#note[ + You have to configure #pkg("sample-package"), or rather #pkg-aur("sample-package-git"), by editing #filepath("/etc/sample.conf") with e.g. #cmd[`nvim /etc/sample.conf`] + + #filesrc("/etc/sample.conf")[ + ``` + Sample.text=useful + ``` + ] +] + +If there is someting unusual going on, which you don't understand, try turning it off and on again. + +#caution[ + Bad joke detected! +] = Additional notes diff --git a/changelog.org b/changelog.org deleted file mode 100644 index cb8b32d..0000000 --- a/changelog.org +++ /dev/null @@ -1,3 +0,0 @@ -#+title: Changelog - -* Unreleased diff --git a/dustdoc.cls b/dustdoc.cls deleted file mode 100644 index 1c5faf8..0000000 --- a/dustdoc.cls +++ /dev/null @@ -1,190 +0,0 @@ -\NeedsTeXFormat{LaTeX2e} -\ProvidesClass{dustdoc}[DustVoice modified report class] - -\DeclareOption*{\PassOptionsToClass{\CurrentOption}{report}} -\ProcessOptions - -\LoadClass{report} - -\RequirePackage[document]{ragged2e} - -\RequirePackage[a5paper,margin=15mm]{geometry} - -\RequirePackage{color} -\RequirePackage{tcolorbox} - -\RequirePackage{epstopdf} - -\RequirePackage{amsmath} -\RequirePackage{amssymb} -\RequirePackage{amsthm} - -\RequirePackage{array} -\RequirePackage{caption} -% Replaced because outdated and unmaintained -%\RequirePackage{longtable} -%\RequirePackage{tabu} -\RequirePackage{tabularray} - -\RequirePackage{fix-cm} -\RequirePackage{fontspec} - -\RequirePackage{graphicx} -\RequirePackage{wrapfig} -\graphicspath{ {images/} } -\DeclareGraphicsExtensions{.png, .jpg, jpeg, .pdf} - -\RequirePackage{float} -\RequirePackage[newfloat]{minted} -\RequirePackage{fancyvrb} -\RequirePackage{fvextra} - -\RequirePackage{microtype} -\RequirePackage[htt]{hyphenat} -\RequirePackage{seqsplit} - -\RequirePackage{titling} -\RequirePackage{titlesec} -\RequirePackage{titletoc} - -\RequirePackage{hyperref} - -\hypersetup{ - colorlinks=true, - linkcolor=magenta, - urlcolor=blue, - pageanchor=false -} - -\makeatletter -\renewcommand{\minted@inputpyg}{% - \expandafter\let\expandafter\minted@PYGstyle% - \csname PYG\minted@get@opt{style}{default}\endcsname - \VerbatimPygments{\PYG}{\minted@PYGstyle}% - \ifthenelse{\boolean{minted@isinline}}% - {\ifthenelse{\equal{\minted@get@opt{breaklines}{false}}{true}}% - {\let\FV@BeginVBox\relax - \let\FV@EndVBox\relax - \def\FV@BProcessLine##1{% - \FancyVerbFormatLine{% - \FV@BreakByTokenAnywhereHook - \FancyVerbFormatText{\FancyVerbBreakStart##1\FancyVerbBreakStop}}}% - \minted@inputpyg@inline}% - {\minted@inputpyg@inline}}% - {\minted@inputpyg@block}% -} -\makeatother - -\setminted{breaklines=true,breakanywhere=true,breakbytoken=true,breakbytokenanywhere=true,tabsize=4,frame=single,framesep=.5em,samepage=false} -\setmintedinline{breaklines=true,breakanywhere=true,breakbytoken=true,breakbytokenanywhere=true} - -\fvset{breaklines=true,breakanywhere=true,breakbytoken=true,breakbytokenanywhere=true,tabsize=4,frame=single,framesep=.5em,samepage=false} -\DefineVerbatimEnvironment{verbatim}{Verbatim}{} - -\newcommand{\admonition}[2]{\textbf{#1}: {#2}} -\newcommand{\rolered}[1]{ \textcolor{red}{#1} } -\newcommand{\roleblue}[1]{ \textcolor{blue}{#1} } - -\newtheorem{example}{Example} -\newtheorem{note}{Note} - -\newenvironment{sidebar}[2] -{\begin{tcolorbox} - \begin{bf} - #1 - \end{bf} - \\#2} -{\end{tcolorbox}} - -\colorlet{admonitionBG}{black!5!white} -\definecolor{draculaBlue}{HTML}{6272a4} -\definecolor{draculaYellow}{HTML}{f1fa8c} -\definecolor{draculaRed}{HTML}{ff5555} -\definecolor{draculaOrange}{HTML}{ffb86c} -\definecolor{draculaPink}{HTML}{ff79c6} -\definecolor{draculaFG}{HTML}{f8f8f2} -\definecolor{draculaBG}{HTML}{282a36} - -\newenvironment{NOTE} -{\begin{tcolorbox}[before upper={\setlength{\parindent}{1.5em}\noindent}, colback=admonitionBG,coltitle=draculaFG,colframe=draculaBlue,colbacktitle=draculaBlue,title=NOTE]} -{\end{tcolorbox}} - -\newenvironment{TIP} -{\begin{tcolorbox}[before upper={\setlength{\parindent}{1.5em}\noindent},colback=admonitionBG,coltitle=draculaBG,colframe=draculaYellow,colbacktitle=draculaYellow,title=TIP]} -{\end{tcolorbox}} - -\newenvironment{IMPORTANT} -{\begin{tcolorbox}[before upper={\setlength{\parindent}{1.5em}\noindent},colback=admonitionBG,coltitle=draculaFG,colframe=draculaRed,colbacktitle=draculaRed,title=IMPORTANT]} -{\end{tcolorbox}} - -\newenvironment{WARNING} -{\begin{tcolorbox}[before upper={\setlength{\parindent}{1.5em}\noindent},colback=admonitionBG,coltitle=draculaBG,colframe=draculaOrange,colbacktitle=draculaOrange,title=WARNING]} -{\end{tcolorbox}} - -\newenvironment{CAUTION} -{\begin{tcolorbox}[before upper={\setlength{\parindent}{1.5em}\noindent},colback=admonitionBG,coltitle=draculaBG,colframe=draculaPink,colbacktitle=draculaPink,title=CAUTION]} -{\end{tcolorbox}} - -% See note for tabu -%\newenvironment{packagetable} -%{\begin{longtabu}to \textwidth [b]{X[1,r]|X[1,l]}} -%{\end{longtabu}} - -\NewTblrTheme{packagetable}{ - \DefTblrTemplate{head}{default}{} - \DefTblrTemplate{foot}{default}{} -} - -\newenvironment{pkgtable}[1] -{\begin{longtblr}[b, theme=packagetable]{colspec={X[1,r]|X[1,l]}, width=\textwidth}} -{\end{longtblr}} - -\newenvironment{pkgtblr}[1] -{\begin{longtblr}[b, theme=packagetable]{colspec={X[c]|X[c]|X[c]|X[c]}}} -{\end{longtblr}} - -\newenvironment{mintedlisting}{% - \begin{listing}[H]% - \captionsetup{% - format=plain,% - width=.75\textwidth,% - type=listing,% - justification=centering,% - singlelinecheck=off,% - position=bottom,% - skip=0pt,% - name=Code-Listing% - }% -}{% - \end{listing}% -} - -\newcommand{\chapterbreak}{\clearpage} -\newcommand{\sectionbreak}{\clearpage} -\newcommand{\subsectionbreak}{\clearpage} -\newcommand{\subsubsectionbreak}{\clearpage} -\dottedcontents{chapter}[1.5em]{}{1.5em}{1pc} -\dottedcontents{section}[3.25em]{}{3.25em}{1pc} -\dottedcontents{subsection}[5em]{}{5em}{1pc} -\dottedcontents{subsubsection}[6.75em]{}{6.75em}{1pc} - -\newcommand{\hreffn}[2]{\href{#1}{#2}\footnote{#1}} - -\setlength{\parindent}{1.5em} -\setlength{\parskip}{0.0pt plus 1.0pt} - -\setcounter{secnumdepth}{3} -\setcounter{tocdepth}{3} - -\pagenumbering{gobble} - -\renewcommand\maketitle{ - \begin{titlingpage} - \begin{center} - \includegraphics[width=\textwidth]{arch.png}\par\vspace{10em} - {\huge \thetitle}\par\vspace{2.5em} - {\LARGE \theauthor}\par\vspace{2.5em} - {\large \thedate}\par - \end{center} - \end{titlingpage} -} diff --git a/dustypst b/dustypst new file mode 160000 index 0000000..1da1823 --- /dev/null +++ b/dustypst @@ -0,0 +1 @@ +Subproject commit 1da18234c7eb002e8ff88fe9e4c1888e81440c78 diff --git a/notes.org b/notes.org deleted file mode 100644 index 80c3f6e..0000000 --- a/notes.org +++ /dev/null @@ -1,3 +0,0 @@ -#+title: Notes - -* Inbox diff --git a/todo.org b/todo.org deleted file mode 100644 index 92f1100..0000000 --- a/todo.org +++ /dev/null @@ -1,3 +0,0 @@ -#+title: Todo - -* Inbox