Sergibarroso Gentoo Install Save

This file is a step by step how to install Gentoo guide. With systemd, uefi, luks and much more.... Thanks for reading :)

Project README

Gentoo install guide

gentoo_logo

Introduction

Gentoo is a Linux distribution that, unlike binary distros like Arch, Debian, and many others, the software is compiled locally according to the user preferences and optimizations.

The name Gentoo comes from the penguin species, which are known to be the fastest in the world.

I've been using Gentoo since 2002 (20+ years already :astonished: ), and what I like most about Gentoo is:

  • Is fun
  • The possibility of getting everything under control
  • Deep customization One learns a lot about GNU/Linux from using it.

Disclaimer: Gentoo is the perfect distribution to use the quote from an ancient adage that says: With great power comes great responsibility. Remember that although Gentoo gives you a lot of flexibility and customization, it also requires time, dedication, and patience.

If you are that kind of person, speak emerge and enter :sunrise:

:warning: Disclaimer
This guide is intended to be a learning experience, and I will try to explain all steps to give you an understanding of what we're doing and why.

Installation concerns

Stop before further reading. It's important to know that this guide only contemplates an installation with UEFI, crypt/luks disk, lvm partitioning, and systemd init system. Please remember that if you want a different setup, don't take this guide step-by-step but as a general guideline.

Start live-cd environment

The first thing we need to install our Gentoo is a live-cd environment with UEFI vars enabled.

I like systemrescuecd because is Gentoo-based and has UEFI vars enabled. You can download it here bootable usb.

As systemrescuecd is now based on Arch, we will use the Gentoo LiveGUI USB Image. You can find it in the Gentoo downloads section. Scroll to Advanced choices and other architectures and get the Boot media called LiveGUI USB Image.

To make sure that we boot on UEFI mode, by running:

efivar -l

If the command listed the UEFI variables, we're good to go :checkered_flag:

Prepare Hard disk

I suggest you use whatever you're familiar with, I will show you the process using gdisk, but others like cgdisk or parted will do the job.

:information_source: Info point
Once you run the first gdisk command, you will enter the gdisk console.

If you use SATA disk, run:

gdisk /dev/sda

I will continue using NVME, but if you use a SATA disk, from now on, replace everything appearance of /dev/nvme0n1 or /dev/nvme0n1p1, for /dev/sda or dev/sda1 :thumbsup:

If you use NVME disk, then run:

gdisk /dev/nvme0n1

Create a new GUID partition table and destroy everything on the disk:

o (Create a new empty GUID partition table (GPT))
Proceed? Y

Now that we've got the disk wiped, we'll create some new partitions. The standard partition schema would be a partition for EFI, a partition for SWAP, and one or more for the system. I'm not going to create a partition for SWAP because I have enough RAM to handle the system's load, but feel free to make one for your needs.

n (Add a new partition)
Partition number 1
First sector 2048 (default)
Last sector +512M
Hex code EF00

n (Add a new partition)
Partition number 2
First sector 1050624 (default)
Last sector (press Enter to use remaining disk)
Hex code 8E00

Now, apply the changes to the disk and quit:

w
Y

Partitions should look something like this:

gdisk -l /dev/sda
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   EF00  EFI
   2         1050624       500118158   238.0 GiB   8300  LVM

Or, in the case of NVME:

gdisk -l /dev/nvme0n1
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048         1050623   512.0 MiB   EF00  EFI
   2         1050624       500118158   238.0 GiB   8300  LVM

Prepare encrypted container

At this point, we have the disk partitioned. Next, we want to create an encrypted container that will hold the LVM volumes.

To get the best performance of working with encrypted containers, we should use an encryption algorithm supported by our CPU. We have to be wise in picking up because we won't be able to change it afterward. Luckily for us, cryptosetup is here :ok_hand:

Run:

cryptsetup benchmark

You should see something like this:

# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1      3355443 iterations per second for 256-bit key
PBKDF2-sha256    5447148 iterations per second for 256-bit key
PBKDF2-sha512    2068197 iterations per second for 256-bit key
PBKDF2-ripemd160 1182160 iterations per second for 256-bit key
PBKDF2-whirlpool  784862 iterations per second for 256-bit key
argon2i      10 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id     10 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
#     Algorithm |       Key |      Encryption |      Decryption
        aes-cbc        128b      1876.9 MiB/s      7495.4 MiB/s
    serpent-cbc        128b       113.2 MiB/s       816.2 MiB/s
    twofish-cbc        128b       283.5 MiB/s       516.3 MiB/s
        aes-cbc        256b      1431.1 MiB/s      5949.0 MiB/s
    serpent-cbc        256b       114.3 MiB/s       816.3 MiB/s
    twofish-cbc        256b       284.0 MiB/s       516.4 MiB/s
        aes-xts        256b      6022.2 MiB/s      6000.8 MiB/s
    serpent-xts        256b       767.7 MiB/s       728.6 MiB/s
    twofish-xts        256b       475.3 MiB/s       481.8 MiB/s
        aes-xts        512b      5261.2 MiB/s      5233.4 MiB/s
    serpent-xts        512b       776.3 MiB/s       729.4 MiB/s
    twofish-xts        512b       477.6 MiB/s       480.9 MiB/s

Choose the option with better overall performance. For example, in the output above would be aes-xts and the key size PBKDF2-sha256.

When you have yours chosen, then proceed by running:

