Content is under CC-BY-SA 3.0.
This is a guide to setting up Gentoo (arm64) on a Raspberry Pi 4.
We will bootstrap the Gentoo install from a stage3 provided by gentoo.org, via Raspbian.
You do not need a Gentoo system already or to cross-compile.
sam_
on libera.chatarm64
system (read: kernel).screen
to make it easy to do other things, like check htop
during setup & compilation.Prep:
Flash with latest Raspbian (September 2019 here)
Easiest way to avoid filesystem mess is to modify cmdline.txt
to change init=/usr/lib/raspi-config/init_resize.sh
to init=/sbin/init
.
Edit config.txt
and tell the bootloader to use the 64 bit kernel (kernel8.img
). arm_64bit=1
Place a file in /boot
called ssh
, e.g. touch /boot/ssh
. This enables sshd
on the next boot.
Setup WiFi if appropriate.
Boot. Verify that you’re running 64bit by looking for aarch64
in uname -a
, e.g.
$ uname -a
Linux raspberrypi 4.19.75-v8+ #1270 SMP PREEMPT Tue Sep 24 18:59:17 BST 2019 aarch64 GNU/Linux
sudo apt update && sudo apt upgrade
to get the latest bootloader, kernel, etc.
Reboot.
Filesystem setup (I’m using f2fs for the Gentoo partition)
Install f2fs-tools
for mkfs.f2fs
and resize.f2fs
;
Create an f2fs partition. I had to create a partition inbetween the main ext4 one and my f2fs one to get the right size. Couldn’t figure out why at the time.
Mount it at /mnt/gentoo
and cd
there..
Unmount /boot
from Raspbian (so we can mount it in the chroot): umount /boot
Fetch the stage3:
wget https://gentoo.osuosl.org/releases/arm64/autobuilds/current-stage3-arm64/stage3-arm64-20210905T230622Z.tar.xz -O /mnt/gentoo/
tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner
Start customising make.conf
, set these:
# Different to default
COMMON_FLAGS="-O2 -pipe -march=native"
MAKEOPTS="-j4"
# Default
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"
FCFLAGS="${COMMON_FLAGS}"
FFLAGS="${COMMON_FLAGS}"
Note that you can set -march etc appropriately to use distcc, but still get the benefits.
Enter chroot as usual (copy DNS settings first, then mount, then chroot):
# Copy over some firmware for WiFi and Bluetooth from Raspbian
mkdir /mnt/gentoo/lib/firmware/
cp -rv /lib/firmware/brcm/ /mnt/gentoo/lib/firmware/
# Standard Gentoo chroot setup
cp --dereference /etc/resolv.conf /mnt/gentoo/etc/resolv.conf
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
chroot /mnt/gentoo /bin/bash
source /etc/profile
export PS1="(chroot) ${PS1}"
Sync emerge
so we can install packages: emerge --sync
Build the (RPi, not upstream) kernel:
Prerequisites:
emerge -a -uvDU @world
is likely needed to avoid e.g. bindist conflicts! You may be able to for now --exclude gcc though.emerge -av dev-vcs/git
to fetch the sources.emerge -av sys-devel/bc
for the kernel (build requirement)Get the sources:
cd /opt
git clone --depth 1 https://github.com/raspberrypi/linux.git
# so e.g. emerge knows what kernel we're running
ln -s /opt/linux /usr/src/linux
Configure:
# Generate base configs
# Pi 4: bcm2711
make bcm2711_defconfig
# menuconfig to customise
make menuconfig
Modify arch/arm64/Makefile
(optional, probably not very useful):
KBUILD_CFLAGS += -march=native
Start compiling:
time make -j4 Image modules dtbs
For me, this took:
real 66m55.242s
user 234m46.421s
sys 27m24.339s
… but I was quite generous with the modules I chose to compile in for fun, e.g. KVM.
Mount /boot
inside the chroot this time:
mount /dev/mmcblk0p1 /boot
Take a backup of the old kernel, just in case:
# kernel8 is for arm64
mv /boot/kernel8.img /boot/kernel8.img.bak
Install modules, etc:
make modules_install dtbs_install
scripts/mkknlimg arch/arm64/boot/Image /boot/kernel8.img
Tasks before reboot:
emerge -a -uvDN @world
Create /etc/fstab
:
proc /proc proc defaults 0 0
PARTUUID=6c586e13-01 /boot vfat defaults 0 2
/dev/mmcblk0p4 / f2fs defaults,noatime 0 1
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that
Modify two parameters (root, rootfstype) in /boot/cmdline.txt
:
root=/dev/mmcblk0p4 rootfstype=f2fs
Optional extras before reboot:
Set up network and SSH
# Needed for WiFi / network
emerge -av dhcpcd wpa_supplicant
# Create wpa_supplicant.conf as appropriate
# https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md
# Tell wpa_supplicant, sshd to start on boot
rc-update add wpa_supplicant default
rc-update add sshd default
# Setup the network scripts
# https://wiki.gentoo.org/wiki/Wpa_supplicant#Setup_for_Gentoo_net..2A_scripts
Create a user with sudo rights
# Create a user
useradd -m gentoo -G wheel,video,users,audio,usb
# Set a password (optional)
passwd gentoo
# Add in an SSH key (optional)
su gentoo
mkdir ~/.ssh
# Put your public ssh key in ~/.ssh/authorized_keys
# Install sudo
emerge -av sudo
rng-tools
to use the built-in RNG:
emerge -av rng-tools
mkdir /etc/modules-load.d/
echo 'bcm2835-rng' > /etc/modules-load.d/random.conf
rc-update add rngd
# Useful tools like equery, eix (optional)
emerge -av gentoolkit eix htop
# Time sync
emerge -av openntpd
# Start on boot
rc-update add ntpd
# Set up swclock to save last clock on shutdown, restore on boot
rc-update add swclock boot
Reboot and hope for the best!
Post-boot:
If your time is wrong, force a manual sync:
# Stop running ntpd
/etc/init.d/ntpd stop
# Manual sync
ntpd -s -d
# Wait a few seconds for it to sync
# Then CTRL-C (quit)
# Run date to check time is now accurate
date
# Start up ntpd again
/etc/init.d/ntpd start
Set CPU_FLAGS_ARM
:
emerge -av cpuid2cpuflags
mkdir /etc/portage/package.use
echo "*/* $(cpuid2cpuflags)" > /etc/portage/package.use/00cpuflags
emerge -c cpuid2cpuflags
Raspberry Pi specific utilities:
Installing Raspberry Pi userland:
emerge -av cmake git
mkdir -p ~/git/build/ && cd ~/git/build
git clone https://github.com/raspberrypi/userland
cd userland
./buildme
# Now it's installed, we need to make it accessible
echo 'export PATH="/opt/vc/bin:${PATH}"' >> ~/.bashrc
echo '/opt/vc/lib' > /etc/ld.so.conf.d/06-rpi.conf
. ~/.bashrc
# Regenerate ld cache
sudo env-update
# Happily use vcgencmd and friends!
Update the firmware (Pi 4):
# For convenience, add a dir to PATH
# Only run this part the first time you update
mkdir ~/bin
echo 'export PATH="$HOME/bin:${PATH}"' >> ~/.bashrc
. ~/.bashrc
cd ~/git/build
# Run `git clone ...` the first time
# Run `git pull` in future to check for updates
git clone https://github.com/raspberrypi/rpi-eeprom
cd rpi-eeprom
# Copy the firmware files to where tool wants
sudo mkdir /lib/firmware/raspberrypi/bootloader/
sudo cp -rv firmware/* /lib/firmware/raspberrypi/bootloader
# Copy vl805 to your bin
cp firmware/vl805 ~/bin
# Run the actual update
sudo --preserve-env=PATH env ./rpi-eeprom-update
Install dosfsutils
for vfat fsck:
emerge -av sys-fs/dosfstools