Skip to content
Henryk Paluch edited this page Apr 17, 2024 · 10 revisions

Gentoo setup

Here are my terse instructions for Gentoo setup. Please note that they are not complete, because I often use multi-boot configurations and two systems (build system on Azure, and target bare-metal system at home)...

I always use this profile:

  • OpenRC (no systemd allowed)
  • Desktop (plan to play with Wayland and X is fallback)

Generally I follow:

I currently use Desktop+OpenRC. Typically I look to this mirror for Stage3 tarball:

NOTE: I use two machines:

  1. Build machine: Azure VM running stock Debian 12 - I made future chroot simple as directory called /srv/gentoo-intel Using Size: Standard_E4s_v5. In your case ensure that you use same Family of CPU (Intel or AMD) as will be on Target machine. For AMD you can use Standard_E4as_v5 (there has to be a letter for AMD)
  2. Target machine: local Zotac PC, currently with external USB disk, where I have btrfs partition with subvolume - BTRFS mounted as /mnt/gentoo-btrfs, chroot path with subvolume is /mnt/gentoo-btrfs/ZOTAC-WL (WL is shortcut for Wayland)

I download to parent-dir of future boostrap, for example:

curl -fLO https://ftp.linux.cz/pub/linux/gentoo/releases/amd64/autobuilds/current-stage3-amd64-desktop-openrc/stage3-amd64-desktop-openrc-20231224T164659Z.tar.xz

Inside future chroot I use standard command to unpack:

# CWD is in future chroot
tar xpvf ../stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner

Required copies:

# CWD in future chroot
mkdir -p etc/portage/repos.conf
cp usr/share/portage/config/repos.conf etc/portage/repos.conf/gentoo.conf
cp -L /etc/resolv.conf etc

Now here is my etc/portage/package.use/custom common for all deployments where I plan to use Wayland with Sway:

# /etc/portage/package.use/custom

# Custom USE flags per app
app-text/ghostscript-gpl -dbus
app-arch/cpio  -nls
app-editors/vim -X -acl -crypt -sound

# required to install sway/wayland
>=gui-apps/swaybg-1.2.0 gdk-pixbuf
# required for Wayland
sys-auth/seatd server
www-client/firefox pulseaudio openh264
# required to build firefox
>=media-libs/libvpx-1.13.1 postproc
>=media-plugins/alsa-plugins-1.2.7.1-r1 pulseaudio

And here is common part (for both Azure build host and Target) of etc/portage/make.conf

# Temporarily we don't use specific CPU flags
COMMON_FLAGS="-O2 -fno-strict-aliasing"
# other flags keep "as is"

MAKEOPTS="-j4"
USE="vaapi vdpau brotli webp -kde -accessibility -openmp -fortran \
     -qmanifest -imap -pop3 -qtegrity -tftp compress-zstd zstd \
     logrotate wayland kms gles2 vim-syntax lvm lm-sensors contrib \
     layers tray wallpapers -bluetooth -joystick alsa"
VIDEO_CARDS="nouveau intel qxl"
ACCEPT_LICENSE="@FREE @BINARY-REDISTRIBUTABLE"

# It is closest mirror for me - you may need to change it
GENTOO_MIRRORS="http://ftp.fi.muni.cz/pub/linux/gentoo/"

# always build binary packages (useful for example if compiler gets corrupted, etc...)
FEATURES="buildpkg"
# which Binary packages to NOT build:
EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --buildpkg-exclude  'acct-*/* sys-kernel/*-sources virtual/*'"

We need to first build 2 cpu utils to later use proper CPU flags for compilers.

  • in your chroot prepare script bind_mounts.sh with contents:
    #!/bin/bash
    set -xeuo pipefail
    cd `dirname $0`
    mount --types proc /proc `pwd`/proc
    mount --rbind /sys `pwd`/sys
    mount --rbind /dev `pwd`/dev
    mount --bind  /run `pwd`/run
    exit 0
  • and also prepare environment script init_shell.sh
    source /etc/profile
    # change ZOTAC-WL (ZOTAC PC with Wayland) to your environment name
    export PS1="(ZOTAC-WL) ${PS1}"
  • now OUTSIDE chroot run /PATH_TO_CHROOT/bind_mounts.sh
  • enter chroot: cd /PATH_TO_CHROOT && chroot pwd bash
  • inside chroot run source /init_shell.sh

