Skip to content

Instantly share code, notes, and snippets.

@s0dyy
Last active May 7, 2024 13:50
Show Gist options
  • Save s0dyy/905be36b2c39fb8c14906e15c05c68a3 to your computer and use it in GitHub Desktop.
Save s0dyy/905be36b2c39fb8c14906e15c05c68a3 to your computer and use it in GitHub Desktop.
Exherbo Linux Install (ESP / XBOOTLDR / BTRFS ON LUKS / SYSTEMD-BOOT / DRACUT)
  ________   ___    _ ______ _____  ____   ____       _____ _   _  _____ _______       _      _      
 |  ____\ \ / / |  | |  ____|  __ \|  _ \ / __ \     |_   _| \ | |/ ____|__   __|/\   | |    | |     
 | |__   \ V /| |__| | |__  | |__) | |_) | |  | |______| | |  \| | (___    | |  /  \  | |    | |     
 |  __|   > < |  __  |  __| |  _  /|  _ <| |  | |______| | | . ` |\___ \   | | / /\ \ | |    | |     
 | |____ / . \| |  | | |____| | \ \| |_) | |__| |     _| |_| |\  |____) |  | |/ ____ \| |____| |____ 
 |______/_/ \_\_|  |_|______|_|  \_\____/ \____/     |_____|_| \_|_____/   |_/_/    \_\______|______|

NVME / ESP / XBOOTLDR / BTRFS ON LUKS / SYSTEMD-BOOT / DRACUT

This guide is based on several documentations

Exherbo

Systemd

Freedesktop

 

1. Boot a live system

Download SystemRescueCD, Archlinux or other live systems.

Put it on the usb stick:

root@archiso ~ # dd if=/path/to/system-x.y.z.iso of=/dev/sdx

Reboot

 

2. Prepare the hard disk

Disk layout:

+-----------------+ +-----------------+ +-----------------------------------------------------------------------+
|       ESP       | |     XBOOTLDR    | |    Subvolume 1    |      Subvolume 2     |        Subvolume 3         |
|                 | |                 | |                   |                      |                            |
|      /efi       | |      /boot      | |       @ or /      |    @home or /home    |  @snapshots or /.snapshot  |
|                 | |                 | |                   |                      |                            |
|                 | |                 | |_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ __ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ ____|
|                 | |                 | |                                                                       |
| /dev/nvme0n1p1  | | /dev/nvme0n1p2  | |               LUKS2 encrypted partition nvme0n1p3                     |
|                 | |                 | |                                                                       |
+-----------------+ +-----------------+ +-----------------------------------------------------------------------+

Create a new GPT disklabel and three partitions, one for the ESP (~100mb), one for the XBOOTLDR (~200mb) and another one for the LUKS container (the remaining disk space).

root@archiso ~ # fdisk /dev/nvme0n1

Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): g
Created a new GPT disklabel (GUID: AF3C933D-3C72-4342-8CBA-057327B4FD1A).

Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-1000215182, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-1000215182, default 1000215182): +100MB

Created a new partition 1 of type 'Linux filesystem' and of size 95 MiB.

Command (m for help): t
Selected partition 1
Partition type or alias (type L to list all): 1
Changed type of partition 'Linux filesystem' to 'EFI System'.

Command (m for help): n
Partition number (2-128, default 2):
First sector (196608-1000215182, default 196608):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (196608-1000215182, default 1000215182): +200MB

Created a new partition 2 of type 'Linux filesystem' and of size 191 MiB.

Command (m for help): t
Partition number (1,2, default 2):
Partition type or alias (type L to list all): 48

Changed type of partition 'Linux filesystem' to 'Linux extended boot'.

Command (m for help): n
Partition number (3-128, default 3):
First sector (587776-1000215182, default 587776):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (587776-1000215182, default 1000215182):

Created a new partition 3 of type 'Linux filesystem' and of size 476.7 GiB.

Command (m for help): p
Disk /dev/nvme0n1: 476.94 GiB, 512110190592 bytes, 1000215216 sectors
Disk model: WDC PC SN720 SDAQNTW-512G-1001
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: AF3C933D-3C72-4342-8CBA-057327B4FD1A

Device          Start        End   Sectors   Size Type
/dev/nvme0n1p1   2048     196607    194560    95M EFI System
/dev/nvme0n1p2 196608     587775    391168   191M Linux extended boot
/dev/nvme0n1p3 587776 1000215182 999627407 476.7G Linux filesystem

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Format EFI Partition:

root@archiso ~ # mkfs.vfat -F32 /dev/nvme0n1p1

Format BOOT Partition:

root@archiso ~ # mkfs.vfat -F32 /dev/nvme0n1p2

Create the LUKS encrypted container and open it:

root@archiso ~ # cryptsetup --cipher aes-xts-plain64 --hash sha512 --use-random --verify-passphrase luksFormat /dev/nvme0n1p3
root@archiso ~ # cryptsetup open /dev/nvme0n1p3 root

Format LUKS container

root@archiso ~ # mkfs -t btrfs --force -L root /dev/mapper/root

Create BTRFS subvolumes:

root@archiso ~ # mount -t btrfs -o compress=zstd /dev/mapper/root /mnt

root@archiso ~ # btrfs subvolume create /mnt/@
root@archiso ~ # btrfs subvolume create /mnt/@home
root@archiso ~ # btrfs subvolume create /mnt/@snapshots

Unmount the system partition at /mnt

root@archiso ~ # umount /mnt

Mount options:

root@archiso ~ # o=defaults,x-mount.mkdir
root@archiso ~ # o_btrfs=$o,compress=zstd,ssd,noatime

Mount new subvolumes:

root@archiso ~ # mount -o compress=zstd,subvol=@,$o_btrfs /dev/mapper/root /mnt
root@archiso ~ # mount -o compress=zstd,subvol=@home,$o_btrfs /dev/mapper/root /mnt/home
root@archiso ~ # mount -o compress=zstd,subvol=@snapshots,$o_btrfs /dev/mapper/root /mnt/.snapshots

Get the latest automatically-built daily archive of Exherbo from Stages and verify the consistence of the file:

root@archiso ~ # cd /mnt
root@archiso /mnt # curl -O https://dev.exherbo.org/stages/exherbo-x86_64-pc-linux-gnu-current.tar.xz
root@archiso /mnt # curl -O https://dev.exherbo.org/stages/sha1sum
root@archiso /mnt # grep exherbo-x86_64-pc-linux-gnu-current.tar.xz sha1sum | sha1sum -c

Extract the stage:

root@archiso /mnt # tar xJpf exherbo*xz

 

3. Chroot into the system

Mount everything for the chroot:

root@archiso ~ # mount -o rbind /dev /mnt/dev/
root@archiso ~ # mount -o bind /sys /mnt/sys/
root@archiso ~ # mount -t proc none /mnt/proc/
root@archiso ~ # mount /dev/nvme0n1p1 -o x-mount.mkdir /mnt/efi
root@archiso ~ # mount /dev/nvme0n1p2 /mnt/boot

Make sure the network can resolve DNS:

root@archiso ~ # cp /etc/resolv.conf /mnt/etc/resolv.conf

Change your root:

root@archiso ~ # env -i TERM=$TERM SHELL=/bin/bash HOME=$HOME $(which chroot) /mnt /bin/bash
root@archiso / # source /etc/profile
root@archiso / # export PS1="(chroot) $PS1"

 

4. Update the install

Make sure Paludis is configured correctly:

(chroot) root@archiso ~ # cd /etc/paludis && vim bashrc && vim *conf

Sync all the trees – now it is safe to sync

(chroot) root@archiso ~ # cave sync
(chroot) root@archiso ~ # cave resolve world -cx

 

5. Make it bootable

Create fstab:

(chroot) root@archiso /mnt # vim /etc/fstab
# <fs>                      <mountpoint>           <type> <opts> <dump/pass>

/dev/mapper/root             /                      btrfs defaults,noatime,discard,ssd,compress=zstd,subvol=@ 0 1
/dev/mapper/root             /home                  btrfs defaults,noatime,discard,ssd,compress=zstd,subvol=@home 0 1
/dev/mapper/root             /.snapshots            btrfs defaults,noatime,discard,ssd,compress=zstd,subvol=@snapshots 0 1

tmpfs                       /tmp                   tmpfs rw,nosuid,noatime,nodev,mode=1777 0 0

Create crypttab:

(chroot) root@archiso /mnt # blkid | grep nvme0n1p3
/dev/nvme0n1p3: UUID="5a1558cc-0d27-4795-a2bc-64ffdfc04f8b" TYPE="crypto_LUKS" PARTUUID="c6d92a71-284e-1d41-a5c0-748cf21e53b8"

(chroot) root@archiso /mnt # vim /etc/crypttab
root UUID=5a1558cc-0d27-4795-a2bc-64ffdfc04f8b none luks,cipher=aes-xts-plain64,discard

Rebuild systemd with efi and cryptsetup flag:

(chroot) root@archiso ~ # echo "sys-apps/systemd cryptsetup efi" >> /etc/paludis/options.conf
(chroot) root@archiso ~ # cave resolve -x sys-apps/systemd 

Install dracut, cryptsetup and btrfs-progs:

(chroot) root@archiso ~ # echo "sys-apps/coreutils xattr" >> /etc/paludis/options.conf
(chroot) root@archiso ~ # cave resolve -x dracut --take btrfs-progs 

Configure dracut:

(chroot) root@archiso ~ # echo "compress=\"xz\"" > /etc/dracut.conf.d/compress.conf

(chroot) root@archiso ~ # echo "force=\"yes\"" > /etc/dracut.conf.d/force.conf

(chroot) root@archiso ~ # echo "hostonly=\"yes\"" > /etc/dracut.conf.d/hostonly.conf
(chroot) root@archiso ~ # echo "hostonly_mode=\"strict\"" >> /etc/dracut.conf.d/hostonly.conf

(chroot) root@archiso ~ # echo "dracutmodules=\"base bash crypt dm btrfs dracut-systemd fs-lib i18n kernel-modules rootfs-block systemd systemd-initrd terminfo udev-rules usrmount\"" > /etc/dracut.conf.d/modules.conf

Configure console keymap:

(chroot) root@archiso ~ # echo KEYMAP=fr > /etc/vconsole.conf

Create kernel cmdline:

(chroot) root@archiso ~ # echo quiet > /etc/kernel/cmdline

Install systemd-boot:

(chroot) root@archiso ~ # mount -t efivarfs efivarfs /sys/firmware/efi/efivars
(chroot) root@archiso ~ # bootctl --make-machine-id-directory=yes --esp-path=/efi --boot-path=/boot install

Download and extract the latest stable kernel from The Linux Kernel Archives.

Go to the kernel folder:

(chroot) root@archiso ~ # mkdir /usr/src/kernel && cd $_

(chroot) root@archiso /usr/src/kernel # wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.4.tar.xz
(chroot) root@archiso /usr/src/kernel # tar -xf linux-5.10.4.tar.xz && cd linux-5.10.4

Configure kernel:

(chroot) root@archiso /usr/src/kernel/linux-5.10.4 # make nconfig

NVM Express block device:

Device Drivers  --->
  <*> NVM Express block device

Btrfs support:

File systems  --->
    <*> Btrfs filesystem

Device mapper and crypt target:

Device Drivers --->
    [*] Multiple devices driver support (RAID and LVM) --->
        <*>   Crypt target support

Framebuffer:

Device Drivers  --->  
    Graphics support  --->  
        Frame buffer Devices  --->  
	    <*> Support for frame buffer devices  --->
	        [*] EFI-based Framebuffer Support   

Cryptographic API functions:

[*] Cryptographic API --->
    <*> XTS support
    <*> User-space interface for hash algorithms
    <*> User-space interface for symmetric key cipher algorithms

Compression algorithm:

[*] Cryptographic API --->
    <*> LZO compression algorithm
    <*> LZ4 compression algorithm
    <*> LZ4HC compression algorithm
    <*> Zstd compression algorithm

Iwd:

Security Options --->
	[*] Enable access key retention support
		[*] Diffie-Hellman operations on retained keys

Cryptographic API  --->
	<*>   Triple DES EDE cipher algorithm (x86-64)
	<*>   ARC4 cipher algorithm

Build and install kernel/initramfs:

(chroot) root@archiso /usr/src/kernel/linux-5.3.11 # eclectic installkernel set -2
(chroot) root@archiso /usr/src/kernel/linux-5.3.11 # make -j$(nproc)
(chroot) root@archiso /usr/src/kernel/linux-5.3.11 # make modules_install
(chroot) root@archiso /usr/src/kernel/linux-5.3.11 # make install

 

5. Last step

Configure your hostname:

(chroot) root@archiso ~ # echo "laptop" > /etc/hostname

Configure hosts:

(chroot) root@archiso ~ # vim /etc/hosts
127.0.0.1        laptop.local laptop localhost
::1              laptop.local laptop localhost

Additional kernel support (e.g. for an Intel wireless card):

(chroot) root@archiso ~ # cave resolve repository/hardware -x
(chroot) root@archiso ~ # cave resolve -x linux-firmware

Locales / LANG / timezone:

(chroot) root@archiso ~ # localedef -i en_US -f ISO-8859-1 en_US
(chroot) root@archiso ~ # echo LANG="en_US.UTF-8" > /etc/env.d/99locale
(chroot) root@archiso ~ # ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime

Install iwd:

(chroot) root@archiso ~ # cave resolve -x iwd

Enable service:

(chroot) root@archiso ~ # systemctl enable getty@
(chroot) root@archiso ~ # systemctl enable iwd
(chroot) root@archiso ~ # systemctl enable dhcpcd

Set root password:

(chroot) root@archiso ~ # passwd

 

8. Reboot

🔪 + 🐐 + 🙏

@ldoguin
Copy link

ldoguin commented Jan 31, 2021

Add to do cave resolve repository/python -x before installing iwd.
All good otherwise thank you !

@lportemo
Copy link

lportemo commented Feb 8, 2021

Thanks :) very useful for beginners that cannot interpret paludis error messages (yet). I was stuck with an error during the install of dracut and your little guide helped a lot.

@aurrelhebert
Copy link

aurrelhebert commented Mar 9, 2021

Kernel config

To access locally to the config on exherbo, you can set:

General Setup  --->
    <*> Kernel .config support
        [*] Enable access to .config through /proc/config.gz

You will have access to your kernel setting in /proc/config.gz

I also activated:

[*] Cryptographic API --->
   <*> SHA384 and SHA512 digest algorithm

Troubleshooting

Reconnect in CHROOT

To validate or debug your installation, you can reconnect in CHROOT by:

root@archiso ~ # mount -o subvol=@ /dev/mapper/root /mnt
root@archiso ~ # mount -o subvol=@home /dev/mapper/root /mnt/home
root@archiso ~ # mount -o subvol=@snapshots /dev/mapper/root /mnt/.snapshots

Then replayed all commands of the step 3

Unavailable cave package

Whenever you encounter the error "item/package unavailable" with cave. This can be resovled with:

cave show package

Show package will print you a repository name where you can fin your package.
Add the repository with:

cave resolve -x1z repository/repo_name

Cannot proceed without: being reconfigured

If you encoutered the error: Cannot proceed without: being reconfiguredwhen building cave packages:

dev-lang/python:3.8:arbor ... 
You need to change: -sqlite -> sqlite No changes needed: .... 
Cannot proceed without: user configuration change

It means that currently sqlite is disbled for dev-lang/python:3.8, to activate simply edit /etc/paludis/options.conf by adding at the end of the file:

echo "dev-lang/python:3.8 sqlite" >> /etc/paludis/options.conf

This will activate sqlite for dev-lang/python:3.8.

Missing package option:

If you encoutered an error like:

dev-python/setuptools:2.7:arbor ... 
You need to change: PYTHON_ABIS -2.7 -> 2.7 No changes needed: .... 
Cannot proceed without: user configuration change

It means you need to set PYTHON_ABIS=2.7as a package paludis option (more information: https://paludis.exherbo.org/configuration/use.html):

echo "dev-python/setuptools:2.7 python_abis: 2.7" >> /etc/paludis/options.conf

Use kernel crypto for cryptsetup

When boot exherbo and trying to open the encrypted partition, a "crypt unknown target type" error occured.
To reslove it, edit /etc/paludis/options.conf:

vim /etc/paludis/options.conf 

And swith cryptsetup to kernel instead of openssl by adding:

sys-fs/cryptsetup -openssl kernel 

Recompile cryptsetup:

cave -resolve -x cryptsetup

Finally recompile your linux kernel to apply this change:

cd /usr/src/kernel/linux-X.Y.Z
make install

Activate wireless networking after reboot

First of all check that the service iwd is working on systemd:

systemctl status iwd

On my side I needed to activate one more kernel flag: CONFIG_CRYPTO_HMAC.
Once iwd is up an running, check if you have at least one internet device configured:

iwctl
[iwd]# device list

If device list isn't empty, you can directly follow iwd documentation to connect to a network.

In case it's empty, it means your wireless card is not ready to use. First find which card it is:

lspci -nn | grep Network

It will render something like:

Network controller []: .... Wireless ... [XXXX:YYYY]

Use https://linux-hardware.org/?view=search to find your card XXXX corresponds to vendor ID, and YYYY corresponds to device ID.
On linux-hardware you will find the kernel flag you need to activate for your device. Follow stricly https://wiki.gentoo.org/wiki/Iwlwifi#Kernel to correclty configure the kernel for iwlwifi:

cd /usr/src/kernel/linux-X.Y.Z
make nconfig
# Activate correctly all https://wiki.gentoo.org/wiki/Iwlwifi#Kernel kernel flag
make -j$(nproc)
make modules_install

Then don't forget to build the linux-firmware package:

cave resolve -x firmware/linux-firmware

Run kernel make install at the end to update the boot:

make install

You can now reboot and follow iwd documentation to connect to a network!

Once this is done, if you have trouble to resolve, ensure the network can resolve DNS:

# Test to resolve to google
ping google.com

# If ping is failing due to resolution, edit resolv configuration
vim /etc/resolv.conf

# Google DNS
# https://developers.google.com/speed/public-dns/docs/using
nameserver 8.8.8.8
nameserver 8.8.4.4

Install a GUI

To set up a GUI as KDE you can follow https://exherbo.org/docs/kde.html documentation:

cave resolve plasma

If you encounters errors as:

Found nothing suitable matching plasma ... kde/kdeplasma-addon, kde/plasma-applet, kde/plasme-desktop... 
or 
Name "plasma" is not a valid package name

You may miss the kderepository

cave resolve -x1z repository/kde

Retry plasma:

cave resolve plasma

Fix the errors, if you get:

Unsuitable candidate
   x11-dri/mesa 
      Flag wayland enabled
  ....

This means you need to activate the wayland flag for the x11-dri/mesa lib:

echo "x11-dri/mesa wayland" >> /etc/paludis/options.conf

If you get a second error message you need to be add the wayland flag to a second library:

echo "x11-libs/gtk+ wayland" >> /etc/paludis/options.conf

@aurrelhebert
Copy link

Window manager

To setup xinit as a first window manager, you need to install Xorg. You can find a documentation here. To complete this guide, check what driver is used by your graphic card:

lspci -nnk | grep -C 2 VGA

You will get you drive name with Kernel driver in use: kernel_driver.

Then edit your /etc/paludis/options.conffile:

echo "*/* kernel_driver" >> /etc/paludis/options.conf

# For an Intel card:
echo "*/* video_drivers: intel" >> /etc/paludis/options.conf

Install xorg-server as defined:

cave resolve -x x11-server/xorg-server

If you need additional x11-drivers e.g. for Intel:

cave search x11-drivers/xf86-video

# x11-drivers/xf86-video-intel
cave resolve -x x11-drivers/xf86-video-intel

Check if Xorg is correctly install:

ls /usr/bin/Xo*

If it's not the case, to resolve it, first reinstall x11-dri/mesa, dev-libs/libepoxy and dev-libs/libglvnd without X:

echo "x11-dri/mesa -X" >> /etc/paludis/options.conf
echo "dev-libs/libepoxy -X" >> /etc/paludis/options.conf
echo "dev-libs/libglvnd -X" >> /etc/paludis/options.conf
cave resolve -x x11-dri/mesa
cave resolve -x dev-libs/libepoxy
cave resolve -x dev-libs/libglvnd

Then update /etc/paludis/options.conf file, to reactivate X for all those three libraries. As in it's tests libglvnd include some call to X, activate the flag build_options: -recommended_tests for the dev-libs/libglvnd library:

vim /etc/paludis/options.conf

Which gives:

x11-dri/mesa X 
dev-libs/libepoxy X
dev-libs/libglvnd X build_options: -recommended_tests

Rebuild all library with X and Xorg:

cave resolve -x x11-dri/mesa
cave resolve -x dev-libs/libepoxy
cave resolve -x dev-libs/libglvnd
cave resolve -x x11-server/xorg-server

Then install xinit and xterm:

cave resolve -x xinit --suggestions take 
cave resolve -x xterm

Copy the xinitrc file in a normal user home:

cp /etc/X11/xinit/xinitrc ~/.xinitrc

Use the startx command to start the window manager:

#run as normal user
startx

@toastal
Copy link

toastal commented Mar 18, 2023

This would be a lot easier to read if you changed your syntax highlighting from sh or shell to sh-session as much of this isn't scripts, but the shell session.

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