~kris/dots

srice

ref: 512b7381d0155d6247fad64b640b0704496a8035 srice/GENTOO-MIGRATION.md -rw-r--r-- 12.5 KiB
512b7381 — Kris Yotam mksh: port bashisms to mksh-safe (process subs, DEBUG-trap history hook, direnv, cd- alias) 2 months ago

#Gentoo Migration Guide for Moirai

#Hardware Summary

Component Spec Gentoo Kernel Implications
CPU Intel Core Ultra 7 265K (Arrow Lake, 20C, 5.6GHz) Needs latest kernel (6.8+), no hyperthreading to configure
RAM 30GB ZRAM swap configured in userspace
dGPU AMD Radeon RX 6800 XT (Navi 21) VIDEO_CARDS="amdgpu", firmware blobs required
iGPU Intel Arrow Lake (i915/xe) VIDEO_CARDS="intel", xe driver experimental
Storage 2x NVMe 931G + 1x 1.8T HDD NVMe + AHCI in kernel
Displays 4 monitors, dual GPU, mixed rotation Xorg multi-GPU config

#Filesystem Choice

#Recommendation: ext4 for root, XFS for /home and storage

Mount Filesystem Why
/boot (1G) ext4 Universal bootloader support, simple
/ (50G) ext4 Rock-solid, fast fsck, Gentoo wiki assumes ext4
/home (880G) XFS Excellent large-file performance, scales well, no shrink but you won't need to
/mnt/storage (1.8T HDD) XFS Best for large sequential I/O, HDD-friendly
/mnt/storage2 (931G NVMe) XFS Consistent with /home

#Why NOT these:

  • Btrfs: Tempting for snapshots, but write amplification on NVMe, and you don't need snapshots if you have backups. Adds complexity for marginal gain on a desktop.
  • ZFS: Requires out-of-tree kernel module, constant rebuilds on kernel updates, memory overhead. Not worth it for a desktop workstation.
  • F2FS: Designed for flash but less mature tooling, no real advantage over ext4/XFS on desktop NVMe.
  • HAMMER2 (DragonflyBSD): Not available on Linux.

#Partition Layout

/dev/nvme0n1:
  p1: 1G    /boot     ext4    (EFI system partition if UEFI)
  p2: 50G   /         ext4
  p3: 880G  /home     XFS

/dev/nvme1n1:
  p1: 931G  /mnt/storage2  XFS

/dev/sda:
  p1: 1.8T  /mnt/storage   XFS

#Kernel Configuration

Gentoo's biggest decision: genkernel vs manual config.

Recommendation: Manual config (make menuconfig). You have specific hardware that benefits from a tailored kernel. Use your current Arch kernel config as a starting point:

zcat /proc/config.gz > /usr/src/linux/.config
make oldconfig

#Critical kernel options:

# CPU
CONFIG_MCORE2=y              # or CONFIG_GENERIC_CPU for safety
CONFIG_NR_CPUS=20
CONFIG_PREEMPT_VOLUNTARY=y   # desktop responsiveness

# GPU - AMD
CONFIG_DRM_AMDGPU=m
CONFIG_DRM_AMDGPU_SI=y
CONFIG_DRM_AMDGPU_CIK=y
CONFIG_HSA_AMD=y
CONFIG_AMD_IOMMU=y

# GPU - Intel (for iGPU monitor)
CONFIG_DRM_I915=m
# CONFIG_DRM_XE=m            # experimental xe driver, try if i915 fails on Arrow Lake

# Storage
CONFIG_BLK_DEV_NVME=y        # built-in, not module (boot drive)
CONFIG_SATA_AHCI=y
CONFIG_XFS_FS=y
CONFIG_EXT4_FS=y

# ZRAM
CONFIG_ZRAM=m
CONFIG_ZSWAP=y
CONFIG_CRYPTO_LZ4=y

# Audio (pipewire needs ALSA base)
CONFIG_SND_HDA_INTEL=m
CONFIG_SND_USB_AUDIO=m

# Networking
CONFIG_IWLWIFI=m             # if you have Intel WiFi
CONFIG_BT=m                  # Bluetooth

# Misc
CONFIG_USB_XHCI_HCD=y
CONFIG_FUSE_FS=m
CONFIG_V4L2_LOOPBACK=m       # if needed

#Firmware

AMD GPU requires firmware blobs:

emerge sys-kernel/linux-firmware
# or minimal: just /lib/firmware/amdgpu/navi21*

#Profile and USE Flags

#Profile

eselect profile set default/linux/amd64/23.0/desktop

Don't use systemd profile (you'll want OpenRC for simplicity and suckless philosophy alignment).

#Global USE Flags (/etc/portage/make.conf)