cryptsetup -v --cipher aes-xts-plain64 --key-size 256 -y luksFormat /dev/nvme0n1p2

The command will ask you to confirm with a YES. After a second, you should see something like Command successful.

Then we need to open (decrypt) the container to start creating the volumes inside.

When we open the container, we need to specify a label name to identify the container once opened. As you can see, in the command below, I've used cryptcontainer, be creative :stuck_out_tongue_winking_eye:

cryptsetup open --type luks /dev/nvme0n1p2 cryptcontainer

And... we're done with the encryption. Now, volume time! :sound:

Create LVM volumes

:information_source: Info point
For those of you that are not familiar with this acronym, LVM stands for Logical Volume Management. You can read more about it here.

The good thing about logical volumes is that you can modify them at any point. In this example, I'm going to create two logical volumes, one for the root partition and one for the home, but feel free to create as many as you want.

Also, I'll use the name vg0 to identify this volume group. This is a trivial name, so again, be creative :D

pvcreate /dev/mapper/cryptcontainer
vgcreate vg0 /dev/mapper/cryptcontainer

If running the previous commands, you see some warnings like:

WARNING: Failed to connect to lvmetad. Falling back to device scanning.

It's fine as long as you see a Physical volume "/dev/mapper/cryptcontainer" successfully created. following.

At this point, let's check that what we have is what we want:

vgdisplay

You should see something like:

  --- Volume group ---
  VG Name               vg0
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               63.48 GiB
  PE Size               4.00 MiB
  Total PE              16251
  Alloc PE / Size       0 / 0
  Free  PE / Size       16251 / 63.48 GiB
  VG UUID               uQEI07-lgcP-hQ6j-jTR8-BhsO-AsTA-IlLMwC

If what you see makes sense, let's create the volumes:

lvcreate --size 50G vg0 --name root
lvcreate --extent 100%FREE vg0 --name home

To double-check what we've done, run:

lvdisplay

You should see something like:

  --- Logical volume ---
  LV Path                /dev/vg0/root
  LV Name                root
  VG Name                vg0
  LV UUID                ggiZPZ-ygBQ-0fxR-oiXN-qLjC-KDOm-phY1ip
  LV Write Access        read/write
  LV Creation host, time livecd, 2022-08-26 09:35:21 +0000
  LV Status              available
  # open                 0
  LV Size                50.00 GiB
  Current LE             12800
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0

  --- Logical volume ---
  LV Path                /dev/vg0/home
  LV Name                home
  VG Name                vg0
  LV UUID                PZwAiM-kbw5-Cq1y-63xY-nApf-VEms-t31rJI
  LV Write Access        read/write
  LV Creation host, time livecd, 2022-08-26 09:35:32 +0000
  LV Status              available
  # open                 0
  LV Size                1.77 TiB
  Current LE             464003
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1

If you do, well done :muscle: Let's keep rolling!

Create filesystems

The good thing about Linux is that we have a lot of filesystems that we can use, but this is also the wrong thing :sweat_smile: "what to choose" and "when" will most probably come to your mind at some point.

You can read as much as you want here, but we'll keep it easy. We will use ext4, the default filesystem for many Linux distributions.

Let's create our three main filesystems volumes, one FAT32 for UEFI (:fearful: yes, I know, but this is how UEFI works), and then our main ext4 filesystems. If you've created more volumes, remember to make a filesystem for all of them:

mkfs.vfat -F32 /dev/nvme0n1p1
mkfs.ext4 /dev/mapper/vg0-root
mkfs.ext4 /dev/mapper/vg0-home

Mount the new filesystems

With our logical volumes created and our filesystems ready, let's mount our partitions to start building our Gentoo system:

mkdir -p /mnt/gentoo
mount /dev/mapper/vg0-root /mnt/gentoo
mkdir -p /mnt/gentoo/boot
mount /dev/nvme0n1p1 /mnt/gentoo/boot
mkdir /mnt/gentoo/home
mount /dev/mapper/vg0-home /mnt/gentoo/home

Installing the Gentoo base system

Before installing Gentoo, ensure the date and time are set correctly. A misconfigured clock may lead to strange results in the future, and you don't want this :)

To check our current system date just run:

date

Select the timezone:

tzselect

Then use NTP to set sync the time and date:

ntpdate pool.ntp.org

Install the stage3 tarball

To avoid installing Linux from scratch, the awesome Gentoo developers provide a Stage 3 build, mainly a base-binary-semi-working-non-bootable-environment (no joke :satisfied: ) created to save us tons of time.

We're going to grab that base-binary-semi-working-non-bootable-environment, untar it into our Gentoo directory structure. This will create all the necessary binaries and files to start compiling our Gentoo system.

We first download the tarball:

curl -o /mnt/gentoo/stage3-amd64-systemd.tar.xz -L https://bouncer.gentoo.org/fetch/root/all/releases/amd64/autobuilds/20230307T201702Z/stage3-amd64-systemd-20230307T201702Z.tar.xz

And we unpack it in our root directory that is mounted in /mnt/gentoo directory:

cd /mnt/gentoo/
tar xvf stage3-*.tar.xz --xattrs

At this point, we have all files to start setting up our new Gentoo environment.

Now is when our CPU starts panicking :worried:

Configuring compile options

I would like to introduce you to Portage, Gentoo's cornerstone.

