Skip to content

Instantly share code, notes, and snippets.

@PillTime
Last active March 9, 2024 13:26
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save PillTime/d1eea7b6e000112f7fd3da56962ad458 to your computer and use it in GitHub Desktop.
Save PillTime/d1eea7b6e000112f7fd3da56962ad458 to your computer and use it in GitHub Desktop.
Installing Arch Linux
I might make a big revision someday to review everything, fix anything that needs fixing, and explain the reason for each step. Maybe.

Installing Arch Linux

Small notes before we start:

  • Some computers won't work out of the box because of bugs left by the manufacturers.
Example My laptop spams tty1 with the following errors when the network card starts being used:
pcieport 0000:00:1c.5: AER:   Error of this agent reported first

pcieport 0000:00:1c.5: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID)
pcieport 0000:00:1c.5:   device [8086:9d15] error status/mask=00000001/00002000
pcieport 0000:00:1c.5:    [ 0] RxErr                  (First)

rtl8723be 0000:03:00.0: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID)
rtl8723be 0000:03:00.0:   device [10ac:b723] error status/mask=00000001/00006000
rtl8723be 0000:03:00.0:    [ 0] RxErr                  (First)

Upon investigating, adding the kernel parameters pci=noaer or pcie_aspm=off solves this issue.

  • Arch Linux now comes with an installer, so if you just want a minimal system ready in a few minutes, you're better off just doing archinstall.
  • The only officially supported architecture by Arch Linux is x86_64, so make sure your computer uses that architecture before attempting to install it.
  • This guide is for UEFI only, not BIOS.



Before we start

  • Write the Arch Linux ISO into a USB drive. There are several tools available for this, like dd, balenaEtcher, Rufus, or my personal favorite, Ventoy.
  • Disable Secure Boot in the UEFI.
  • Boot from the USB drive.



Preparations

  • After booting into the USB drive, type loadkeys (with a space at the end) and tap the TAB key a couple of times to select your keymap. You'll be able to use the arrow keys to move the selection. The most commonly used keymaps are in i386/qwerty.
  • Take a note of the keymap name. For example, if the final command is loadkeys i386/qwerty/pt-latin9.map.gz, the keymap name is pt-latin9 (everything between the last / and the first .). We'll need this name later.
  • Do ls /sys/firmware/efi | grep efi to verify that you have indeed booted in UEFI mode. The output should be efivars.

Time to connect to the Internet:

  • If you're not going to use DHCP, check the Arch Wiki on how to manually set a static IP.
  • If you're using a wired connection (recommended), it should already be working.
  • If you're using a wireless connection, the live system comes with iwd enabled, so you can use iwctl. iwctl's man page (man iwctl) shows a simple example on how to connect to a network.
    • If scanning with iwctl isn't working (you get no networks found), simply do systemctl restart iwd and try again.
  • Do ping -4c4 archlinux.org to verify that everything is working properly.

  • Now that we have an Internet connection, do timedatectl set-ntp true to update the live system clock.
  • You can then do timedatectl status to check the time (in the UTC timezone).

Onto partitioning the disk. This part is quite subjective, and can vary wildely depending on your needs. Consider reading more about this process instead of blindly following my instructions here.

I'll be using a single disk, creating the necessary partitions (ESP and root) and a SWAP partition. You can choose to simply not have a SWAP partition, or instead have a SWAP file. If you want a SWAP file, check the Arch Wiki. You'll need a SWAP if you want hibernation.

  • Do lsblk and identify your disk. Most of the time your disk will be identified as sda. If you're using NVMe, it'll most likely look something like nvme0n1. I'll use sda for the example.
  • Do gdisk /dev/sda, and then the commands o and w. They will "erase" everything in the disk and create a new partition table.
  • Do cgdisk /dev/sda:
    • Create the ESP partition (NECESSARY):
      • First sector is the default one.
      • Size is 1G.
      • Type is ef00.
      • Name is ESP.
    • Create the SWAP partition (OPTIONAL):
      • First sector is the default one.
      • Size is complicated. If unsure, use the amount of RAM (e.g. if you have 4GB of RAM, size is 4G).
      • Type is 8200.
      • Name is SWAP.
    • Create the / (root) partition (NECESSARY):
      • First sector is the default one.
      • Size is the default one.
      • Type is the default one.
      • Name is ROOT.
    • Hit [Write], and then [Quit].
  • Now to format the partitions:
    • Do mkfs.vfat -F 32 -n ESP /dev/disk/by-partlabel/ESP to format the ESP.
    • Do mkswap -L SWAP /dev/disk/by-partlabel/SWAP to format the SWAP partition.
    • Do mkfs.btrfs -L ROOT /dev/disk/by-partlabel/ROOT to format the / (root) partition.
  • Activate the SWAP partition with swapon /dev/disk/by-partlabel/SWAP.
  • Mount the / (root) partition with mount /dev/disk/by-partlabel/ROOT /mnt.
  • Do mkdir /mnt/boot to create a directory for the ESP.
  • Mount the ESP with mount /dev/disk/by-partlabel/ESP /mnt/boot.
  • Do lsblk /dev/sda to verify everything is correct. If you did exactly what I did, you should have something like this:
    • ESP (sda1 @ /mnt/boot)
    • SWAP (sda2 @ [SWAP])
    • / (root) (sda3 @ /mnt)



