Raspberry Pi/ARM64 in place installation
This page is based on https://cmpct.info/~sam/gentoo/arm64/PiGentoo64.html by User:Sam (CC-BY-SA 3.0)
We will bootstrap the Gentoo install from a stage3 provided by gentoo.org via RaspberryPi OS 64bit.
You do not need a Gentoo system already or to cross-compile. The instructions here are very similar for 32-bit Raspberry Pis too.
IRC
If you need help join #gentoo-arm on irc.libera.chat, ask your question and wait for at least 24h (see also: IRC). This guide was originally written by sam_ on libera.chat.
Notes about the installation
f2fs is used for the root filesystem in this document, you don’t have to. Ext4, btrfs and other filesystems should work, too. Please install the appropriate packages and customize the configuration.
The installation in this document was tested with RaspberryPi OS (former Raspbian) and bootstrapped from there. In theory, you could jump in from any arm64 system (read: kernel).
The terminal multiplexer app-misc/screen is handy to make it easy to do other things, like check sys-process/htop during setup & compilation.
Prerequisites
- Raspberry Pi 4B or 400 (should work with 3B/B+ too)
- An SD card with at least 32GB minimum is recommended. (Using a 16GB card may be possible when using e.g. rust-bin.)
- The latest RaspberryPi OS 64bit (former Raspbian) flashed onto the card
Nice-to-haves
- The biggest the SD card, the better; it’ll wear out slower;
- A fan and heatsinks (to reduce heat when compiling, prevent throttling);
- A high-quality power supply (prevent corruption, prevent throttling).
- A Linux machine sitting around to make tweaks if needed.
Useful links
- Raspberry_Pi_3_64_bit_Install
- https://github.com/sakaki-/gentoo-on-rpi-64bit
- For RPis with 4GB RAM or less: Knowledge_Base:Emerge_out_of_memory
Guide
Prepare
Flash with latest Raspbian 64bit (September 2019 at time of creation).
The 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. This enables sshd on the next boot:
root #
touch /boot/ssh
Setup WiFi if appropriate in Raspbian.
Boot
Verify that you are running 64bit by looking for aarch64 in uname -a:
user $
uname -a
Linux raspberrypi 4.19.75-v8+ #1270 SMP PREEMPT Tue Sep 24 18:59:17 BST 2019 aarch64 GNU/Linux
Update and reboot your system
To get the latest bootloader, kernel, etc.
user $
sudo apt update && sudo apt upgrade
user $
sudo reboot
Filesystem setup
Recommended filesystems for the root partition are ext4, btrfs or f2fs. f2fs is used as an example. Install sys-fs/f2fs-tools for mkfs.f2fs and resize.f2fs:
root #
emerge --ask sys-fs/f2fs-tools
Create an f2fs partition:
root #
mkfs.f2fs /dev/mmcblk0pX
(Raspberry Pi OS configured SSD cards have a gap at the start before the boot partition and FDisk will automatically create a partition there with its defaults. Prevent this by manually entering the start cylinder as at least one more than the end cylinder of the main 2Gb partition)
Mount the f2fs partition at /mnt/gentoo and cd there:
root #
mkdir /mnt/gentoo
root #
mount /dev/mmcblk0pX /mnt/gentoo
root #
cd /mnt/gentoo
Unmount /boot from Raspbian (so we can mount it in the chroot):
root #
umount /boot
Fetch the stage file
Fetch the stage3 (please check for a newer one on gentoo.org/downloads -> ARM64).
Preparations and chroot
Untar the stage file as usual:
root #
tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner
Start customising make.conf. Set MAKEOPTS="-jx" suitableAs a rule of thumb, MAKEOPTS jobs should be less than or equal to the minimum of the size of RAM/2GB or CPU thread count. for the system:
# 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.
Copy over some firmware for WiFi and Bluetooth from RaspberryPi OS:
root #
mkdir -p /mnt/gentoo/lib/firmware/
root #
cp -rv /lib/firmware/brcm/ /mnt/gentoo/lib/firmware/
Enter chroot as usual: Copy DNS settings first, then mount, then chroot:
root #
cp --dereference /etc/resolv.conf /mnt/gentoo/etc/resolv.conf
root #
mount --types proc /proc /mnt/gentoo/proc
root #
mount --rbind /sys /mnt/gentoo/sys
root #
mount --make-rslave /mnt/gentoo/sys
root #
mount --rbind /dev /mnt/gentoo/dev
root #
mount --make-rslave /mnt/gentoo/dev
root #
chroot /mnt/gentoo /bin/bash
root #
source /etc/profile
Build the (RPi, not upstream) kernel:
Prerequisites
Updating the system is likely needed to avoid e.g. bindist conflicts! You may be able to for now --exclude sys-devel/gcc though:
root #
emerge --sync
root #
emerge -a -uvDU @world
Fetch build requirements for the kernel:
root #
emerge -av dev-vcs/git
root #
emerge -av sys-devel/bc
Get the sources so e.g. emerge knows what kernel we're running:
root #
cd /opt
root #
git clone --depth 1 https://github.com/raspberrypi/linux.git
root #
ln -s /opt/linux /usr/src/linux
Configure and build the kernel
Generate base configs. For all 64bit configurations (including Pi 3, 3+, 4, and 400, as per upsream) this should be:
root #
make bcm2711_defconfig
Customise the kernel:
root #
make menuconfig
Modify arch/arm64/Makefile (optional, probably not very useful):
KBUILD_CFLAGS += -march=native
Start compiling, the time will differ:
root #
time make -j4 Image modules dtbs
real 66m55.242s user 234m46.421s sys 27m24.339s
Mount /boot inside the chroot this time:
root #
mount /dev/mmcblk0p1 /boot
Take a backup of the old kernel. kernel8 is for ARM64:
root #
mv /boot/kernel8.img /boot/kernel8.img.bak
Install modules and kernel:
root #
make modules_install dtbs_install
root #
cp arch/arm64/boot/Image /boot/kernel8.img
Optional: Compressing the kernel
On 64bit installations the kernel8.img may be a gzip compressed image with the same filename. The bootloader recognizes the gzip header [1].
root #
cd /boot
root #
gzip -9cf kernel8.img > kernel8.img
Tasks before reboot
Update world:
root #
emerge -a -uvDN @world
Create /etc/fstab:
proc /proc proc defaults 0 0
PARTUUID=XXXXXXXX-XX /boot vfat defaults 0 2
/dev/mmcblk0pX / 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/mmcblk0pX rootfstype=f2fs
Optional extras before reboot
Set up network and SSH
Needed for WiFi / network:
root #
emerge -av dhcpcd wpa_supplicant
Create wpa_supplicant.conf as appropriate (see Raspberry Pi docs).
Tell wpa_supplicant and sshd to start on boot:
root #
rc-update add wpa_supplicant default
root #
rc-update add sshd default
Setup the network scripts: Wpa_supplicant#Setup_for_Gentoo_net..2A_scripts
Create a user with sudo rights
Create a user, e.g. gentoo:
root #
useradd -m gentoo -G wheel,video,users,audio,usb
Set a password (optional):
root #
passwd gentoo
Add in an SSH key (optional):
root #
su gentoo
root #
mkdir ~/.ssh
Put your public ssh key in ~/.ssh/authorized_keys.
Install app-admin/sudo
root #
emerge --ask app-admin/sudo
Utilize the built-in random number generator and additional tools
Install sys-apps/rng-tools and configure the system to start the RNG at boot:
root #
emerge -av rng-tools
root #
mkdir /etc/modules-load.d/
root #
echo 'bcm2835-rng' > /etc/modules-load.d/random.conf
root #
rc-update add rngd
Emerge useful tools by running:
root #
emerge --ask app-portage/gentoolkit app-portage/eix sys-process/htop
Syncing time
Install net-misc/chrony:
root #
emerge --ask net-misc/chrony
Start chronyd on boot:
root #
rc-update add chronyd
Set up swclock to save last clock on shutdown and restore on boot:
root #
rc-update add swclock boot
Reboot and hope for the best!
Post-boot
Set CPU_FLAGS_ARM
Install, use and remove a tool for setting the CPU flags:
root #
emerge --oneshot -av cpuid2cpuflags
root #
mkdir /etc/portage/package.use
root #
echo "*/* $(cpuid2cpuflags)" > /etc/portage/package.use/00cpuflags
root #
emerge -c cpuid2cpuflags
Raspberry Pi specific utilities
Installing Raspberry Pi userland
It may be possible to use media-libs/raspberrypi-userland or media-libs/raspberrypi-userland-bin instead.
root #
emerge -av dev-util/cmake dev-vcs/git
root #
mkdir -p ~/git/build/ && cd ~/git/build
root #
git clone https://github.com/raspberrypi/userland
root #
cd userland
root #
./buildme
Now it's installed, we need to make it accessible
root #
echo 'export PATH="/opt/vc/bin:${PATH}"' >> ~/.bashrc
root #
echo '/opt/vc/lib' > /etc/ld.so.conf.d/06-rpi.conf
root #
. ~/.bashrc
Regenerate the dynamic loader (ld) cache
root #
env-update
Happily use vcgencmd and friends!
Update the firmware (Pi 4/Pi 400 only)
It should be possible to use dev-embedded/rpi-eeprom instead.
For convenience, add a dir to PATH. Only run this part the first time you update.
root #
mkdir ~/bin
root #
echo 'export PATH="$HOME/bin:${PATH}"' >> ~/.bashrc|. ~/.bashrc
Run git clone ... the first time, then run git pull in future to check for updates
Copy the firmware files to where tool wants:
root #
sudo mkdir -p /lib/firmware/raspberrypi/bootloader/
root #
sudo cp -rv firmware/* /lib/firmware/raspberrypi/bootloader
Copy vl805 to your bin:
root #
cp firmware/vl805 ~/bin
Run the actual update:
user $
sudo --preserve-env=PATH env ./rpi-eeprom-update
Install dosfsutils
fsck.vfat is needed for the boot partition. Install sys-fs/dosfsutils:
root #
emerge --ask sys-fs/dosfstools