For those who don't know (yet), Portage is Gentoo's auto-build system and package management tool. It will grab the source code of anything we want to install (defined in the ebuild file), compile it (based on CPU architecture Flags and which features are available for every package with what are known as "use flags"), and install it in our system. There's also the option to download pre-compiled packages, but I like to make my CPU work hard :D

This might be intimidating for some of you, but no worries, we will take it step by step.

And the firsts are the CPU flags. The CPU flags tell the compiler the options natively supported for our CPU. This translates to our CPU, and not any other will compile the system binaries.

The easiest way is to go to the Gentoo wiki here and check the best COMMON_FLAGS to use for your CPU, but if you're interested, you can also do it manually by:

Running:

gcc -c -Q -march=native --help=target | awk '/^  -march=/ {print $2}'

You should see one word, in my case, was tigerlake. So basically, this is the best CPU flag for my CPU type.

Before setting it, it's worth double checking the value with what is defined in the Gentoo wiki, just in case :)

Now, edit this file:

nano -w /mnt/gentoo/etc/portage/make.conf

And set the -march=tigerlake (or the type you got) at the beginning of COMMON_FLAGS to something like:

COMMON_FLAGS="-march=tigerlake -O2 -pipe"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"

Now we're going to set up MAKEOPTS. MAKEOPTS describes the number of parallel jobs used by Portage.

There's always been some discussion on what to set here, but I'm going to follow what the Gentoo wiki recommends here, which is: less than or equal to the minimum of the size of RAM/2GB or CPU thread count.

We will use the number of CPU threads by running:

lscpu | awk '/^CPU\(s\):/ {print $2}'

Additionally, to keep the system responsive when compiling, the build system supports limiting the maximum load for compilation with the parameter --load-average.

With all that we've said in this section, let's edit the make.conf file again:

nano /mnt/gentoo/etc/portage/make.conf

And this time, we set MAKEOPTS:

MAKEOPTS="--jobs 8 --load-average 9"

Selecting mirrors

Gentoo uses the closes mirror to sync the packages index, so setting the best mirrors for your location is essential. Luckily the tool mirrorselect is going to do the hard work for us :D

:warning: Make sure that you have Internet access from your live-cd:

mirrorselect -D -s4 -o >> /mnt/gentoo/etc/portage/make.conf

You should now have an entry for GENTOO_MIRRORS in /mnt/gentoo/etc/portage/make.conf.

Configuring the main Gentoo repository

Copy the Gentoo repository configuration file from Portage package:

mkdir -p /mnt/gentoo/etc/portage/repos.conf
cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf

Copy DNS info

Copy the DNS information from your working live-cd environment into the new system to make sure that we will be able to resolve domain names once we switch to it:

cp --dereference /etc/resolv.conf /mnt/gentoo/etc/

Mounting the necessary filesystems

In addition to the LVM filesystem we created in our local disk, other pseudo-filesystems are created during system boot that is needed to chroot into our new environment:

:warning: If you are setting an environment without SystemD, then you can skip the --make-rslave lines

mount --types proc /proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --make-rslave /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --make-rslave /mnt/gentoo/dev
mount --bind /run /mnt/gentoo/run
mount --make-slave /mnt/gentoo/run

Entering the new environment

Chroot into the new environment:

chroot /mnt/gentoo /bin/bash
source /etc/profile
export PS1="(chroot) $PS1"

Great! We are inside our Gentoo system :tada: Unfortunately, it still needs a little bit more time baking :cake:

Please take a deep breath, and let's keep rolling.

Configuring Portage

Portage does the heavy lifting of repository and package management. Everything from dependency resolution, building source code, and installing the software on our system is done by Portage, using some of the tools that it provides, such as emerge.

First, we need to synchronize the remote repositories with the local Portage tree to know what packages are available to be installed.

Updating the Portage tree

Then update the snapshot with the latest version of the repository:

emerge --sync

Choosing the right profile

A Portage profile specifies default values for global and per-package USE flags, specifies default values for most variables found in /etc/portage/make.conf, and defines a set of system packages. The Gentoo developers maintain the profiles as part of the Portage tree.

List the available profiles:

eselect profile list

From the output list, we must select our best fitting option. Because the system we're building is based on SystemD, the best profile we can choose is the systemd. Of course, we can choose any other that has systemd in it, like default/linux/amd64/17.0/desktop/gnome/systemd, but we want a minimal environment to be configured.

[..]
[17]  default/linux/amd64/17.1/systemd (stable) *
[..]

This should be the default profile selected, as we can tell for the * at the end. But if not, make sure you choose it with eselect:

eselect profile set 17 # or the number that you have on your list

Configuring the USE variable

As we said, USE flags are a core feature of Gentoo. Therefore, a good understanding of how to deal with them is needed to have a customized and healthy Gentoo system.

The USE variables can be defined system-wide or per package domain. You can read more info here:

We can see the list of USE flags that are set up in our system by running:

emerge --info | grep ^USE

Don't get scared by the list. You will most probably increase this once we finish with this section.

We can find a description of all USE flags in less /var/db/repos/gentoo/profiles/use.desc.

Additionally, the utility named quse from portage-utils package can tell us which package uses what USE flags.

For example, if you want to know which packages use the systemd flag we simply need to run:

quse systemd

And you will have the list of packages affected by systemd.

:hand: Reminder
At this point is normal if you feel overwhelmed. Setting and choosing the proper USE flags before installing anything in our system will save us time later. It's crucial to remember that USE flags we use can always be changed, and if we choose something that we don't want to use anymore or we made a mistake, we can always change them and re-compile the affected packages. So, relax :relaxed:

