Gentoo rpi - hpaluch/hpaluch.github.io GitHub Wiki
Gentoo on Raspberry PI
My target: Raspberry PI 1.b
[!WARNING]
I did not deployed results on real hardware - so far only tested chroot using "QEMU User ARM" emulation.
There are actually 3 ways how to run and build Gentoo on Raspberry PI:
- Run builds natively on RPi
- Use chroot with qemu-user-arm (QEMU that will emulate ARM for running ELF binaries using binfmt-misc kernel support. It is similar approach as for legendary Nokia "scratchbox" (remains are on scratchbox.org). But not complete (scratchbox actually runs native cross gcc for amd64/i386 to get decent compiler speed).
- Crossdev package - crossbuilding ARM on amd64 Host machine to directory
under
/usr/ARM_ARCH_NAME
- fastest.
Variant 1 is theoretically most reliable but prohibitively slow and also today quite impossible because current compilers require excessive amount of memory (my RPi 1.b has only 512MB RAM - even reduced when GPU is used and 1 core at 700 MHz). So basically any C++ project with enabled LTO (Link time optimizations) will exhaust all memory. Without LTO it could be barely better (older compilers optimized code on single module boundary only so it was not that memory hungry as LTO). Also SD card with its very slow I/O speed will not help.
Variant 2 is moderately slow but convenient (because some packages have issues
with cross-building). But some sandboxes must be disabled in /etc/portage/make.conf
to make
qemu work properly. See
https://wiki.gentoo.org/wiki/Embedded_Handbook/General/Compiling_with_QEMU_user_chroot#Portage_configuration
Variant 3 is fastest (because compiler runs at native Host speeds) but most tricky - not all packages can be cross-build without issues (GNU Autoconf is very hostile to that - because it compiles and runs C program - where later is not possible on cross-compilation) - for example Glib with Introspection.
Setup
You should always start on https://wiki.gentoo.org/wiki/Raspberry_Pi/Installation to
find what ARM version you have. In my case (RPi 1.B) it is armv6j-unknown-linux-gnueabihf
.
(hf
means "hard-float" - that such ARM CPU has hardware support for floating-point math).
Originally I tried QEMU User Chroot setup
which is described
on:
- https://wiki.gentoo.org/wiki/Embedded_Handbook/General/Compiling_with_QEMU_user_chroot
- https://wiki.gentoo.org/wiki/Raspberry_Pi/Installation
But I found it very slow (configure script and/or Python is terribly slow under qemu-arm (user)).
So I'm now testing variant 3:
- following: https://wiki.gentoo.org/wiki/Crossdev
# running on amd 64 Host:
emerge --ask sys-devel/crossdev
emerge -an app-eselect/eselect-repository
# `crossdev` here is automatically selected as default cross-build repo:
eselect repository create crossdev
# command below will take lot of time
crossdev -S -t armv6j-unknown-linux-gnueabihf
# I already downloaded stage3 tarball:
tar xpvf /mnt/gentoo-rpi/stage3-armv6j_hardfp-openrc-20250312T233353Z.tar.xz -C /usr/armv6j-unknown-linux-gnueabihf --exclude=dev --skip-old-files
Basic benchmark - building app-editor/vim
:
- command:
armv6j-unknown-linux-gnueabihf-emerge -an app-editor/vim
- QEMU user chroot: 18 minutes (despite 5 parallel jobs, 6 host cores).
- crossdev: 1.5 minute (!)
Testing Cross-dev chroot:
- first you must copy QEMU user for
arm
in my case:# qemu-arm must be in same direcctory in chroot as in main system so binfmt-misc will work: cp /usr/bin/qemu-arm /usr/armv6j-unknown-linux-gnueabihf/usr/bin/qemu-arm
- small fix:
mkdir -p /usr/armv6j-unknown-linux-gnueabihf/dev
- script
/usr/armv6j-unknown-linux-gnueabihf/bind_mounts.sh
contains:#!/bin/bash set -xeuo pipefail cd $(dirname $0) for i in dev sys proc do [ -d "$i" ] || { echo "Fatal error: '$i' missing at `pwd`" >&2 exit 1 } mount -B /$i $i done exit 0
- script
/usr/armv6j-unknown-linux-gnueabihf/enter-chroot.sh
contains:#!/bin/bash set -xeuo pipefail cd $(dirname $0) chroot . /bin/bash exit 0
- and finally script
/usr/armv6j-unknown-linux-gnueabihf/init_shell.sh
containssource /etc/profile export PS1="(AZ CROSS-RPI) ${PS1}"
Usage:
- after boot once and only once run:
/usr/armv6j-unknown-linux-gnueabihf/bind_mounts.sh
- now every time you want to enter emulated ARM chroot, run:
/usr/armv6j-unknown-linux-gnueabihf/enter-chroot.sh
- inside chroot run:
source /init_shell.sh
- and try:
$ uname -m armv7l
- remember - to quickly crossbuild anything, run on Host (outside chroot!):
armv6j-unknown-linux-gnueabihf-emerge -an PACKAGE_NAME
Bugs
Need to also cross-build kernel!
armv6j-unknown-linux-gnueabihf-emerge -an app-misc/mc
* Unable to find kernel sources at /usr/armv6j-unknown-linux-gnueabihf/usr/src/linux
* Unable to calculate Linux Kernel version for build, attempting to use running version
* Unable to check for the following kernel config options due
* to absence of any configured kernel sources or compiled
* config:
* - INOTIFY_USER
* You're on your own to make sure they are set if needed.
* ERROR: dev-libs/glib-2.84.0::gentoo failed (configure phase):
* configure failed
Trying:
# On Host:
armv6j-unknown-linux-gnueabihf-emerge -an sys-kernel/raspberrypi-sources
# Now dirty trick!
cd /usr/armv6j-unknown-linux-gnueabihf/usr/src/linux-6.6.47_p20240902-raspberrypi
# creates config from template
CROSS_COMPILE=armv6j-unknown-linux-gnueabihf- ARCH=arm make bcmrpi_defconfig
# builds kernel
CROSS_COMPILE=armv6j-unknown-linux-gnueabihf- ARCH=arm make -j`nproc`
# still on Host - be carefull
CROSS_COMPILE=armv6j-unknown-linux-gnueabihf- ARCH=arm \
make install INSTALL_PATH=/usr/armv6j-unknown-linux-gnueabihf/boot \
INSTALL_MOD_PATH=/usr/armv6j-unknown-linux-gnueabihf
CROSS_COMPILE=armv6j-unknown-linux-gnueabihf- ARCH=arm \
make modules_install INSTALL_PATH=/usr/armv6j-unknown-linux-gnueabihf/boot \
INSTALL_MOD_PATH=/usr/armv6j-unknown-linux-gnueabihf
Under chroot create symlink:
# in chroot
$ eselect kernel list
vailable kernel symlink targets:
[1] linux-6.6.47_p20240902-raspberrypi
$ eselect kernel set 1
Trying again on host:
armv6j-unknown-linux-gnueabihf-emerge -an app-misc/mc
Errrr
ERROR: An exe_wrapper is needed for /usr/armv6j-unknown-linux-gnueabihf/tmp/portage/dev-libs/glib-2.84.0/work/gobject-in
trospection-1.82.0-build/tools/g-ir-compiler but was not found. Please define one in cross file and check the command an
d/or add it to PATH.
As workaround must disable introspection
(it is hostile to cross-builds) for glib:
USE=-introspection armv6j-unknown-linux-gnueabihf-emerge -an app-misc/mc
Yeah! That did the trick... Now you can try in chroot mc
command if it works.
FIXME
I should use QEMU exec wrapper to emulate armv6j
(as is on RPi 1b), because
default is armv7l
which may cause troubles.