USE="X vulkan vaapi vdpau alsa pipewire pulseaudio bluetooth
     python lua luajit nodejs rust go
     zsh-completion fish-completion
     -wayland -gnome -kde -systemd -qt5 -qt6
     jpeg png webp gif svg tiff
     truetype fontconfig
     dbus elogind policykit
     lto pgo -debug"

VIDEO_CARDS="amdgpu intel"
INPUT_DEVICES="libinput"

# CPU flags (run cpuid2cpuflags after first boot)
CPU_FLAGS_X86="aes avx avx2 avx512f fma3 mmx popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"

MAKEOPTS="-j16"              # 16 of 20 cores for compiles (leave headroom)
EMERGE_DEFAULT_OPTS="--jobs=4 --load-average=16"

# Language targets
L10N="en"
PYTHON_TARGETS="python3_12"
LUA_TARGETS="lua5-4 luajit"

#What to Compile vs Use Binaries

This is the key Gentoo decision. Your system has 20 cores at 5.6GHz so compilation is fast, but some packages take hours regardless.

#USE BINARIES (via getuto binhost or -bin packages)

Package Why binary
www-client/firefox-bin or librewolf-bin 2+ hour compile, frequent updates, USE flags rarely matter
app-office/libreoffice-bin 3+ hour compile, you probably barely use it
dev-lang/rust-bin 1+ hour bootstrap, needed as dependency only
dev-lang/go Bootstraps itself, binary is fine
dev-util/electron Hours to compile, used as runtime only
net-libs/nodejs Slow compile, binary works identically
dev-dotnet/dotnet-sdk-bin .NET is binary-distributed anyway
app-containers/docker Binary works fine, no custom flags needed
dev-java/openjdk-bin JVM is JVM
dev-lang/ghc-bin Haskell compiler bootstrap is brutal

#COMPILE FROM SOURCE (where it matters)

Package Why compile
sys-kernel/gentoo-sources Custom kernel for your hardware
x11-wm/dwm (from git) Your custom patches, the whole point
x11-terms/st (from git) Your custom patches
x11-misc/dmenu (from git) Your custom patches
media-video/mpv Custom codec/GPU flags
app-editors/neovim LuaJIT integration, latest features
media-video/pipewire Audio stack, needs exact flag match
x11-base/xorg-server GPU-specific optimization
sys-libs/glibc Foundation of everything
app-shells/fish Small, fast compile, benefits from LTO
net-misc/curl Security-relevant, want exact TLS backend
dev-vcs/git Used constantly, benefits from optimization
app-misc/tmux Tiny, fast
sys-process/htop/app-misc/btop Tiny
media-gfx/imagemagick Custom format support
net-dns/unbound If using local DNS
x11-misc/picom Compositor, benefits from GPU flags
app-misc/conky Lua + X11 integration
All suckless tools The entire point of suckless

#GREY AREA (compile if you have time, binary if impatient)

Package Notes
www-client/chromium 4-6 hour compile but vaapi/vulkan flags matter for video
dev-lang/python 10 min compile, LTO makes measurable difference
media-libs/mesa 15 min, GPU-specific optimizations apply
sys-devel/gcc 30-45 min, PGO build genuinely faster
sys-devel/llvm 45-60 min, needed for mesa/amdgpu

#Init System

OpenRC, not systemd.

Reasons:

  • Simpler, faster boot
  • Shell scripts you can read
  • Aligns with suckless philosophy
  • elogind provides seat/session management without systemd
  • Everything in your stack works fine without systemd

Services to enable:

rc-update add elogind default
rc-update add dbus default
rc-update add NetworkManager default  # or dhcpcd if you prefer
rc-update add bluetooth default
rc-update add zram-init default
rc-update add cronie default

#Overlay Strategy

You need the guru overlay and possibly a personal overlay.

emerge app-eselect/eselect-repository
eselect repository enable guru
emerge --sync

#Packages needing overlays:

Package Source
eww guru or custom ebuild
fastfetch guru
eza guru or main repo (check)
zoxide main repo (app-shells/zoxide)
rmpc custom ebuild (Rust, cargo install)
mouseless custom ebuild (go build)
ueberzugpp guru
pywal pip install or custom ebuild
nerd-fonts guru
lazygit main repo
lazydocker guru
git-delta main repo (dev-util/git-delta)
ani-cli custom ebuild or /usr/local
mullvad-vpn custom ebuild from Mullvad
lf main repo (app-misc/lf)

For anything without an ebuild, use /usr/local/ or ~/.local/bin/ (which you already do for many scripts).

#Suckless Build Strategy

Your suckless programs live in ~/src/{dwm,st,dmenu,dwmblocks,scron,quark}. On Gentoo:

  1. Don't use portage for suckless tools
  2. Keep building from your git repos with make clean install
  3. Install build deps via portage: x11-libs/libX11 x11-libs/libXft x11-libs/libXinerama media-libs/fontconfig