Installation

  • Open the file /etc/pacman.conf and uncomment the line #ParallelDownloads = 5.
  • Do pacman-key --refresh-keys to ensure the keyring is up to date.
  • Do pacstrap -i /mnt base{,-devel} btrfs-progs dkms linux{{,-lts}{,-headers},-firmware}:
    • For the dbus-units provider, select dbus-broker-units.
    • For the initramfs provider, select mkinitcpio.
  • Create the fstab file with genfstab -U /mnt >> /mnt/etc/fstab.



Basic system configuration

  • Do arch-chroot /mnt to go into your system.
  • Install some important packages with pacman -S dhclient git man-{db,pages} nano networkmanager openssh polkit vi vim zsh{,-{autosuggestions,completions,history-substring-search,syntax-highlighting}}.

  • Edit the file /etc/NetworkManager/conf.d/dhcp.conf to contain the following:
[main]
dhcp=dhclient
  • Edit the file /etc/NetworkManager/conf.d/dns.conf to contain the following:
[main]
dns=systemd-resolved
  • If you want to enable mDNS support, which is useful for adding network printers for example, do the following:
    • Edit the file /etc/systemd/resolved.conf and uncomment the line #MulticastDNS=yes
    • Edit the file /etc/NetworkManager/conf.d/dns.conf and add the following lines:
[connection]
connection.mdns=2

  • Do ln -svf /usr/share/zoneinfo/$(tzselect | tail -1) /etc/localtime to set your timezone.
  • Then, do hwclock -w to update the hardware clock.
  • You can do hwclock -r to see the current time stored by the hardware clock. You'll notice that it takes the timezone into account.

  • Open the file /etc/locale.gen. Uncomment the en_US.UTF-8 and any other locales you want to use.
  • Do locale-gen to generate the uncommented locales.
  • Do echo LANG=LOCALE > /etc/locale.conf, LOCALE being your preferred locale from the ones you just generated.
  • Do echo KEYMAP=KEYMAP > /etc/vconsole.conf, KEYMAP being the name of the keymap you're using (set when you used the loadkeys command earlier).
  • Do echo FONT=lat0-16 >> /etc/vconsole.conf. You can find all fonts available in /usr/share/kbd/consolefonts.

  • Do echo HOSTNAME > /etc/hostname, HOSTNAME being the name you want your system to have.
  • The hostname must be compatible with the following regex expression: ^(:?[0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z]|[0-9a-zA-Z]{1,63})$.
  • You can click here and put the hostname you want your computer to have in the text field to see if you can actually use it.
  • Edit the file /etc/hosts to contain the following:
# Static table lookup for hostnames.
# See hosts(5) for details.

127.0.0.1 localhost.localdomain localhost localhost-ipv4
::1       localhost.localdomain localhost localhost-ipv6
127.0.0.1 HOSTNAME.localdomain  HOSTNAME  HOSTNAME-ipv4
::1       HOSTNAME.localdomain  HOSTNAME  HOSTNAME-ipv6

HOSTNAME being the hostname you chose in the previous command.


  • Enable some services with systemctl enable sshd NetworkManager systemd-resolved.
  • If you have an SSD, do systemctl enable fstrim.timer.
  • Edit the file /etc/mkinitcpio.conf and change udev to systemd in the HOOKS list.
  • Update the initramfs by doing mkinitcpio -P.
  • Do passwd to give the root user a password.

  • Time to install the microcode updater:
    • If you're using an Intel CPU, do pacman -S intel-ucode.
    • If you're using an AMD CPU, do pacman -S amd-ucode.

  • Now all we need is a bootloader/bootmanager. There are two choices: GRUB and rEFInd.
  • The main differences between the two are very well explained here by the creator of rEFInd.
  • If installing GRUB:
    • Do pacman -S grub efibootmgr os-prober.
    • Then do grub-install --target=x86_64-efi --efi-directory=/boot --bootloader-id=GRUB.
    • Do grub-mkconfig -o /boot/grub/grub.cfg.
  • If installing rEFInd:
    • Do pacman -S refind.
    • Then do refind-install.
    • Do mkdir /etc/pacman.d/hooks and edit the file /etc/pacman.d/hooks/refind.hook to contain the following:
[Trigger]
Operation=Upgrade
Type=Package
Target=refind

