Installing Gentoo

Aug 26, 2021


Gentoo is a source based Linux distribution which is very flexible and can be customized to fit the user’s needs. A bit ago I started using Gentoo Linux daily. EDIT: Back to using Arch Linux. Here’s the install procedure, because a lot of people seem to think it’s difficult.

Creating a live USB

Obviously before we can begin, we need to boot the computer into some kind of environment. I opt for systemrescuecd .

You can use dd to create the USB.

$ dd if=systemrescuecd.iso of=/dev/sdb bs=4096 status=progress

If you are on Windows you can use win32diskimager .


Boot into systemrescuecd the same way you’d boot into any other USB. Once booted you can either start the GUI or continue in the command line, your choice. I will be going through the steps in the command line.

Partitioning the disk

List the disks out using lsblk, you should see an output like this:

NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                                             8:0    0 931.5G  0 disk  
└─sda1                                          8:1    0 931.5G  0 part  
sr0                                            11:0    1     2K  0 rom   

This command lists out block devices. Keep note of the hard disk or SSD you want to install to because you’ll need to know it for preparing the disk.

Run the cfdisk command with the name of the disk you want to install to.

# cfdisk /dev/sda

Follow the instructions for creating a new partition, should be self explanatory, but if you’re not sure how to use cfdisk, this article explains better than me. If you are using MBR or DOS you will need to mark the first partition as Bootable.

This is an example layout:

Boot partition: /dev/sda1   fat32   500MB (must be fat32 if you're using UEFI, because that's the EFI system partition)
Root partition: /dev/sda2   ext4    241GB (you're gonna need a lot for compiling)
Swap partition: /dev/sda3   swap    8GB

Formatting and creating the filesystems.

# mkfs.vfat -n boot /dev/sda1 (creates a fat32 filesystem with the label boot)
# mkfs.ext4 -L linux /dev/sda2 (creates an ext4 filesystem with the label linux)
# mkswap -L swap /dev/sda3 (creates a swap partition with the label swap)

Mounting the disks

# mkdir -p /mnt/gentoo
# mount /dev/sda2 /mnt/gentoo (mount root partition in /mnt/gentoo)
# mkdir /mnt/gentoo/boot (create boot directory)
# swapon /dev/sda3 (swapon the swap partition)

Installing the root filesystem

You will need a root filesystem tarball to use for installing Gentoo, you can get it from .

# cd /mnt/gentoo (enter the directory where the root partition is mounted)
# wget (download a stage tarball as close to this date as possible)

Unpack the stage tarball

# tar xvpf stage3-amd64-openrc-20210801T170533Z.tar.xz --xattrs-include="*" --numeric-owner

Configure some things like the make.conf

# vim /mnt/gentoo/etc/portage/make.conf

A default make.conf will look something like this

# These settings were set by the catalyst build script that automatically
# built this stage
# Please consult /usr/share/portage/config/make.conf.example for a more
# detailed example
COMMON_FLAGS="-O2 -pipe"

# NOTE: This stage was built with the bindist Use flag enabled

# This sets the language of build output to English.
# Please keep this setting intact when reporting bugs.

Customize it the way you want or need, here’s an example of a customized one

# CFLAGS and other stuff specific to my CPU
COMMON_FLAGS="-march=skylake -O2 -pipe"
VIDEO_CARDS="intel i965 iris"
INPUT_DEVICES="wacom libinput"
CPU_FLAGS_X86="aes avx avx2 f16c fma3 mmx mmxext pclmul popcnt rdrand sse sse2 sse3 sse4_1 sse4_2 ssse3"

# USE flags
USE="-gnome -ppp wayland X xinerama bluetooth pulseaudio networkmanager \
     qt5 kde dvd cdr avahi Xvaapi sound vim-syntax x264 \
     zsh-completion udev ios gphoto2"

# Build a binary package that I can distribute to other machines
L10N="en en-US"

# Set targets for certain packages
QEMU_SOFTMMU_TARGETS="arm aarch64 alpha i386 x86_64 sparc sparc64 ppc ppc64 riscv32 riscv64 mipsel mips64el mips mips64"
QEMU_USER_TARGETS="x86_64 i386 aarch64 arm"
GRUB_PLATFORMS="efi-64 pc"

# Accept all licenses, except those with a EULA

# Set default emerge options
EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --jobs 4 --usepkg-exclude 'sys-kernel/gentoo-sources virtual/*'"

# Portage directories

# This sets the language of build output to English.
# Please keep this setting intact when reporting bugs.

# Mirrors

A quick run down of what the basic options do


COMMON_FLAGS is basically where your compiler flags will go. You can read a bit about safe CFLAGS here . CFLAGS tell the compiler what optimizations and options to use, when compiling the code. So it basically tells the compiler how it wants to produce the code. Some CFLAGS which you should pay attention to are -O, this is optimization level, it goes all the way up to -O3. -O2 is the recommended and known stable optimization level. -O0 is basically no optimization, so it’s usually used for debugging, and -O1 is little optimization. You might want to pay attention to -march and -mtune which tells the compiler how to produce the best and most optimized code for your CPU microarchitecture. -march is forwards compatible, but not backwards compatible, so binaries compiled using -march=core2 will run on Core 2 and up. -mtune tells the compiler to optimize code for a specific CPU microarchitecture, without breaking compatibility with older CPUs. An example would be -march=haswell -mtune=skylake, what this would do is produce binaries compatible with Haswell and up, but optimized for Skylake, so it won’t perform as well as -march=skylake but your binaries will remain compatible with the older microarchitecture. I recommend avoiding most CFLAGS, that you might see on forums and things, such as -funroll-all-loops and -ffast-math. These CFLAGS are typically very aggressive and can produce unstable and/or broken code. -pipe will not make any difference on the generated code, but will make compilation faster, turn this off if you are on a limited amount of RAM.


CPU_FLAGS_X86 is what tells the compiler which CPU instructions to enable, you can see which your CPU supports by running the lscpu command, and checking out flags. This is optional and you probably don’t have to worry about it right now, but it’s something you can either setup now or later. It tells the compiler to produce code that takes advantage of the instructions in your CPU, so if you want binaries compatible with an older CPU, only use instructions compatible with that older CPU, otherwise you’ll get illegal instruction when trying to run the binaries on an older CPU that’s missing that instruction.


MAKEOPTS tells portage how many threads to give the compiler. It’s recommended to only enable as many MAKEOPTS as you have RAM to support it. If you are running into compilation failures due to lack of RAM, or lock ups, lower your MAKEOPTS. You should have at least 2GB RAM for each MAKEOPT you have. For MAKEOPTS=j4 you should have at least 8GB RAM.

USE flags

USE tells portage what global use flags to enable. If you want to enable qt5 and kde globally, such as if you are a KDE user. You can enable that by setting USE in make.conf. For individual packages you should instead customize /etc/portage/package.use. You can set USE flags for individual packages for example app-editors/emacs dbus gtk gpm gui inotify libxml2 sound source ssl xft xwidgets which sets these use flags for emacs. /etc/portage/package.use can either be a directory or a file, by default it’s a directory now. A quick way to enable use flags for a package would be # echo "app-editors/emacs dbus gtk gpm gui inotify libxml2 sound source ssl xft xwidgets" > /etc/portage/package.use/emacs.


ACCEPT_LICENSE tells portage which licenses to accept by default, by default I believe it accepts free software licenses, but I have it set to the old behavior ACCEPT_LICENSE="* -@EULA" which is accept any license, except EULAs.

Configuring the Gentoo repos

Create the repos.conf directory

# mkdir --parents /mnt/gentoo/etc/portage/repos.conf

Copy the Gentoo repository configuration file to repos.conf

# cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf


Enter the following commands to get into the chroot environment.

# mount -t proc /proc /mnt/gentoo/proc
# mount -R /sys /mnt/gentoo/sys
# mount -R /dev /mnt/gentoo/dev
# chroot /mnt/gentoo /bin/bash
# source /etc/profile
# export PS1="(chroot) ${PS1}" (so we know we are in the chroot)
# echo "nameserver" > /etc/resolv.conf (we need a resolv.conf for networking as it provides DNS info, I just use the DNS for the chroot)

Syncing the portage tree

At this point you should sync the portage tree before going any further

# emerge-webrsync (grabs a recent snapshot of portage, might be a couple days old)
# emerge --sync (syncs portage with the latest repositories on the Gentoo servers as of the moment you run it)

Selecting a profile

List profiles to see which one you want

# eselect profile list
Available profile symlink targets:
  [1]   default/linux/amd64/17.1 (stable) *
  [2]   default/linux/amd64/17.1/selinux (stable)
  [3]   default/linux/amd64/17.1/hardened (stable)
  [4]   default/linux/amd64/17.1/hardened/selinux (stable)
  [5]   default/linux/amd64/17.1/desktop (stable)
  [6]   default/linux/amd64/17.1/desktop/gnome (stable)
  [7]   default/linux/amd64/17.1/desktop/gnome/systemd (stable)
  [8]   default/linux/amd64/17.1/desktop/plasma (stable)
  [9]   default/linux/amd64/17.1/desktop/plasma/systemd (stable)
  [10]  default/linux/amd64/17.1/desktop/systemd (stable)
  [11]  default/linux/amd64/17.1/developer (stable)
  [12]  default/linux/amd64/17.1/no-multilib (stable)
  [13]  default/linux/amd64/17.1/no-multilib/hardened (stable)
  [14]  default/linux/amd64/17.1/no-multilib/hardened/selinux (stable)
  [15]  default/linux/amd64/17.1/no-multilib/systemd (dev)
  [16]  default/linux/amd64/17.1/systemd (stable)
  [17]  default/linux/amd64/17.0 (dev)
  [18]  default/linux/amd64/17.0/selinux (dev)
  [19]  default/linux/amd64/17.0/hardened (dev)
  [20]  default/linux/amd64/17.0/hardened/selinux (dev)
  [21]  default/linux/amd64/17.0/desktop (dev)
  [22]  default/linux/amd64/17.0/desktop/gnome (dev)
  [23]  default/linux/amd64/17.0/desktop/gnome/systemd (dev)
  [24]  default/linux/amd64/17.0/desktop/plasma (dev)
  [25]  default/linux/amd64/17.0/desktop/plasma/systemd (dev)
  [26]  default/linux/amd64/17.0/developer (dev)
  [27]  default/linux/amd64/17.0/no-multilib (dev)
  [28]  default/linux/amd64/17.0/no-multilib/hardened (dev)
  [29]  default/linux/amd64/17.0/no-multilib/hardened/selinux (dev)
  [30]  default/linux/amd64/17.0/systemd (dev)
  [31]  default/linux/amd64/17.0/x32 (dev)
  [32]  default/linux/amd64/17.0/musl (exp)
  [33]  default/linux/amd64/17.0/musl/hardened (exp)
  [34]  default/linux/amd64/17.0/musl/hardened/selinux (exp)
  [35]  default/linux/amd64/17.0/uclibc (exp)
  [36]  default/linux/amd64/17.0/uclibc/hardened (exp)

You can set a profile with

# eselect profile set 5 (setting the desktop profile, which pulls in desktop packages)

Setting timezone

Now it’s time to set the timezone, list available timezones in /usr/share/zoneinfo

# ls /usr/share/zoneinfo 

Set your timezone by putting the name in /etc/timezone.

# echo "US/Pacific" > /etc/timezone

Reconfigure timezone data now

emerge --config sys-libs/timezone-data

Updating world

The tarball is usually a couple days out of date, so you will need to update world.

# emerge -vuaDN world

Installing your favorite editor

At this point I install vim because that’s the editor I like to use.

# emerge vim

Setting the locale

Locales are the language, but also rules for your system, such as strings and date and time. These are case sensitive and must be typed correctly. You can find a list in /usr/share/i18n/SUPPORTED

# vim /etc/locale.gen

Example /etc/locale.gen

en_US ISO-8859-1
en_US.UTF-8 UTF-8

Then generate the locales

# locale-gen

Then set the default locale

# eselect locale list
Available targets for the LANG variable:
  [1]   C *
  [2]   C.utf8
  [3]   en_US
  [4]   en_US.iso88591
  [5]   en_US.utf8
  [6]   POSIX
  [ ]   (free form)
# eselect locale set 5

Next update your environment

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


You can either configure the kernel, or use a preconfigured one. I won’t go over configuring the kernel because that’s a more advanced thing, for now let’s use a preconfigured one.

# emerge sys-kernel/linux-firmware (install firmwares)
# emerge sys-kernel/installkernel-gentoo
# emerge sys-kernel/gentoo-kernel-bin (installs a prebuilt kernel, omit the -bin if you want portage to compile it)


Install a bootloader, grub2 for example. You will need to make sure the correct GRUB_PLATFORMS are selected.

# echo 'GRUB_PLATFORMS="efi-64"' >> /etc/portage/make.conf (build GRUB with x86_64 UEFI support only)
# echo 'GRUB_PLATFORMS="efi-32"' >> /etc/portage/make.conf (build GRUB with i386 UEFI support only)
# echo 'GRUB_PLATFORMS="pc"' >> /etc/portage/make.conf (build GRUB with legacy support only)
# echo 'GRUB_PLATFORMS="pc efi-64"' >> /etc/portage/make.conf (build GRUB with x86_64 UEFI and legacy support)
# echo 'GRUB_PLATFORMS="pc efi-64 efi-32"' >> /etc/portage/make.conf (build GRUB with i386 UEFI, x86_64 UEFI, and legacy support)

Install GRUB in legacy mode

# grub-install /dev/sda

Install GRUB in UEFI mode

# mount -o remount,rw /sys/firmware/efi/efivars
# grub-install --target=x86_64-efi --efi-directory=/boot

Generate GRUB config

# grub-mkconfig -o /boot/grub/grub.cfg


The fstab is the file that tells the computer how to mount each block device, I’m gonna configure it by-label like so.

# vim /etc/fstab
LABEL=boot  /boot   vfat    defaults,noauto 0 2
LABEL=linux  /   ext4    defaults    0 1
LABEL=swap  none    swap    defaults    0 0

Setting hostname

Set the hostname with

# echo 'hostname="phosphor"' > /etc/conf.d/hostname

Configuring networking

The easiest way to do this is using networkmanager

# emerge networkmanager
# rc-update add NetworkManager default

Another way to configure the ethernet interface for example

# emerge dhcpcd
# vim /etc/conf.d/net
# ln -s net.lo net.eth0 
# rc-update add net.eth0 default

Setting root password

Set your root password like so

# passwd root

Finishing up

Now that Gentoo is installed you can exit the chroot environment

# exit


# reboot

If things turn out well you are in a minimal Gentoo system, I won’t cover installing the desktop environment yet and post configuration just yet, but I’ll add that to the post later on.


Magical girl from another dimension.

Learning to Love Vim

Using Wayland daily on KDE Plasma, My Experience