Now fetch portage archives

# inside chroot
emerge-webrsync

Now we have to build 2 CPU feature utilities to prepare intersection of build flags (common build flags for both Build server and Deploy target).

# inside chroot
emerge -an app-portage/cpuid2cpuflags app-misc/resolve-march-native

Now on both (or all planned servers) run these commands to gather CPU information:

Example for Gentoo target (ZOTAC PC with Celeron):

# grep  'model name' /proc/cpuinfo | sort -u

model name      : Intel(R) Celeron(R) CPU N3450 @ 1.10GHz

# resolve-march-native

-march=goldmont --param=l1-cache-line-size=64 --param=l1-cache-size=24 --param=l2-cache-size=1024

# cpuid2cpuflags

CPU_FLAGS_X86: aes mmx mmxext pclmul popcnt rdrand sha sse sse2 sse3 sse4_1 sse4_2 ssse3

Example for Gentoo Build server (Azure Size Standard_E4s_v5 - you have to use E series without a because that is AMD!):

# grep  'model name' /proc/cpuinfo | sort -u

model name      : Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz

# resolve-march-native

march=icelake-server -mabm -mno-pconfig -mno-pku -mno-sgx -mno-wbnoinvd -mrtm --param=l1-cache-line-size=64 --param=l1-cache-size=48 --param=l2-cache-size=49152

# cpuid2cpuflags

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

Now we have to make intersection - in this case it was easy becasue Celeron is just Subset of Intel Xeon. So in my case I have to add to /etc/portage/make.conf on both machines:

COMMON_FLAGS="-O2 -fno-strict-aliasing -march=goldmont -mtune=goldmont"
CPU_FLAGS_X86="aes mmx mmxext pclmul popcnt rdrand sha sse sse2 sse3 sse4_1 sse4_2 ssse3"

Here is complete /etc/portage/make.conf from Azure build server chroot:

# COMMON_FLAGS we intersect Azure intel and ZOTAC
COMMON_FLAGS="-O2 -fno-strict-aliasing -march=goldmont -mtune=goldmont"
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
CPU_FLAGS_X86="aes mmx mmxext pclmul popcnt rdrand sha sse sse2 sse3 sse4_1 sse4_2 ssse3"

MAKEOPTS="-j4"
USE="vaapi vdpau brotli webp -kde -accessibility -openmp -fortran \
     -qmanifest -imap -pop3 -qtegrity -tftp compress-zstd zstd \
     logrotate wayland kms gles2 vim-syntax lvm lm-sensors contrib \
     layers tray wallpapers -bluetooth -joystick alsa"
VIDEO_CARDS="nouveau intel qxl"
GENTOO_MIRRORS="http://ftp.fi.muni.cz/pub/linux/gentoo/"
ACCEPT_LICENSE="@FREE @BINARY-REDISTRIBUTABLE"
FEATURES="buildpkg"
# Server: which Binary packages to NOT build:
EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --buildpkg-exclude  'acct-*/* sys-kernel/*-sources virtual/*'"
# This sets the language of build output to English.
# Please keep this setting intact when reporting bugs.
LC_MESSAGES=C.utf8

Now on build-server we can rebuild world using:

# in chroot of build server
# around 50 packages will be rebuild
emerge --ask --verbose --update --deep --newuse @world

Merging changes in /etc/