Said that we're going to use a tool called ufed that will help use-setting the USE flags that we want in any domain.

emerge app-portage/eix app-portage/ufed

And then, run it to select the USE flags with a beautiful user interface :smile: This step will take some time, so let's grab a :tea: or :coffee: and let's do it!

ufed
:warning: Required USE flags
To make sure that our setup will work as expected, we need at least these USE flags set cryptsetup, lvm, and lvm2create-initrd

Once we're done, we can see how many system-wide USE flags we've defined by looking at the /etc/portage/make.conf file:

nano -w /etc/portage/make.conf
:warning: Don't use this as an example
These are the USE flags for my test system, don't use them for yours
USE="10bit 12bit 256-color 7zip a-like-o aac aacs aalib acpi aio
     bash-completion boost branding caps contrib cpu cpudetection cpuid
     cpuinfo cpuload cryptsetup dbus efi64 gd gzip hardened hddtemp highlight
     highlighting imagemagick initramfs int64 ipv4 jemalloc jpeg json
     kmod lm-sensors lvm lvm2create-initrd lz4 lzip lzma lzo lzo2 nano
     nano-syntax networkmanager nss numa opencl opengl openssl python ssh
     sslv2 sslv3 startup-notification tcmalloc threaded threads thunderbolt
     truetype udisks uefi unzip upower usb x264 x265 xfs xv zeroconf
     zsh-completion -cups"

Configuring the CPU Flags

USE flags that are available for our system. We could use the advantages of some CPU instruction sets using what are called CPU flags. You can read more on the Gentoo wiki page.

To know what optimizations we can use for our CPU, we're going to use a tool called cpuid2cpuflags:

emerge --ask app-portage/cpuid2cpuflags

And then run it to get those values:

cpuid2cpuflags

You should see an output like:

CPU_FLAGS_X86: aes avx avx2 avx512f avx512dq avx512cd avx512bw avx512vl avx512vbmi f16c fma3 mmx mmxext pclmul popcnt rdrand sha sse sse2 sse3 sse4_1 sse4_2 ssse3

We have to add this into our /etc/portage/make.conf, but instead of colon (:), we will use this format. CPU flags could be added to /etc/portage/package.use/ instead (with another format), but we will use our beloved :heart: make.conf :

nano /etc/portage/make.conf

And we add our CPU_FLAGS_X86 somewhere in the file.

CPU_FLAGS_X86="aes avx avx2 avx512f avx512dq avx512cd avx512bw avx512vl avx512vbmi f16c fma3 mmx mmxext pclmul popcnt rdrand sha sse sse2 sse3 sse4_1 sse4_2 ssse3"

Re-compile and update @world

After setting up the USE and CPU flags, we're ready to re-compile and update all packages that we have installed in our base system before moving forward:

emerge --ask --verbose --update --deep --newuse @world

Configuring the base system

In addition to Portage, some other options should be configured before we can take our Gentoo out of the oven :pizza:

Allow licenses for packages

Each package in our Gentoo system defines what kind of license it uses. Setting what licenses we accept in our system is crucial to avoid problems installing free or binary redistributable packages. Also, to get installed automatically without asking us every time they get installed or updated.

You can read more about Gentoo licenses here.

Licenses acceptance is set in our /etc/portage/make.conf in the variable ACCEPT_LICENSE, like:

ACCEPT_LICENSE="-* @FREE @BINARY-REDISTRIBUTABLE"

Timezone

Set our time zone. We can use the tool tzselect to interactively select our country, and it will tell us what the value of /etc/timezone file should be.

tzselect

Take the last line from the output and add it to the timezone file like:

ln -sf /usr/share/zoneinfo/Europe/Berlin /etc/localtime

Configure locales

Locales are a set of information that most programs use to determine the country and language of your system. Most users would use one or a few locales instead of all. This could save us compiling time, to avoid compiling all languages available for each package, and space on the filesystem by not installing man pages that we can't understand :)

Edit the /etc/locale.gen and uncomment the locale you are interested. Make sure you prioritize UTF-8 locales because at least one is needed for the build system to work correctly.

nano -w /etc/locale.gen

Now, execute locale-gen to generate all locales specified in the previous file, and write them to the locale-archive /usr/lib/locale/locale-archive.

locale-gen

The more locales you select, the slower this process will be.

To check if the locales you've selected are active, run the following command and see if they are on the list. No worries if there're some locales you didn't choose, that's part of the system.

locale -a

Once the locale is available, let's ensure that it is the default one used in our system. Again we use eselect for this, now with the locale module:

eselect locale list

You should see something like:

Available targets for the LANG variable:
  [1]   C
  [2]   C.utf8
  [3]   POSIX
  [4]   en_US.utf8
  [5]   C.UTF8 *
  [ ]   (free form)

Pick what locale you would activate and then run the following command with the number that you want to select:

eselect locale set 4

Now reload the environment:

env-update && source /etc/profile && export PS1="(chroot) $PS1"

Configuring Linux kernel

While Portage is the core of Gentoo Linux system, the Linux kernel is the operating system's core. Therefore, this last offers an interface for programs to access the hardware via the modules, aka drivers.

The first step is installing the kernel source code. Gentoo's recommendation is, of course, the kernel package called sys-kernel/gentoo-sources. It is maintained by the Gentoo team and patched to fix security vulnerabilities and functionality problems and improve compatibility with rare system architectures. But, as always, there're many other options available.