This is identical to your current Arch workflow.

#Migration Path

#Phase 1: Preparation (on Arch)

# Save current state
pacman -Qe > ~/packages-explicit.txt
zcat /proc/config.gz > ~/kernel-config
cp -r /etc/X11/xorg.conf.d ~/xorg-backup/
lspci -k > ~/lspci-drivers.txt

#Phase 2: Install Gentoo

  1. Boot Gentoo minimal install ISO from USB
  2. Partition nvme0n1 (keep /home intact if possible, just reformat / and /boot)
  3. Stage3 tarball (OpenRC, no-multilib unless you need 32-bit wine)
  4. Configure make.conf with the flags above
  5. Build kernel from your saved config
  6. Install bootloader (GRUB or systemd-boot work fine)
  7. Reboot into Gentoo

#Phase 3: Desktop Stack

# X11 + GPU
emerge xorg-server xf86-video-amdgpu mesa vulkan-loader vulkan-tools

# Fonts
emerge media-fonts/noto media-fonts/liberation-fonts
# nerd-fonts from guru overlay

# Audio
emerge media-video/pipewire media-video/wireplumber

# Desktop deps
emerge libX11 libXft libXinerama fontconfig freetype harfbuzz

# Build suckless from ~/src/
cd ~/src/dwm && sudo make clean install
cd ~/src/st && sudo make clean install
cd ~/src/dmenu && sudo make clean install
cd ~/src/dwmblocks && sudo make clean install

# Shell + tools
emerge fish zoxide fzf fd ripgrep bat eza dust nnn tmux neovim

# Apply srice
cd ~/src/srice && stow .

#Phase 4: Verify

  • 4 monitors working (xrandr / screenlayout script)
  • Audio (pipewire + wireplumber)
  • GPU acceleration (vulkaninfo, glxinfo)
  • All statusbar modules
  • Fish shell + all configs

#Compile Time Estimates (20-core Arrow Lake)

Package Approx Time
Full @world (first build, ~300 packages) 4-8 hours
Kernel 5-10 minutes
GCC 30-45 minutes
LLVM 45-60 minutes
Mesa 10-15 minutes
Firefox/Librewolf (if compiling) 2-3 hours
Python 8-12 minutes
Neovim 2-3 minutes
Xorg-server 5 minutes

With 20 cores and --jobs=4, initial system build is a half-day affair. After that, emerge --update @world weekly takes 15-60 minutes depending on what changed.

#Gotchas Specific to Your Setup

  1. Arrow Lake is bleeding edge -- Ensure kernel 6.8+ for full support. Gentoo-sources usually tracks latest stable quickly.

  2. Dual GPU Xorg -- You need /etc/X11/xorg.conf.d/10-gpu.conf just like on Arch. Copy your existing one.

  3. Intel xe vs i915 -- Arrow Lake is in the transition zone. Try i915 first (CONFIG_DRM_I915), fall back to xe if the iGPU monitor doesn't work.

  4. ZRAM -- Not automatic on Gentoo/OpenRC. Install sys-block/zram-init, configure in /etc/conf.d/zram-init.

  5. elogind + seatd -- Needed for non-root Xorg. emerge elogind, add to default runlevel.

  6. Plan 9 from User Space -- emerge dev-util/plan9port. Installs to /usr/lib/plan9 same as Arch.

  7. Fish as login shell -- After install: chsh -s /usr/bin/fish. May need to add to /etc/shells first.

  8. picom -- The picom in Gentoo repos may be the fork (FT-Labs) or original. Check which you need.

  9. gnome-keyring without GNOME -- Works fine, just emerge gnome-base/gnome-keyring and keep your .xprofile autostart.

  10. Conky + Lua -- Needs USE="lua" on conky, ensure LuaJIT is available.

#Why Gentoo Over Staying on Arch

Honest assessment for your use case:

Advantage Real Impact
USE flags Eliminate dependencies you don't want (no Qt, no GNOME libs, no Wayland)
Optimized binaries Measurable on CPU-bound tasks (compilation, grep over large codebases)
Rolling + stable You choose when to update, not forced by partial upgrades
Learning Deep understanding of every layer (aligns with your systems-hacker trajectory)
Control Nothing happens you didn't ask for
OpenRC Simpler init, readable service scripts
Disadvantage Real Impact
Compile time Weekly ~30 min maintenance, occasional multi-hour rebuilds
AUR equivalent weaker Overlays exist but aren't as vast as AUR
Breakage risk USE flag conflicts require manual resolution
Initial setup Full day minimum

For someone building a Plan 9 grid and pursuing deep systems knowledge, Gentoo is a natural stepping stone. You'll understand your Linux system at a level Arch doesn't require.