Now we need to publish binary packages on build server

  • following https://wiki.gentoo.org/wiki/Binary_package_guide
  • on build server install lighttpd:
    # in chroot of build server
    emerge -an www-servers/lighttpd
  • append to /etc/lighttpd/lighttpd.conf
    # in chroot of build server
    # listen to IPv4
    server.bind = "0.0.0.0"
    server.port = "80"
    # enable listing for binary packages...
    server.dir-listing = "enable"
    server.modules += ( "mod_alias" )
    alias.url = ( "/packages" => "/var/cache/binpkgs/" )
    
  • finally run in chroot of build server:
    /usr/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf

Now on client Machine do this:

  • verify that your Build server is accessible:

    # run on client machine
    curl -fv http://FQDN_OF_BUILD_SERVER/packages/
  • now edit /etc/portage/binrepos.conf/gentoobinhost.conf on client Chroot and REPLACE sync-url with above URL:

    [gentoobinhost]
    priority = 1
    #sync-uri = https://gentoo.osuosl.org/releases/amd64/binpackages/17.1/x86-64
    sync-uri = http://FQDN_OF_BUILD_SERVER/packages
    
  • finally append on Client /etc/portage/make.conf Client excludes:

    # Client: do not fetch specified binary packages (use always source)
    EMERGE_DEFAULT_OPTS="${EMERGE_DEFAULT_OPTS} --usepkg-exclude 'acct-*/* sys-kernel/*-sources virtual/*'"
    
  • now conditionally rebuild world on Client Chroot

    • notice added -gk which will prefer to fetch binary packages if available
    emerge --ask --verbose --update --deep --newuse -gk @world
  • all packages (with exception of those excluded) should be in magenta color with prefix binary

  • if it looks correctly press Enter to reinstall these packages from build server.

Now: Client (Target) machine only:

# on Client chroot
echo Europe/Prague > /etc/timezone
emerge --config sys-libs/timezone-data

On both client and server:

  • edit chroot file /etc/locale.gen
    • I uncommented only en_US.*
  • inside chroot run locale-gen
  • verify selected locale: eselect locale list
    • I use C.UTF-8 (should be default - with asterisk *)

On Client chroot install firmware (not needed on build Server because it is Debian and it will never boot Gentoo)

emerge -an sys-kernel/linux-firmware

Installing kernel source:

  • on both (Build Server and Target - because many programs need kernel source in /usr/src):
    # first run on Build Server chroot (in my case it will build 2 CPIO packages and lspci)
    emerge -a sys-kernel/gentoo-sources sys-apps/pciutils sys-kernel/dracut \
      sys-fs/btrfs-progs sys-fs/lvm2
  • when build on Server is finished run on Client (-gk to install CPIO binaries):
    # run in Client chroot
    emerge -angk sys-kernel/gentoo-sources sys-apps/pciutils sys-kernel/dracut \
      sys-fs/btrfs-progs sys-fs/lvm2
  • on both machines select only source (it will create symbolic link /usr/src/linux needed by apps)
    eselect kernel list
    eselect kernel set 1

Now we have to build right kernel - follow Gentoo for this...

Installing various programs:

# run on Build server first with -an:
emerge -an sys-fs/ncdu app-portage/gentoolkit app-editors/vim app-misc/mc app-admin/sudo \
  app-misc/tmux app-admin/sysstat sys-apps/smartmontools \
  net-misc/dhcpcd app-admin/rsyslog sys-process/cronie app-shells/bash-completion \
  sys-process/lsof
# repeate with additional -gk on Client machine:
emerge -angk ...