To get a complete list of kernel sources with short descriptions can be found by searching with emerge:

emerge --search sources

Installing external firmware

Linux kernel is an open-source project, but some hardware manufacturers don't like the idea of open-source the code of its firmware (or modules), releasing a compiled binary version of them. These binaries can't be included in the Linux kernel repository, and they are packed in a package called sys-kernel/linux-firmware.

So, before compiling the kernel, it is essential to know that some devices require additional firmware to make the system run properly. Second, these are more common than we think, from network adapters, wireless cards, graphic cards, and CPUs.

For the most common firmware requirements, we will install the sys-kernel/linux-firmware:

emerge --ask sys-kernel/linux-firmware

Additionally, check the Microocode page in the Gentoo wiki to see if you need any additional firmware to make your CPU work properly. For example, intel CPUs are usually required to install the Intel microcode package sys-firmware/intel-microcode.

Installing the sources

We're not going to get "too crazy" and install Zen kernel (my favorite). Instead, we will install the default Gentoo kernel:

emerge --ask sys-kernel/gentoo-sources

Once installed, we have to select what kernel we want our system to use by using our magic wand eselect :zap:

eselect kernel list

You will probably see only one kernel on the list:

Available kernel symlink targets:
  [1]   linux-5.15.59-gentoo

So we go with that:

eselect kernel set 1

What this actually does is create a symlink /usr/src/linux to point to /usr/src/linux-5.15.59-gentoo

From this point, only two things are missing: configure and compile it. There are two ways to do that:

  1. Manual configuration and automated build
  2. Semi-automated by using genkernel
  3. Fully automated via distribution kernels (not covered in this guide. Follow the official documentation here)
Manual set up

The manual process it's intimidating for beginners because you can break your system if you miss specific options. In addition, the process involves a lot of reading and digging.

As much as I would love to spend time explaining every single option of the kernel, doing so will be time-consuming and at least double the size of this guide :bangbang:

So, if you feel brave, I will give you some hints:

  1. Install sys-apps/pciutils. This package contains a tool called lspci that you will use to identify what PCI hardware you have in your system. You will have to enable all drivers on the kernel.

    emerge --ask sys-apps/pciutils
    
  2. Configure the kernel by running make menuconfig inside /usr/src/linux:

    cd /usr/src/linux
    make menuconfig
    
  3. After the required options are activated either as a module or part of the kernel binary, compile the kernel and the modules, and install them by:

    make && make modules_install
    make install
    
  4. Install sys-kernel/dracut. This package will help you create an initrmfs (Init Ram Filesystem) with the required tools to make the kernel bootable:

    emerge --ask sys-kernel/dracut
    
  5. Run dracut to generate an initramfs for our kernel version:

    dracut --kver=5.15.59-gentoo
    
Semi-automatic set up using genkernel

For those who prefer a more pleasant initial experience, I'll explain how to use genkernel.

What genkernel really does is configure a generic kernel that works with most of the hardware. Like the LiveCD that we're using does.

  1. Install genkernel:

    emerge --ask sys-kernel/genkernel
    
  2. Genkernel needs the /boot entry in the /etc/fstab file. So go to the fstab section now and continue with point 2 when you're done.

  3. Edit /etc/genkernel.conf:

    nano -w /etc/genkernel.conf
    

    Ensure that LVM and LUKS are set to yes; otherwise, the system will not boot. Leave the rest of the options as they are:

    # Add LVM support
    LVM="yes"
    
    # Add LUKS support
    LUKS="yes"
    
  4. Once genkernel is configured, then run to generate the kernel binary:

    genkernel all
    

Configuring the modules

If we need to auto-load a kernel module each time to system boots, we should specify it in /etc/conf.d/modules file.

You can list your available modules with:

find /lib/modules/<kernel version>/ -type f -iname '*.o' -or -iname '*.ko' | less

LVM Configuration

Install lvm2 tools if it is not yet installed:

emerge --ask sys-fs/lvm2

Then edit the package configurations:

nano -w /etc/lvm/lvm.conf
use_lvmetad = 1
issue_discards = 1
volume_list = ["vg0"] # Our VG volume name, check with vgdisplay

Fstab

Before editing fstab we need to know which UUID are using our devices inside and outside lvm and luks volumes:

blkid /dev/mapper/vg0-root | awk '{print $2}' | sed 's/"//g'
UUID="576e229c-cf68-4010-8d85-ff8149158416"
blkid /dev/mapper/vg0-home | awk '{print $2}' | sed 's/"//g'
UUID="95fa5807-ea57-4cf5-b717-74f4aba190e2"

Then edit /etc/fstab:

nano -w /etc/fstab
/dev/sda1                                       /boot   vfat    noatime                                         1 2
UUID="576e229c-cf68-4010-8d85-ff8149158416"     /       ext4    discard,noatime,commit=600,errors=remount-ro    0 1
UUID="95fa5807-ea57-4cf5-b717-74f4aba190e2"     /home   ext4    discard,noatime,commit=600                      0 0
tmpfs                                           /var/tmp tmpfs  nodev,nosuid                    0 0
tmpfs                                           /tmp    tmpfs   nodev,nosuid                    0 0

Configuring crypttab

Warning!!! As we don't have encrypted partitions other than root, which the systemd must mount before the whole system start, we don't need to set it up there, so our crypttab must be empty.

Configuring mtab

