I have ported this Gist to a handbook. I'll not maintain this Gist anymore, but will keep it here for future references. You can access the respective chapter in the handbook here.
In this guide you will find:
- btrfs with Zstandard compression
- LUKS-encrypted root and swapfile
- GRUB with UEFI
You will not find:
- Instructions for file systems other than btrfs
- Full disk encryption (there's an official guide here)
- Explanation for all choices I've made (sometimes I don't know the true reason behind my choices)
There are two available users, root
(superuser) and anon
. The password of both is voidlinux
. I like to log in using the superuser so I don't have to type sudo
at all. I highly suggest you run exec bash
so you don't have to deal with dash
's limitations.
If you need a different layout other than en-US
, you can do the following:
# loadkeys $(ls /usr/share/kbd/keymaps/i386/**/*.map.gz | grep <your-layout>)
# cp /etc/wpa_supplicant/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-<wlan-interface>.conf
# wpa_passphrase <ssid> <passphrase> >> /etc/wpa_supplicant/wpa_supplicant-<wlan-interface>.conf
# sv restart dhcpcd
# ip link set up <interface>
The minimum number of partitions is three:
- The EFI partition (
/efi
) - The boot partition, where kernels are stored (
/boot
) - The LUKS-encrypted btrfs root partition
So, first we need to generate the partition tables. Check which device is the one you want to install Void into. For this guide I'll simply use /dev/sda
, but it can change depending on your setup, so watch out! Back to the partition tables:
# fdisk /dev/sda
After running fdisk
, it will prompt you with a menu, so follow these steps:
- Select
g
to generate a GTP table - Select
n
to create the EFI partition with size of +200M - After creating the partition, change its type by selecting
t
and then selecting the option that represents EFI Partition (generally 1) - Select
n
to create the boot partition with size of +500M (more space means more kernels, I like using +800M) - Select
n
to create the btrfs partition with the remaining size
# mkfs.vfat -nBOOT -F32 /dev/sda1
# mkfs.ext2 -L grub /dev/sda2
# cryptsetup luksFormat --type=luks -s=512 /dev/sda3
# cryptsetup open /dev/sda3 cryptroot
# mkfs.btrfs -L void /dev/mapper/cryptroot
First, let's mount the main btrfs partition:
# BTRFS_OPTS="rw,noatime,ssd,compress=zstd,space_cache,commit=120"
# mount -o $BTRFS_OPTS /dev/mapper/cryptroot /mnt
# btrfs subvolume create /mnt/@
# btrfs subvolume create /mnt/@home
# btrfs subvolume create /mnt/@snapshots
# umount /mnt
Then, let's mount the top-level partitions:
# mount -o $BTRFS_OPTS,subvol=@ /dev/mapper/cryptroot /mnt
# mkdir -p /mnt/home
# mount -o $BTRFS_OPTS,subvol=@home /dev/mapper/cryptroot /mnt/home
# mkdir -p /mnt/.snapshots
# mount -o $BTRFS_OPTS,subvol=@snapshots /dev/mapper/cryptroot /mnt/.snapshots
NOTE: Configure mount options according to your needs.
After that, let's mount some nested partitions, which won't have a snapshot taken, since snapshots don't work resursively:
# mkdir -p /mnt/var/cache
# btrfs subvolume create /mnt/var/cache/xbps
# btrfs subvolume create /mnt/var/tmp
# btrfs subvolume create /mnt/srv
You also need to create a nested subvolume for the swapfile:
# btrfs subvolume create /mnt/var/swap
Once the root partition is mounted, it is time to mount the remaining ones:
# mkdir /mnt/efi
# mount -o rw,noatime /dev/sda1 /mnt/efi
# mkdir /mnt/boot
# mount -o rw,noatime /dev/sda2 /mnt/boot
Set the appropriate variables (this may vary depending on your needs):
# REPO=https://alpha.us.repo.voidlinux.org/current
# ARCH=x86_64
If using musl
, the values might be something like:
# REPO=https://alpha.us.repo.voidlinux.org/current/musl
# ARCH=x86_64-musl
NOTE: Here is a handful of mirrors.
Then run:
XBPS_ARCH=$ARCH xbps-install -S -R "$REPO" -r /mnt base-system btrfs-progs cryptsetup
The command above installs the base system along with btrfs utilites, GRUB and dm-crypt utility, which are core parts of this setup.
Mount the pseudo file systems needed for a chroot
:
# for dir in dev proc sys run; do mount --rbind /$dir /mnt/$dir; mount --make-rslave /mnt/$dir; done
Copy the DNS configuration into the new root so that XBPS can still download new packages inside the chroot
:
# cp /etc/resolv.conf /mnt/etc/
Then chroot
into the new installation:
# BTRFS_OPTS=$BTRFS_OPTS PS1='(chroot) # ' chroot /mnt/ /bin/bash
Write the desired hostname to /etc/hostname
.
Refer to this documentation in order to configure your rc.conf
file.
For glibc installations, edit /etc/default/libc-locales
, then run:
(chroot) # xbps-reconfigure -f glibc-locales
(chroot) # passwd
(chroot) # UEFI_UUID=$(blkid -s UUID -o value /dev/sda1)
(chroot) # GRUB_UUID=$(blkid -s UUID -o value /dev/sda2)
(chroot) # ROOT_UUID=$(blkid -s UUID -o value /dev/mapper/cryptroot)
(chroot) # cat <<EOF > /etc/fstab
UUID=$ROOT_UUID / btrfs $BTRFS_OPTS,subvol=@ 0 1
UUID=$UEFI_UUID /efi vfat defaults,noatime 0 2
UUID=$GRUB_UUID /boot ext2 defaults,noatime 0 2
UUID=$ROOT_UUID /home btrfs $BTRFS_OPTS,subvol=@home 0 2
UUID=$ROOT_UUID /.snapshots btrfs $BTRFS_OPTS,subvol=@snapshots 0 2
tmpfs /tmp tmpfs defaults,nosuid,nodev 0 0
EOF
I advise doing a "hostonly" install, that is, Dracut will generate a lean initramfs with everything you might need, including i915
drivers if you have an Intel CPU with integrated graphics:
(chroot) # echo hostonly=yes >> /etc/dracut.conf
(chroot) # xbps-install -Su void-repo-nonfree intel-ucode
(chroot) # xbps-install grub-x86_64-efi
(chroot) # grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id="Void Linux"
In order to have an encrypted swap, let's use a more modern approach by using a swapfile as our swap partition. For this example, I'll create a swapfile of 16 GiB, but you can choose the best size for your installation:
(chroot) # btrfs subvolume create /var/swap
(chroot) # truncate -s 0 /var/swap/swapfile
(chroot) # chattr +C /var/swap/swapfile
(chroot) # btrfs property set /var/swap/swapfile compression none
(chroot) # chmod 600 /var/swap/swapfile
(chroot) # dd if=/dev/zero of=/var/swap/swapfile bs=1G count=16 status=progress
(chroot) # mkswap /var/swap/swapfile
(chroot) # swapon /var/swap/swapfile
After that, follow this Arch's guide on calculating the resume_offset
kernel parameter for btrfs.
HINT: You can use XBPS to compile the
btrfs_map_physical
for you by using my own template. Just clone the branch and usexbps-src
as usual topkg
thebtrfs_map_physical
package.
After calculating it, append the following line to GRUB's config:
(chroot) # RESUME_OFFSET=<calculated-offset-from-tutorial-above>
(chroot) # cat <<EOF >> /etc/default/grub
GRUB_CMDLINE_LINUX="resume=UUID=$ROOT_UUID resume_offset=$RESUME_OFFSET"
EOF
NOTE: You need Linux 5.0+ in order to use a swapfile with btrfs.
(chroot) # xbps-reconfigure -fa
(chroot) # exit
# shutdown -r now
Log in as root and then run:
# xbps-install -S zsh
# useradd -m -G wheel,input,video -s /bin/zsh <username>
# passwd <username>
# visudo
After running visudo
, uncomment the line that contains %wheel
. Log out and then log in with the newly created user.
NOTE: If you want to lock down the root account, you can run
sudo passwd -dl root
. Be careful though, since you won't be able to log in using the root account anymore.
Please refer to this official guide from the handbook.
Hi there! Thanks a lot for the install-description! I was searching for that. Cause I want to try install multiboot distro/BSD... Right now only GNU Linux, without BSD's, on just one btrfs partion.
The idea is to try to install it on just on 1 partion (sda1) with dos-MBR part-table. Then create on sda1 subvolumes like void-root, void-home etc. After that another distro again on sda1, but with subvol like artix-root,artix-boot etc. And of cource a subvolume for swap & data
Now I'm just trying it. After install I can say more. But one I know, that os-prober doesn't find distributions on same partion & different subvolumes. So I need to config it manually. But there is another instruction how to config grub for multiboot on btrfs subvolumes))
So what I thought. If I create nested subvolumes like
#btrfs subvolume create /mnt/var/tmp
btrfs subvolume create /mnt/srv
You also need to create a nested subvolume for the swapfile:
btrfs subvolume create /mnt/var/swap
So when I install a second distro with the same subvolumes like /mnt/var/tmp. Would be there a conflict? Cause the subvolume-name would be /mnt/var/tmp on both distros? Or would it register like child from exactly subvol=void-root? And not like child from whole btrfs ssda1 partion?
I like the way with nested subvolumes more. But not sure wouldit be a conflict between 2 distros with same subvol-name. Then my idea would be create all subvols as subvolid=5, and give them different names like void-root, void-tmp, void-xbps etc.