When kernel is build I use script to backup all kernel files (you need to tailor it to your environment:

#!/bin/bash
set -euo pipefail
set -x

kv=6.1.67-gentoo-zotac

tar -cav --numeric-owner --one-file-system \
      -f /home/azureuser/az-gentoo-kernel-$kv-`date '+%s'`.tar.zst -C /srv/gentoo-intel \
       boot/System.map-$kv boot/config-$kv boot/initramfs-$kv.img boot/vmlinuz-$kv lib/modules/$kv
exit 0

And then unpack it on target.

On Target chroot remember to at least set root password:

passwd root

Set proper default editor - create script etc/profile.d/editor.sh with contents:

export EDITOR=/usr/bin/vim

Source it in chroot:

source /etc/profile.d/editor.sh

And do few changes using visudo in chroot:

  • add Defaults !fqdn to avoid DNS lookups on each sudo invocation
  • uncomment %wheel ALL=(ALL:ALL) NOPASSWD: ALL
  • now setup user and add it to wheel group:
# all commands run in Target chroot:
u=YOUR_USERNAME
/usr/sbin/useradd -G wheel -m -s /bin/bash $u
passwd $u

In chroot ensure that neede services will start:

# run in Target chroot
rc-update add dhcpcd default
rc-update add rsyslog default
rc-update add sshd default

GRUB configuration:

  • I use other host Linux to boot Gentoo
  • here is my example /etc/grub.d/40_custom on Host Linux
# ...
menuentry "Gentoo - BTRFS/ZOTAC-WL - Elements" {
	insmod gzio
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root 8202950e-f135-43fb-8dbd-7f599ae1ca03
        linux /boot/external-hd/vmlinuz-6.1.67-gentoo-zotac root=UUID=7da4d92f-aa4e-441b-893e-39ea40ba42d1 rootflags=noatime,compress=zstd:1,subvolid=257 ro net.ifnames=0
        initrd /boot/external-hd/initramfs-6.1.67-gentoo-zotac.img
}

NOTES:

  • I was unable to boot from Grub my Gentoo from external USB drive, because BIOS simply does not assign "drive letter" to that drive unless it is selected in BIOS Boot Menu (which I don't plan yet)
  • so I have to copy Kernel and Initrd to Host /boot/ partition in my case folder /boot/external-hd
  • the first FS UUID (8202950e-f135-43fb-8dbd-7f599ae1ca03) is UUID of filesystem that holds /boot folder (Host Linux filesystem)
  • second FS UUID (7da4d92f-aa4e-441b-893e-39ea40ba42d1) is that of main BTRFS filesystem, that holds my Gentoo Linux.
  • finally you need to get right subvolid (257 in my case) which is BTRFS subvolume ID where is installed my Gentoo - you can get it on Host using btrfs su li /BTRFS_MOUNT_POINT
  • finally I do on Host (openSUSE LEAP):
    grub2-mkconfig -o /tmp/grub.cfg
    diff -u /tmp/grub.cfg /boot/grub2/grub.cfg
    # review and finally:
    cp /tmp/grub.cfg /boot/grub2/grub.cfg

Wayland install

Here is compressed version from Gentoo wiki.

  • ensure that you have right contents in /etc/portage/package.use/custom - as shown in above text
  • now on Build Server run:
    # chroot of Build Server
    emerge -an gui-wm/sway sys-auth/seatd gui-apps/foot x11-misc/dmenu media-fonts/terminus-font \
        gui-apps/waybar
    # on Client use -angk
    emerge -angk ...

TODO:

  • XDG, usermod, service seatd,...

X-Window install

It is always usefull to have X-Window as fallback (if Wayland does not work) - we can follow https://wiki.gentoo.org/wiki/Xorg/Guide - I plan to install X-Window + XFCE and use startx to start X-Window and sway to start Wayland.

NOTE this:

  • all my real hardware is NVidia or Intel GPU (no AMD/ATI)
  • I plan to also use Gentoo as VM - so qxl, VMware or VirtualBox guest support is wanted.
  • here are my settings in etc/portage/make.conf
    INPUT_DEVICES="libinput vmmouse"
    VIDEO_CARDS="intel nouveau qxl i915 nvidia vesa virtualbox vmware"
    USE=" ... xvfb xa"

WARNING! In case of my old NVidia GT218 there is bad news, looking at

  • https://wiki.gentoo.org/wiki/NVIDIA
  • last driver that supports that card is 340
  • this should help (but not yet tested) - from https://wiki.gentoo.org/wiki/NVIDIA/nvidia-drivers:
    echo '>x11-drivers/nvidia-drivers-340' >> /etc/portage/package.mask/nvidia-gt218
  • PROBLEM: As of Dec 2023 - oldest nvidia-drivers-X package is x11-drivers/nvidia-drivers-390.157, but my card is supported by 340 only... In such case the only "solution" is to remove "nvidia" from VIDEO_CARDS...

Following: https://wiki.gentoo.org/wiki/Xorg/Guide First we should check if we have correct flags for Driver:

emerge -pv  x11-base/xorg-drivers

When it looks reasonable, building with:

emerge -an x11-base/xorg-server
echo XSESSION="Xfce4" > /etc/env.d/90xsession
env-update && source /etc/profile

Additionally I plan to use:

emerge -an  x11-apps/xinit x11-terms/xterm
# has to be in this order
echo 'media-libs/libcanberra pulseaudio' >> /etc/portage/package.use/custom
emerge -an xfce-extra/xfce4-notifyd
echo 'gnome-base/gvfs blueray fuse samba gphoto2' >> /etc/portage/package.use/custom
emerge -an xfce-base/xfce4-meta
# TODO startup...

To start X-Window few requirements must be met:

  • resolvable hostname - ping below must work properly:
    ping `hostname`
    • otherwise there will be xauth related errors
  • due required X-Server privileges, the elogind must be running in OpenRC environment (my case)
    rc-update add elogind boot
    /etc/init.d/elogind start
    • you need to logout and login, because there is elogind PAM module executed on login
    • otherwise X-server will report permission error when accessing /dev/ttyX When done you can start X-Window using startx command...

If mouse and keyboard does not work we need to follow

  • https://wiki.gentoo.org/wiki/Libinput
  • emerge:
    emerge -an x11-misc/xdotool x11-misc/wmctrl
  • add your user to input group:
    usermod -a -G input USERNAME
    • and login again to become member of input group
  • to detect PS/2 mouse I needed to reboot machine - than it worked:
    libinput list-devices | fgrep -A 1 -i ps/2
    
    Device:           ImPS/2 Generic Wheel Mouse
    Kernel:           /dev/input/event15

Importing VM from VirtualBox to libvirt

I simply do this to copy VM from VirtualBox to libvirt (virt-manager):

  1. exporting VM from VirtualBox to OVA
  2. unpacking OVA with tar xvf file.ova (really!)
  3. converting VMDK to QCOW2 using qemu-img convert -O qcow2 image.vmdk image.qcow2
  4. Copying QCOW2 image to target /var/lib/libvirt/images and changing owner to root:root
  5. invoking virsh pool-refresh default
  6. verifying with virsh vol-list default
  7. Creating empty VM of type Gentoo 2022
  8. Attaching above Volume in pool default
  9. Booting VM.

However there are artifacts of VirtualBox Guest tools that should be replaced with QEMU/KVM stuff:

First uninstalling VirtualBox guest tools:

# find packages that looks like virtualbox
find /var/db/pkg/ -type d -name '*box*'
# removing list - answer No!
emerge -Ca app-emulation/virtualbox-guest-additions
# I have to stick these packages (to be not removed)
# Your list will be likely different!
# Answer Yes to make these packages sticky:
emerge -an media-fonts/liberation-fonts app-editors/nano 11-apps/xrefresh x11-apps/xrandr
# run again:
emerge -ca
# verify that only these packages will be removed (I don't need gpgme or w3m):
# acct-group/vboxguest dev-libs/boehm acct-user/vboxguest app-crypt/gpgme
# acct-group/vboxsf virtual/w3m-1 www-client/w3m
# If sure, answer Yes to confirm removal...

Finally we should install QEMU guest agent and SPICE/QXL utilities:

  • I have to manually change card type from Virtio to QXL in virt-manager (some functions not yet work properly with Virtio PV card)
  • install and run QEMU guest agent:
    emerge -an app-emulation/qemu-guest-agent
    rc-update add qemu-guest-agent default
  • and SPICE VDA agent:
    emerge -an app-emulation/spice-vdagent
    rc-update add spice-vdagent default
  • reboot system to ensure that all changes will be propagated
Clone this wiki locally