ArchLinux installation in VirtualBox

Table of contents
  1. 🔗Pre-installation
    1. 🔗First basic steps
    2. 🔗Partition the disks
    3. 🔗Preparing the logical volumes
  2. 🔗Installation
    1. 🔗Select the mirrors
    2. 🔗Install the base packages
    3. 🔗Fstab
    4. 🔗Chroot
    5. 🔗Time zone
    6. 🔗Localization
    7. 🔗Network configuration
    8. 🔗Initramfs
    9. 🔗Root password
    10. 🔗Boot loader
  3. 🔗Reboot
  4. 🔗Post-installation
    1. 🔗Before we begin
    2. 🔗System administration
      1. 🔗Users, groups and privilege escalation
    3. 🔗Package management
      1. 🔗Repositories
      2. 🔗Arch User Repository
    4. 🔗Graphical user interface
      1. 🔗Display server and display drivers
      2. 🔗Desktop environments
    5. 🔗Networking
    6. 🔗VirtualBox
      1. 🔗Install the Guest Additions
      2. 🔗Load the VirtualBox kernel modules
    7. 🔗General

First of all, this tutorial doesn't prevent you from following the ArchWiki - Installation guide, it is not standalone.

🔗Pre-installation

🔗First basic steps

For those first steps, I think you are a big boy enough to do them alone.

So you can download the ArchLinux iso, verify its signature, boot the live environment, set the keyboard layout, verify the boot mode, connect to the internet, update the system clock. If you're not confident with those steps check the ArchWiki.

While creating you new virtual machine, you'll need to configure the VM settings in Virtualbox.

If you want to install Arch Linux in EFI mode inside VirtualBox, in the settings of the virtual machine, choose System item from the panel on the left and Motherboard tab from the right panel, and check the checkbox Enable EFI (special OSes only).

In UEFI mode you may experience a black screen, see #Black screen for guest in EFI mode for a workaround.

🔗Partition the disks

Identify the block device associated to disks with lsblk or fdisk -l.

Now we will use LVM to manage the disk and assume there is only one physical disk.

UEFI is enabled, so I will use a GPT partition type and an EFI system partition (ESP).

So we will have two partitions: one ESP and one partition that will host the LVM container.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# fdisk /dev/sda
g # create GUID Partition Table (GPT)
n # create a new partition (EFI system partition)
1 # partition number
2048 # 1st sector
+550M # last sector
t # change partition type
1 # EFI system
n # create a new partition (LVM)
2 # partition number
<ENTER> # default 1st sector
<ENTER> # default last sector
t # change partition type
2 # select partiton 2
31 # partition type: Linux LVM
p # print the partition table
w # write table to disk and exit

🔗Preparing the logical volumes

Create a physical volume:

1
# pvcreate /dev/sda2

Create a volume group, adding the previously created physical volume to it:

1
# vgcreate myvg /dev/sda2

Create all your logical volumes on the volume group:

1
# lvcreate -l 100%FREE myvg -n root

Format your filesystems on each logical volume:

1
2
# mkfs.fat -F32 /dev/sda1
# mkfs.ext4 /dev/myvg/root # or /dev/mapper/myvg-root

Mount your filesystems:

1
2
3
# mount /dev/myvg/root /mnt
# mkdir /mnt/boot/ && mkdir /mnt/efi
# mount /dev/sda1 /mnt/efi # mount ESP to /efi outside /boot

Check the partition table: lsblk -f /dev/sda.

🔗Installation

🔗Select the mirrors

Again, here it let you select the mirrors.

🔗Install the base packages

Install the base + some useful packages:

1
# pacstrap /mnt base base-devel openssh sudo wget curl neovim lvm2

🔗Fstab

Generate an fstab file by UUID:

1
# genfstab -U /mnt >> /mnt/etc/fstab

Check /mnt/etc/fstab correctness and add /efi /boot none defaults,bind 0 0 to mount the EFI mountpoint at boot since we mounted ESP outside of /boot.

So you should have something similar to:

1
2
3
4
5
6
7
8
9
10
11
12
# Static information about the filesystems.
# See fstab(5) for details.

# <file system> <dir> <type> <options> <dump> <pass>
# /dev/mapper/myvg-root
UUID=a35deae9-84b3-4039-a70b-fcc9984bbd6c / ext4 rw,relatime 0 1

# /dev/sda1
UUID=BED1-3FAD /efi vfat rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 2

# bind mount EFI
/efi /boot none defaults,bind 0 0

🔗Chroot

Change root into the new system:

1
# arch-chroot /mnt

🔗Time zone

Set the time zone:

1
# ln -sf /usr/share/zoneinfo/Europe/Paris /etc/localtime

Run hwclock to generate /etc/adjtime:

1
# hwclock --systohc

🔗Localization

Uncomment locales in /etc/locale.gen, and generate them with:

1
# locale-gen

As I'm French, for me locales were:

1
2
en_US.UTF-8 UTF-8
fr_FR.UTF-8 UTF-8

Set variables in /etc/locale.conf, for example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
LC_ADDRESS=fr_FR.UTF-8
LC_COLLATE=fr_FR.UTF-8
LC_CTYPE=fr_FR.UTF-8
LC_IDENTIFICATION=fr_FR.UTF-8
LC_MONETARY=fr_FR.UTF-8
LC_MESSAGES=en_US.UTF-8
LC_MEASUREMENT=fr_FR.UTF-8
LC_NAME=fr_FR.UTF-8
LC_NUMERIC=fr_FR.UTF-8
LC_PAPER=fr_FR.UTF-8
LC_TELEPHONE=fr_FR.UTF-8
LC_TIME=fr_FR.UTF-8
LANG=en_US.UTF-8
LANGUAGE=en_US:en

Because I want all sort of format to be displayed like we do in France but keep the system and displayed messages in English.

Set the keyboard layout in /etc/vconsole.conf, for example (for AZERTY default keyboard):

1
KEYMAP=fr

🔗Network configuration

Create the hostname file (/etc/hostname):

1
archway

Add matching entries to /etc/hosts:

1
2
127.0.0.1 localhost
::1 localhost

🔗Initramfs

Configuring mkinitcpio HOOKS in /etc/mkinitcpio.conf to work with encrypt:

1
HOOKS=(base udev autodetect keyboard keymap consolefont modconf block lvm2 filesystems fsck)

Recreate the initramfs image:

1
# mkinitcpio -p linux

Mount ESP:

1
2
3
4
5
# mkdir -p /efi/EFI/BOOT
# cp -a /boot/vmlinuz-linux /efi/
# cp -a /boot/initramfs-linux.img /efi/
# cp -a /boot/initramfs-linux-fallback.img /efi/
# mount --bind /efi /boot

Warning: Virtualbox will ony see esp/EFI/BOOT/bootx64.efi automatically, see REFInd#VirtualBox.

🔗Root password

Easy!

Change root password:

1
# passwd

🔗Boot loader

I know what you're about to say:

WTF man! Why don't you use GRUB?

Because rEFInd works better for EFI partitions as the name states.

1
2
# pacman -S refind-efi
# refind-install --usedefault /dev/sda1

Then we need to edit /boot/refind_linux.conf:

1
2
3
4
5
"Boot with standard options"  "root=/dev/myvg/root rw add_efi_memmap initrd=/initramfs-%v.img"
"Boot to single-user mode" "root=/dev/myvg/root rw add_efi_memmap initrd=/initramfs-%v.img single"
"Boot with fallback initramfs" "root=/dev/myvg/root rw add_efi_memmap initrd=/initramfs-%v-fallback.img"
"Boot with minimal options" "ro root=/dev/mapper/myvg-root"
"Boot to terminal" "root=/dev/myvg/root rw add_efi_memmap systemd.unit=multi-user.target"

And also /efi/EFI/refind/refind.conf in order to work with %v in refind_linux.conf:

1
2
3
...
extra_kernel_version_strings linux-zen,linux-lts,linux
...

So this way we have to configure the boot entries only once for multiple kernels.

🔗Reboot

You know how to reboot right?

Ok ok, but it's better to quit the chroot and unmount all the partitions first umount -R /mnt.

🔗Post-installation

🔗Before we begin

It could be nice to setup a DHCP client to avoid manual IP configuration.

Enable DHCP client:

1
2
# systemctl start dhcpcd
# systemctl enable dhcpcd

Now we have Internet access, let's update the system before installing anything:

1
# pacman -Syu

We'll use a lot this terminal so let's get a fancier zsh shell:

1
# pacman -S zsh zsh-autosuggestions zsh-completions zsh-history-substring-search zsh-syntax-highlighting

🔗System administration

🔗Users, groups and privilege escalation

We already installed sudo with pacstrap.

Add a new user and assign sudo privilege

1
2
3
# useradd -m -G wheel -s /bin/zsh noraj
# passwd noraj
# visudo

And uncomment %wheel ALL=(ALL) ALL.

Exit root session and log back as user.

Creating default XDG directories

1
2
$ sudo pacman -S xdg-user-dirs
$ xdg-user-dirs-update

🔗Package management

🔗Repositories

Send stats about packages

1
$ sudo pacman -S pkgstats

🔗Arch User Repository

Install a pacman wrapper for AUR support, for example pikaur, pakku, yay:

1
2
3
4
5
$ sudo pacman -S git
$ cd /tmp
$ git clone https://aur.archlinux.org/pikaur.git
$ cd pikaur
$ makepkg -si

Please, don't install yaourt, check the pacman wrapper ArchWiki page.

🔗Graphical user interface

🔗Display server and display drivers

Install the display server, some utils and associated drivers

1
2
$ sudo pacman -S xorg-server xorg-xrandr
$ sudo pacman -S xf86-video-intel xf86-video-nouveau mesa mesa-demos

🔗Desktop environments

As we want a true graphical library backed desktop environment (understand a Qt DE as GTK is only the GIMP library), we have barely two choices: KDE or LXQT, but LXQT is very light (nice for a VM but too light for a nice desktop experience).

Install KDE Desktop Environment

1
2
$ sudo pacman -S plasma-meta
$ sudo systemctl enable sddm

Configure KDE:

  • System Settings > Startup and Shutdown > Background Services > disable all unneeded services
  • System Settings > Desktop Behavior > Desktop Effects > Disable Translucency that behave bad for dark themes.
  • System Settings > Search > File Search > Deselect "Enable File Search"
  • System Settings > Regional Settings > Set Language and Formats
  • System Settings > Input Devices > Keyboard > Layouts > Configure Layouts

Generate SDDM keyboard layout /etc/X11/xorg.conf.d/00-keyboard.conf:

1
$ sudo localectl set-x11-keymap fr

🔗Networking

If not already installed, install NetworkManager network manager and applets:

1
2
3
4
$ sudo pacman -S networkmanager kdeplasma-addons plasma-nm
$ sudo systemctl enable NetworkManager
$ sudo systemctl start NetworkManager
$ sudo systemctl disable netctl

Strenght of NetworkManager are: official package for KDE applet, integrated wifi manager, nice integration with KDE.

Drawback of NetworkManger: does not support the use of dhcpcd for IPv6 currently. So you can change for dhclient instead.

If you want to change to dhclient:

1
2
3
4
5
6
7
$ sudo pacman -S dhclient # not running as systemd service unlike dhcpcd
$ sudo systemctl disable dhcpcd
$ sudo systemctl stop dhcpcd
$ sudoedit /etc/NetworkManager/conf.d/dhcp-client.conf
[main]
dhcp=dhclient
$ sudo systemctl restart NetworkManager

Encrypted Wi-Fi passwords by using KDE wallet.

Disallow /etc/resolv.conf overwrite:

1
2
3
$ sudoedit /etc/NetworkManager/conf.d/dns.conf
[main]
dns=none

🔗VirtualBox

🔗Install the Guest Additions

Install virtualbox-guest-utils provided by virtualbox-guest-modules-arch if you plan to keep the default vanilla kernel, else install it from virtualbox-guest-dkms.

1
$ sudo pacman -S virtualbox-guest-utils

🔗Load the VirtualBox kernel modules

1
$ sudo systemctl enable vboxservice

🔗General

Install a VTE (Virtual Terminal Emulator):

1
$ sudo pacman -S qterminal konsole

Install net browsers, Firefox is far more powerful but use GTK where Falkon is using Qt but is far to be complete and fast. But anyway having several browser is always useful.

1
$ sudo pacman -S firefox falkon

Install general software:

1
$ sudo pacman -S code kate okular dolphin xsel p7zip unrar kvantum-qt5 openssh ksysguard htop

Install some fonts!

1
$ sudo pacman -S ttf-liberation noto-fonts ttf-roboto ttf-anonymous-pro ttf-hack ttf-inconsolata noto-fonts-emoji powerline-fonts adobe-source-code-pro-fonts ttf-fira-mono

Install oh-my-zsh:

1
2
$ pikaur -S oh-my-zsh-git
$ cp /usr/share/oh-my-zsh/zshrc ~/.zshrc

Install a konsole color scheme, I installed bl1nk.

Aliases for color:

1
2
3
4
5
6
7
8
9
10
11
12
13
alias diff='diff --color=auto'
alias grep='grep --color=auto'
alias ls='ls --color=auto'
export LESS=-R
man() {
LESS_TERMCAP_md=$'\e[01;31m' \
LESS_TERMCAP_me=$'\e[0m' \
LESS_TERMCAP_se=$'\e[0m' \
LESS_TERMCAP_so=$'\e[01;44;33m' \
LESS_TERMCAP_ue=$'\e[0m' \
LESS_TERMCAP_us=$'\e[01;32m' \
command man "$@"
}

Color wrappers:

1
$ sudo pacman -S grc

KDE Theme

1
$ sudo pacman -S papirus-icon-theme

SDDM theme: I installed Sugar Dark for SDDM.

Install a Terminal multiplexers:

1
$ sudo pacman -S tmux
Share