In the past, some utilities wrote information (like mount options) into /etc/mtab; thus, it was supposed to be a regular file. Nowadays all software is supposed to avoid this problem. Still, before switching the file to become a symbolic link to /proc/self/mounts.

To create the symlink, run:

ln -sf /proc/self/mounts /etc/mtab

Systemd boot (bootloader)

Systemd-boot is a simple UEFI boot manager which executes configured EFI images. The default entry is selected by an on-screen menu.

It is simple to configure, but can only start EFI executables, such as the Linux kernel EFISTUB, UEFI Shell, GRUB, and go on.

Before installing the EFI binaries we need to check if EFI variables are accessible:

emerge --ask sys-libs/efivar
efivar -l

Verify that you have mounted /boot:

mount | grep boot

Once got it mounted then install the systemd-boot binaries:

bootctl --path=/boot install

This command will copy the systemd-boot binary to your EFI System Partition ($esp/EFI/systemd/systemd-bootx64.efi and $esp/EFI/Boot/BOOTX64.EFI - both of which are identical - on x64 systems) and add systemd-boot itself as the default EFI application (default boot entry) loaded by the EFI Boot Manager.

Every time there's a new version of the systemd you should copy the new binaries to that System Partition by running:

bootctl --path=/boot update

Add bootloader entries

Add one entry into bootloader with this options:

nano -w /boot/loader/entries/gentoo.conf
title    Gentoo Linux
efi      /kernel-genkernel-x86_64-4.4.6-gentoo
options  initrd=/initramfs-genkernel-x86_64-4.4.6-gentoo crypt_root=/dev/sda2 root=/dev/mapper/vg0-root root_trim=yes init=/usr/lib/systemd/systemd ro dolvm

Edit default loader:

nano -w /boot/loader/loader.conf
default gentoo
timeout 3

Efibootmgr

Efibootmgr is not a bootloader itself it's a tool that interacts with the EFI firmware of the system, which itself is acting as a boot loader. With the efibootmgr application, boot entries can be created, reshuffled and updated.

First we need to install the package:

emerge --ask sys-boot/efibootmgr

To list the current boot entries:

efibootmgr -v
BootCurrent: 0003
Timeout: 1 seconds
BootOrder: 0003
Boot0000* Linux Boot Manager  HD(1,GPT,3eb8effe-8e1d-4670-987c-9b49b5f605b2,0x800,0x1ff801)/File(\EFI\systemd\systemd-bootx64.efi)
Boot0001* gentoo  HD(1,GPT,02f231b8-8f9a-471c-b3a9-dc7edb1bd70e,0x800,0xee000)/File(\EFI\gentoo\grubx64.efi)
Boot0003* Gentoo Linux  PciRoot(0x0)/Pci(0x1f,0x2)/Sata(2,32768,0)/HD(1,GPT,73f682fe-e07b-4870-be82-d85077f8aaa2,0x800,0x100000)/File(\EFI\systemd\systemd-bootx64.efi)

I'm only Gentoo in my system so I don't really need anything but the Gentoo entry so I just delete everything with:

efibootmgr -b <entry_id> -B

Once everything is delete we can add our new systemd-boot loader entry:

efibootmgr -c -d /dev/sda -p 2 -L "Gentoo" -l "\efi\boot\bootx64.efi"

Perfect, we're almost ready to reboot.

Rebooting into our new Gentoo systemd

Enable lvm2

systemctl enable lvm2-lvmetad.service

Change the root password

While in chroot we need to change the root password of our new system just before rebooting it.

passwd

And reboot to your new Gentoo system

Don't worry you don't need to cross your fingers, everything should goes fine :smirk:

exit # To exit from chroot
sync # To sync filesystems
reboot

Post-installation

Setting the Hostname

When booted using systemd, a tool called hostnamectl exists for editing /etc/hostname and /etc/machine-info. So we don't need to edit the file manually simlpy run:

hostnamectl set-hostname <hostname>

Configuring Network

Let's plug our new Gentoo system to the world!! :earth_africa:

We can choose between two options, to use systemd as network manager or standalone one, I prefer networkmanager but here are the two options:

Using systemd-networkd

systemd-networkd is useful for simple configuration of wired network interfaces. As it's disabled by default we need to configure it by creating a *.network file under /etc/systemd/network.

Here is an example for a simple ethernet DHCP configuration:

nano -w /etc/systemd/network/50-dhcp.network
[Match]
Name=en*
[Network]
DHCP=yes

And then tell systemd to manage and start that service:

systemctl enable systemd-networkd.service
systemctl start systemd-networkd.service

Using NetworkManager

Often NetworkManager is used to configure network settings. I personally use nmtui because it's easy and has a ncurses client. Just install it:

emerge --ask networkmanager

And now simply run the following command and follow a guided configuration process through nmtui:

nmtui

Setting locales

Yes, you're right, we set the locales before but once booted with systemd, the tool localectl is used to set locale and console or X11 keymaps. So, let's set it again to be sure that everything goes fine.

To change the system locale, run the following command:

localectl set-locale LANG=en_US.utf8

Change the virtual console keymap:

localectl set-keymap es

And finally, to set the X11 layout:

localectl set-x11-keymap es

Setting time and date

Time and date can be set using the timedatectl utility. That will also allow users to set up synchronization without needing to rely on net-misc/ntp or other providers than systemd's own implementation.

To set the local time of the system clock directly:

timedatectl set-time "yyyy-MM-dd hh:mm:ss"

To set time zone:

timedatectl list-timezones
timedatectl set-timezone Europe/Madrid

Set systemd-timesyncd as a simple SNTP daemon. Systemd-timesyncd that only implements a client side, focusing only on querying time from one remote server. It should be more than appropriate for most installations.

timedatectl set-ntp true

To check the status of the daemon:

timedatectl status

When starting, systemd-timesyncd will read the configuration file from /etc/systemd/timesyncd.conf. To add time servers or change the provided ones, uncomment the relevant line and list their host name or IP separated by a space. I'm using the NTP pool project for the main servers and the default Gentoo as fallback:

nano -w /etc/systemd/timesyncd.conf
[Time]
NTP=0.europe.pool.ntp.org 1.europe.pool.ntp.org 2.europe.pool.ntp.org 3.europe.pool.ntp.org
FallbackNTP=0.gentoo.pool.ntp.org 1.gentoo.pool.ntp.org 2.gentoo.pool.ntp.org 3.gentoo.pool.ntp.org

File indexing

In order to index the file system to provide faster file location capabilities we will install sys-apps/mlocate:

emerge --ask sys-apps/mlocate

To keep databse update we need to run updatedb often.

Filesystem tools

Additional to the tools for managing ext2, ext3, or ext4 filesystems (sys-fs/e2fsprogs) which are already installed as a part of the @system set I like to install other filesystem utilities like VFAT, XFS, NTFS and so on:

emerge --ask sys-fs/xfsprogs sys-fs/exfat-utils sys-fs/dosfstools sys-fs/ntfs3g

Adding a user for daily use

Until now we have done everything as root but working as root on a Unix/Linux system is dangerous and should be avoided as much as possible. Therefore it is strongly recommended to add a user for day-to-day use.

The groups the user is member of define what activities the user can perform. The following table lists a number of important groups:

Group Description
audio Be able to access the audio devices.
games Be able to play games.
portage Be able to access portage restricted resources.
usb Be able to access USB devices.
video Be able to access video capturing hardware and doing hardware acceleration.
wheel Be able to use su.

Once you selected which groups would you like to add simply run:

useradd -m -G users,wheel,audio,video,audio,usb -s /bin/bash <username>

To set the user password run:

passwd <username>

Exec as root with sudo

Sudo is a way that a regular user could run commands as root user. It's very useful to avoid using root password each time we need to run a command which needs root perms. To install run:

emerge --ask app-admin/sudo

Then edit config file with command:

visudo

There's lot of examples inside the config file so we should not have any problem to set it up.

Removing installation tarballs

With the Gentoo installation finished and the system rebooted, if everything has gone well, we can now remove the downloaded stage3 tarball from the hard disk. Remember that they were downloaded to the / directory.

rm /stage3-*.tar.bz2*

Power consumption optimization with Powertop

emerge --ask sys-power/powertop

The first step we need to do is to calibrate it, it's quite long process but the most important is to keep our system until the whole process is finished.

powertop --calibrate

To apply automatically optimal settings at boot we need to create a new Systemd unit:

nano -w /etc/systemd/system/powertop.service
[Unit]
Description=Powertop tunings

[Service]
Type=oneshot
ExecStart=/usr/sbin/powertop --auto-tune

[Install]
WantedBy=multi-user.target

Enable at each boot:

systemctl enable powertop.service

GPU

Prior to install xorg we will configure our video card, mine is Intel Generation 6 so we need to add this line into make.conf:

nano -w /etc/portage/make.conf
VIDEO_CARDS="intel i965"

Before installing xorg we need to configure it again by adding custom graphic card information:

nano -w /etc/X11/xorg.conf.d/20-intel.conf
Section "Device"
   Identifier  "Intel Graphics"
   Driver      "intel"
  Option      "AccelMethod"  "sna"
  Option      "DRI"          "3"
  Option      "Backlight"    "intel_backlight"
EndSection

Input devices

We need to do the same with the input devices. I'm using a laptop so check if you need to add joystick, mouse, keyboard, ... :wink:

nano -w /etc/portage/make.conf
INPUT_DEVICES="evdev synaptics

X server

At the time to write this guide wayland is available but I'ld like to use bspwm which only support xorg so I'll continue with xorg server installation and configuration:

emerge --ask xorg-server

A bunch of useful stuff

emerge --ask app-admin/ccze app-arch/unp app-editors/vim app-eselect/eselect-awk app-misc/screen app-shells/gentoo-zsh-completions app-shells/gentoo-zsh-completions app-vim/colorschemes app-vim/eselect-syntax app-vim/genutils app-vim/ntp-syntax media-gfx/feh sys-process/htop x11-terms/rxvt-unicode

Portage nice value

We're running portage with modified scheduling priority, to not impact whole system performance during compilation.

echo 'PORTAGE_NICENESS="15"' >> /etc/portage/make.conf

Setting portage branches

Branch defines if portage use stable or testing packages. Every package in the portage tree has it stable and testing version. The ACCEPT_KEYWORDS variable defines what software branch to use on the system. It defaults to the stable software branch for the system's architecture, for instance amd64.

I recommend to stick with the stable branch. However, if stability is not that much important for you and/or want to help out Gentoo by submitting bug reports to https://bugs.gentoo.org, then the testing is your way.

There are two ways to approach the testing branch for packages:

  1. System wide setting: to make or system set to testing branch.