[Action]
Description=Updating rEFInd in the ESP...
When=PostTransaction
Exec=/usr/bin/refind-install
  • Verify the hook is working by doing pacman -Syu refind | grep upgrading.
  • You should see evidence that the hook detects an already existing installation of rEFInd and upgrades it.
  • Edit the file /boot/EFI/refind/refind.conf:
    • Change timeout 20 to timeout 5.
    • Uncomment the line #fold_linux_kernels false.
    • Uncomment the line #extra_kernel_version_strings linux-lts,linux.
  • Do echo root=UUID=$(blkid -s UUID -o value /dev/disk/by-partlabel/ROOT) > /boot/refind_linux.conf.
  • Do echo resume=UUID=$(blkid -s UUID -o value /dev/disk/by-partlabel/SWAP) >> /boot/refind_linux.conf.
  • The only differences between these two commands is the beginning (root and resume), the partition (ROOT and SWAP), and the output redirection operator (> and >>).
  • Finally, edit the file /boot/refind_linux.conf to contain the following:
"Arch Linux"       "root=UUID=XXXX resume=UUID=YYYY rw initrd=UCODE.img initrd=initramfs-%v.img EXTRA"
"Arch Linux (CLI)" "root=UUID=XXXX resume=UUID=YYYY rw initrd=UCODE.img initrd=initramfs-%v.img systemd.unit=multi-user.target EXTRA"

XXXX and YYYY being the UUIDs that were already on the file (don't change them!). UCODE being the package you installed for the microcode updater. EXTRA being the extra kernel parameters you used to boot the live system.


  • Do exit and then umount -R /mnt.
  • You can now do poweroff.

Congratulations! You've installed Arch Linux!

But we're not done yet. We still have to create a user and do some final touches.




Creating a user

  • Start by logining in as root. Do ln -svf /run/systemd/resolve/resolv.conf /etc/resolv.conf.
  • Change root's shell by doing chsh -s /bin/zsh.
  • Do timedatectl set-ntp true and timedatectl status again to make sure the time is setup correctly. The RTC and Universal time should be in UTC and the Local time in your timezone.

  • Now add a user by doing useradd -m -U -G wheel -s /bin/zsh -c "REAL NAME" USERNAME, REAL NAME being the user's real name, and USERNAME a valid username.
  • Usernames in Unix-like OSs are valid if they're compatible with the regex expression ^[a-z_]([0-9a-z_-]{0,31}|[0-9a-z_-]{0,30}\$)$.
  • You can check if a username is valid by clicking here.
  • Set the user's password with passwd USERNAME.
  • Do visudo, or, if you don't know how to use vi, do EDITOR=nano visudo, and do the following changes:
    • Add the line Defaults pwfeedback, preferably before ## Runas alias specification, if you want asterisks when inputting your password.
    • Uncomment the line # %wheel ALL=(ALL) ALL.

  • Do nmtui and setup your Internet connection.
  • Open the file /etc/pacman.conf and perform the following:
    • Uncomment the line #Color, and create a new line below with the content ILoveCandy (yes, I'm serious).
    • Uncomment the line #ParallelDownloads = 5.
    • Uncomment the line #[multilib] and the line below it.
  • Do pacman -Syu to update pacman's configuration and to perform any updates available.
  • Logout with logout.



User configuration

  • Login as the user you've created. In the ZSH configuration, continue to configure zsh or press q to quit if you already have a configuration in your dotfiles.
  • Do sudo pacman -S bat lm_sensors neo{fetch,vim}.
  • Do mkdir ~/.config/{nano,nvim,zsh}.
  • Configure the files ~/.zshenv, ~/.config/nano/nanorc, ~/.config/nvim/init.vim, and ~/.config/zsh/.zshrc.
  • Or, instead of configuring them, use your saved dotfiles if you have any. Mine are here.

  • Do rm ~/.bash*
  • Logout and log in as root.
    • Do rm ~/.bash*.
    • Do mkdir -p ~/.config/zsh.
    • Do ln -s /home/USERNAME/.zshenv ~.
    • Do ln -s /home/USERNAME/.config/zsh/.zshrc ~/.config/zsh.
  • Logout as log back in as the created user.

  • Now let's install paru, which is a pacman wrapper.
  • Do git clone --depth=1 https://aur.archlinux.org/paru-bin.git, then cd paru-bin, and then makepkg -sir.
  • After the installation is done, do cd .., and then rm -rf paru-bin.
  • From now on you'll be using paru instead of sudo pacman.
  • I also recommend you configure paru before actually using it.
  • Do paru -S xdg-user-dirs and then xdg-user-dirs-update.
  • Do paru -S archlinux-contrib rebuild-detector pacman-cleanup-hook.

  • If you use an AMD GPU, edit /etc/udev/rules.d/30-amdgpu-pm.rules and add:
KERNEL=="card0", SUBSYSTEM=="drm", DRIVERS=="amdgpu", ATTR{device/power_dpm_force_performance_level}="high"
  • Reboot.

Congratulations! You finally have a usable, minimal Arch Linux installation.


TODO:

  • deep read on the general recommendations page
  • check ending of section 3.2 on btrfs in archwiki
@feztix
Copy link

feztix commented Feb 3, 2021

Huge thanks. A great guide

@FaulkNet
Copy link

FaulkNet commented Sep 5, 2022

This is a fabulous base installation guide. I used it as a reference to revamp an older system and give it a more modern foundation with GPT, rEFInd, and Zsh. Just what the doctor ordered! Thank you sir!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment