Introduction
The goal of this article is to explain the installation of Linux distribution with some specificities:
-
The Linux distribution is an Arch Linux
-
The computer is UEFI compatible
-
The disk is a SSD
-
BTRFS will be the file system used
-
Use the BTRFS capabilities to split the
/
,/opt
,/home
and/var
-
The network is a wireless connection, configured with
netctl
Run the Arch Linux installer
First of all, you need to download the ISO (around 550Mb) from the Arch Linux
site
(magnet
or torrent) and
copy it on a USB key or burn it on a CD. To make a copy on a USB key, you can
use the dd
tool.
$ dd if=archlinux-2013.10.01-dual.iso of=/dev/sdb
considering /dev/sdb
is the device’s file for the USB key.
On Mac OS X, you will not have /dev/sdb
but something like /dev/rdisk2
.
You can now run your Arch Linux on the computer you want to install.
Initializations
First of all, you may want to change the keyboard layouts and the locales. For
the keyboard layout, use the loadkeys
tool.
$ loadkeys fr-pc
For the locales, edit the /etc/locale.gen
file and uncomment the locale your
want (you can uncomment more than one). Then generate the new locales and
export your new default locale.
$ locale-gen $ echo LANG=fr_FR.UTF-8 > /etc/locale.conf $ export LANG=fr_FR.UTF-8
You may change the terminal’s font with the following.
$ setfont Lat2-Terminus16
Partitionning
Our installation will consider that the computer is UEFI compatible. UEFI is
compatible with both MBR and GPT partitionning. However, GPT is the standard
way to do it. In order to partition the disk, we will use the GPT version of
fdisk
, which is gdisk
, on the main disk /dev/sda
.
$ gdisk /dev/sda
gdisk
brings you to a new shell. We will create 2 partitions:
-
The first partition will be the EFI partition
-
The second partition will be the partition for the Linux system
These are the operations you should do:
-
type
o
and validate to create the GPT partitionning -
type
n
and validate to create a new partition -
enter the partition number or just validate for the default (the default should be good)
-
enter the first sector or just validate for the default (the default should be good)
-
enter the last sector or the size of your volume; for EFI, enter
+512M
and validate -
enter the type of the partition; for EFI, enter
EF00
and validate -
type
n
and validate to create a new partition -
enter the partition number or just validate for the default (the default should be good)
-
enter the first sector or just validate for the default (the default should be good)
-
enter the last sector or the size of your volume; for Linux system, validate the default which is the last sector of the disk
-
enter the type of the partition; for Linux system, enter
8300
and validate -
type
w
and validate to write all the modifications on the disk.
Formatting
The formatting is pretty easy. The EFI partition should be format in a FAT filesystem (16 or 32). The second partition will be format in BTRFS since it one of the purpose of this article.
$ mkfs.vfat -F32 -n "EFI" /dev/sda1 $ mkfs.btrfs -L "Arch Linux" /dev/sda2
Managing the BTRFS subvolumes
Mounting the main BTRFS volume
First of all, we will mount the BTRFS partition.
$ mkdir -p /mnt/btrfs-root $ mount -o defaults,relatime,ssd,discard,space_cache /dev/sda2 /mnt/btrfs-root
discard
and ssd
mount options are optimizations for SSD drives. discard
is to activate `Discard/TRIM'' optimizations and `ssd
is for specific BTRFS
optimization on SSD drives.
Creating and mounting the BTRFS subvolumes
Then we can create the subvolumes in the BTRFS partition.
$ mkdir -p /mnt/btrfs-root/__snapshot $ mkdir -p /mnt/btrfs-root/__active $ btrfs subvolume create /mnt/btrfs-root/__active/ROOT $ btrfs subvolume create /mnt/btrfs-root/__active/home $ btrfs subvolume create /mnt/btrfs-root/__active/opt $ btrfs subvolume create /mnt/btrfs-root/__active/var
We can now mount the subvolumes in the right order.
$ mkdir -p /mnt/btrfs-active $ mount -o \ defaults,nodev,relatime,ssd,discard,space_cache,subvol=__active/ROOT \ /dev/sda2 /mnt/btrfs-active
We create the directories in this new-mounted subvolume and mount the other subvolumes.
$ mkdir -p /mnt/btrfs-active/home $ mkdir -p /mnt/btrfs-active/opt $ mkdir -p /mnt/btrfs-active/var/lib $ mount -o \ defaults,nosuid,nodev,relatime,ssd,discard,subvol=__active/home \ /dev/sda2 /mnt/btrfs-active/home $ mount -o \ defaults,nosuid,nodev,relatime,ssd,discard,subvol=__active/opt \ /dev/sda2 /mnt/btrfs-active/opt $ mount -o \ defaults,nosuid,nodev,noexec,relatime,ssd,discard,subvol=__active/var \ /dev/sda2 /mnt/btrfs-active/var
Tricky part for the /var/lib
directory
However, the /var/lib
is the directory in which some interesting files are
installed and we want to keep them in the __active/ROOT
subvolume to make
easier the snapshot procedure. Remember, we create a directory in this
subvolume. So we will bind it.
$ mkdir -p /mnt/btrfs-active/var/lib $ mount --bind /mnt/btrfs-root/__active/ROOT/var/lib \ /mnt/btrfs-active/var/lib
Mount the EFI partition into the main directory layout
At this point, we should mount the EFI partition as the /boot
directory.
$ mkdir -p /mnt/btrfs-active/boot $ mount -o \ defaults,nosuid,nodev,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro,discard \ /dev/sda1 /mnt/btrfs-active/boot
Install the base system
Before being able to install the base system, you need to configure a network
connection. If you want a wireless connection, you can simply use wifi-menu
.
It will display you a menu where you can choose a wireless network and enter
your password (in clear).
You may update the list of mirrors /etc/pacman.d/mirrorlist
before running the following command.
The base
package will install a base system for your Arch Linux. Because we
use a BTRFS system, we also install btrfs-progs
package (we could install it
later too).
$ pacstrap /mnt/btrfs-active base btrfs-progs
We must now generate and configure the fstab
file with the help of genfstab
.
$ genfstab -U -p /mnt/btrfs-active >> /mnt/btrfs-active/etc/fstab
You should modify the /etc/fstab
file and make it looks like something like
the following.
tmpfs /tmp tmpfs rw,nodev,nosuid 0 0
tmpfs /dev/shm tmpfs rw,nodev,nosuid,noexec 0 0
# /dev/sda1 LABEL=Arch\x20Linux
UUID=... / btrfs rw,nodev,relatime,ssd,discard,space_cache,subvol=__active/ROOT 0 0
UUID=... /home btrfs rw,nodev,nosuid,relatime,ssd,discard,space_cache,subvol=__active/home 0 0
UUID=... /opt btrfs rw,nodev,nosuid,relatime,ssd,discard,space_cache,subvol=__active/opt 0 0
UUID=... /var btrfs rw,nodev,nosuid,noexec,relatime,ssd,discard,space_cache,subvol=__active/var 0 0
UUID=... /run/btrfs-root btrfs rw,nodev,nosuid,noexec,relatime,ssd,discard,space_cache 0 0
/run/btrfs-root/__active/ROOT/var/lib /var/lib none bind 0 0
# /dev/sdb1 LABEL=EFI
UUID=... /boot vfat rw,nosuid,nodev,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro,discard 0 2
Be careful about the configuration of /var/lib
. In fact,
we need to mount the main BTRFS partition in order to access the directory that
should be binded. Moreover, do not forget to check the line about the /boot
partition.
We also need to create the directory where the root BTRFS partition will mount
(see in the fstab
).
$ mkdir -p /mnt/btrfs-active/run/btrfs-root
Configure the base system
You will now root from the newly installed base system with a arch-chroot
.
The configuration begins with mainly the same operations that we have done before.
$ echo "KEYMAP=fr-pc" > /etc/vconsole.conf $ echo "FONT=Lat2-Terminus16" >> /etc/vconsole.conf $ echo "fr_FR.UTF-8 UTF-8" > /etc/locale.gen $ locale-gen $ echo "LANG=fr_FR.UTF-8" > /etc/locale.conf $ export LANG=fr_FR.UTF-8 $ ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime $ hwclock --systohc --utc $ echo "mypc" > /etc/hostname $ passwd
Configure a wireless network connection
We will configure a default profile for a wireless connection with SSID
mySSID
and a WPA security. Then we will make this connection automatic with
wpa_actiond
. Begin to install wpa_actiond
with the base package netctl
.
The dialog
package allow us the use of wifi-menu
to generate netctl
profiles.
$ pacman -S netctl iw dialog wpa_actiond
Then create a netctl
profile from an example file. You can either
automatically generate a profile file with wifi-menu
or use the manual
configuration below.
$ cp /etc/netctl/examples/wireless-wpa-config /etc/netctl/profile
You should modify /etc/netctl/profile
to make it look like the following.
Description='A wpa_supplicant configuration file based wireless connection'
Interface=wlp3s0
Connection=wireless
Security=wpa-config
WPAConfigFile='/etc/wpa_supplicant/wpa_supplicant.conf'
IP=dhcp
Do not forget to change the path to the wpa_supplicant.conf
file which should
be /etc/wpa_supplicant/wpa_supplicant.conf
.
Now, we can configure the WPA configuration of our mySSID
wifi network. To
configure this network, we use wpa_passphrase
. We first backup the default
configuration file.
$ cp /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant.conf.example $ wpa_passphrase "mySSID" "mypassword" > /etc/wpa_supplicant/wpa_supplicant.conf
Do not forget the double quotes, especially if the SSID contains spaces. You may edit the file and remove the password which appear in clear.
You can now enable this service.
$ systemctl enable netctl-auto@wlp3s0.service
Configure the initial ramdisk environment
To generate the initial ramdisk, because you run with BTRFS partitions, you
should modify some hooks in the /etc/mkinitcpio.conf
. We will add a hook for
btrfs
. For this new hook, we must install the package btrfs-progs
.
Secondly, BTRFS does not have a robust check file system so if we have the
fsck
hook, it will display an error. We have 2 solutions:
-
We erase the
fsck
hook and there will not have file system check anymore, even if other partitions are not BTRFS -
We can create a fake
fsck.btrfs
command$ ln -s /usr/bin/true /usr/bin/fsck.btrfs $ sed 's/^\(HOOKS=.*fsck\)\(.*$\)/\1 btrfs\2/g' -i mkinitcpio.conf $ mkinitcpio -p linux
Install and configure the bootloader
I choose gummiboot
bootloader which is a simple bootloader for EFI systems.
First of all, you install it. Before installing it, you may mount the
efivarfs
.
$ mount -t efivarfs efivarfs /sys/firmware/efi/efivarfs $ pacman -S gummiboot $ gummiboot install
Now, we can configure the bootloader following the specifications propose by http://www.freedesktop.org (see the references). Before configuring it, we will get the following variable:
$ export MACHINE_ID=`cat /etc/machine-id` $ export KERNEL_VERSION=`uname -r` $ export OS_IDENTIFIER=`cat /etc/os-release | grep ID | awk -F '=' '{print $2}'` $ export MACHINE_HARDWARE=`uname -m` $ export OS_VERSION=`echo $KERNEL_VERSION.$OS_IDENTIFIER.$MACHINE_HARDWARE` $ export PARTUUID=`ls -l /dev/disk/by-partuuid/ | grep sda2 | awk '{print $9}'`
Create an entry in /boot/loader/entries
.
$ vi /boot/loader/entries/$MACHINE_ID-$OS_VERSION.conf
title Arch Linux version <value of $OS_VERSION> machine-id <value of $MACHINE_ID> options root=PARTUUID=<value of $PARTUUID> rootflags=subvol=__active/ROOT rw linux /<value of $MACHINE_ID>/<value of $OS_VERSION>/linux initrd /<value of $MACHINE_ID>/<value of $OS_VERSION>/initrd
We may also configure the main configuration file /boot/loader/loader.conf
.
timeout 3 default <name of the entries conf file, without the '.conf'>
The default should be fine since it use any entry file which begin with the machine ID.
You should now create the directories and copy the images into them.
$ mkdir -p /boot/$MACHINE_ID/$OS_VERSION $ cp /boot/vmlinuz-linux /boot/$MACHINE_ID/$OS_VERSION/linux $ cp /boot/initramfs-linux.img /boot/$MACHINE_ID/$OS_VERSION/initrd
Rebooting the system
Before rebooting, you should define a root password, unmount all the mounted filesystems and quit the
chroot
environment.
$ umount /sys/firmware/efi/efivarfs $ exit $ umount -R /mnt/btrfs-active $ umount -R /mnt/btrfs-root $ reboot
Possible errors
Make the ramdisk environment
You may have the following messages during the creation of the ramdisk.
==> WARNING: Possibly missing firmware for module: aic94xx ==> WARNING: Possibly missing firmware for module: bfa ==> WARNING: Possibly missing firmware for module: smsmdtv
It is probably some missing firmware you may install later.
Gummiboot installation
When installing gummiboot
with pacman
, you may have the following error message.
$ pacman -S gummiboot ... Copied /usr/lib/gummiboot/gummibootx64.efi to /boot/EFI/gummiboot/gummibootx64.efi Copied /usr/lib/gummiboot/gummibootx64.efi to /boot/EFI/Boot/BOOTX64.efi Failed to create EFI Boot variable entry: No such file or directory
If this is the case, you may try the following before trying to reinstall
gummiboot
.
$ mount -t efivarfs efivarfs /sys/firmware/efi/efivarfs $ pacman -S gummiboot
When rebooting, crash into ramfs
You may crash into the ramfs
when rebooting. This is probably because you
forget to indicate to the kernel which BTRFS subvolume is the default one. You
may choose one of the two following solutions (both are explained in the above configuration):
-
Give the right option to the kernel with
rootflags
(see above for details) -
Make one of the BTRFS subvolume the default. You can list the subvolume with the following command.
$ btrfs subvolume list -atp /mnt/btrfs-root
You should have something like the following
ID gen parent top level path -- --- ------ --------- ---- 256 18 5 5 __active/ROOT 257 7 5 5 __active/home 258 8 5 5 __active/opt 259 18 5 5 __active/var
We will now set the default subvolume which will be used by the kernel to launch
the system. Keep the ID of the __active/ROOT
subvolume and use it in the following command.
$ btrfs subvolume set-default 256 /mnt/btrfs-root/__active/ROOT
Be aware that this solution will fail to mount the root BTRFS system since it
will mount instead this default subvolume. You may avoid it in the previous
configuration because the root BTRFS file system must be mount in order to bind
/var/lib
.
References
For this article, there is two main references. The first one is the Beginner’s guide for Arch Linux installation. There is a lot of information on how to install an Arch Linux distribution and a lot of links to explain the details.
The second reference is mainly about the BTRFS configuration suggest by Fabio Mancinelli in his article.