nano -w /etc/portage/make.conf
ACCEPT_KEYWORDS="~amd64"
  1. Per package setting: we can set testing branch only for particular packages (This is and example, set whatever you want).
nano -w /etc/portage/package.accept_keywords
sys-kernel/gentoo-sources
sys-power/powertop
app-admin/pass

Masked and unmasked packages

Masking a package the way where Gentoo Developers block a package version from being auto installed. The reason why that package is masked is mentioned in the package.mask file (situated in /usr/portage/profiles/ by default). But if we still wants to use this package, then add the desired version (usually this will be the exact same line from the package.mask file in the profile) to the /etc/portage/package.unmask file (or in a file in that directory if it is a directory).

nano -w /etc/portage/package.unmask
>=app-emulation/docker-compose-1.5.2
>=app-emulation/docker-swarm-1.1.3
>=app-emulation/docker-1.7.1

It is also possible to ask Portage not to take a certain package or a specific version of a package into account. To do so, mask the package by adding an appropriate line to the /etc/portage/package.mask location (either in that file or in a file in this directory).

nano -w /etc/portage/package.mask
=sys-kernel/gentoo-sources-4.5.0

Overlays

Overlays contain additional packages for your Gentoo system while the main repository contains all the software packages maintained by Gentoo developers, additional package trees are usually hosted by repositories. Users can add such additional repositories to the tree that are "laid over" the main tree - hence the name, overlays.

emerge --ask app-portage/layman

To list all available overlays simply run:

layman -L

To install an overlay run:

layman -a <overlay_name>

To keep your installed overlays up to date, run:

layman -S

Custom overlay

If we want to maintain a custom set of ebuilds we just only need to create a local overlay doing these few steps:

mkdir -p /usr/local/portage/{metadata,profiles}
echo '<overlay_name>' > /usr/local/portage/profiles/repo_name
echo 'masters = gentoo' > /usr/local/portage/metadata/layout.conf
chown -R portage:portage /usr/local/portage

Next, tell portage about the overlay:

mkdir -p /etc/portage/repos.conf
nano -w /etc/portage/repos.conf/local.conf
[<overlay_name>]
location = /usr/local/portage
auto-sync = no

Virtualization (How to use Qemu & kvm)

Virtualization is widely use nowadays. Everybody wants to test some environments, apps, or simply have a virtualized machine with other operating systems. In order to do that we should use any virtualization platform available for desktop use such as virtualbox, kvm/qemu, xen or vmware. Among all these options I choose kvm/qemu because its performance and simplicity. So here we are!

First we need to check if our hardware support virtualization:

grep --color -E "vmx|svm" /proc/cpuinfo

We could also check if kvm device is available in our /dev directory:

ls /dev/kvm

If both are available we can continue installing kvm, otherwise you shouldn't use virtualization on your machine.

Kernel options

Before continue building kvm with should check if we have some kernel options enabled as module or build-in.

[*] Virtualization  --->
    <*>   Kernel-based Virtual Machine (KVM) support
    <*>   KVM for Intel processors support <-- if we use Intel cpu, otherwise disable it
    <*>   KVM for AMD processors support <-- if we use AMD cpu, otherwise disable it
    <*>   Host kernel accelerator for virtio net
Device Drivers  --->
   [*] Network device support  --->
      [*]   Network core driver support
      <*>   Universal TUN/TAP device driver support
   [*] Networking support  --->
      Networking options  --->
         <*> The IPv6 protocol
         <*> 802.1d Ethernet Bridging
   File systems  --->
      <*> The Extended 4 (ext4) filesystem
      [*]   Ext4 Security Labels

Once we have kernel compiled and running with new options we can continue by installing package:

emerge --askv app-emulation/qemu

In order to run kvm as normal user and not as root we should add our user account to the kvm group:

gpasswd -a <username> kvm

Finally, to be sure that libvirt daemon is running all the time we should enable with systemd:

systemctl enable libvirtd.service

What is Prelink and how can it help me? I'm sure that most of you are asking this question right now well, most applications we have installed in our system use shared libraries. Every time a program call this libraries they need to be loaded into memory. As more libraries program needs as more time it takes to resolve all symbol references. So prelink simply "maps" this symbol references and makes applications run faster. Of course this is a summary of what it does, but it's enough for us.

The only thing we need to do is to prelink binaries every time we upgrade or install any new program o library. But don't worry, portage will automatically prelink our system for us each time we install a package if we have prelink installed in our system. That's great!!

So we will simply install prelink:

emerge --askv prelink

Then configure the package by running env-update and then editing config file:

env-update

Unfortunately we can't prelink files that were compiled by old versions of binutils. Be default prelink define a number of libraries and directories which as blacklisted to avoid prelinking them. We can add or remove directories in prelink config files:

nano /etc/prelink.conf
nano /etc/prelink.conf.d/*

Finally we will prelink our system with:

prelink -amR

Which is:

  • a: prelink all binary files.
  • m: conserve virtual memory space. If we have a lot of binaries to prelink it takes a lot of space during the process, this parameter will ensure that we not run out of memory.
  • R: randomize the address ordering to enhance security against buffer overflows.

Last notes

Although there's a lot of work to do, I stop this guide at that point which I think that is far from base system installation now you'd walk you path little padawan :smile:

Hope you enjoyed!

Open Source Agenda is not affiliated with "Sergibarroso Gentoo Install" Project. README Source: sergibarroso/gentoo_install

Open Source Agenda Badge

Open Source Agenda Rating