Raspberry Pi/ARM64 in place installation

From Gentoo Wiki
Jump to:navigation Jump to:search

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.


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.


  • 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


  • 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



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

FILE /boot/cmdline.txt

Edit config.txt and tell the bootloader to use the 64 bit kernel (kernel8.img).

FILE /boot/config.txt

Place a file in /boot called ssh. This enables sshd on the next boot:

root #touch /boot/ssh

Setup WiFi if appropriate in Raspbian.


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

(The author had to create a partition inbetween the main ext4 one and the f2fs one to get the right size and couldn’t figure out why at the time.)

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:

FILE /mnt/gentoo/etc/portage/make.conf
# Different to default
COMMON_FLAGS="-O2 -pipe -march=native"
# Default

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:


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 #ln -s /opt/linux /usr/src/linux

Configure and build the kernel

Generate base configs for a Pi 4, Broadcom bcm2711:

root #make bcm2711_defconfig

Customise the kernel:

root #make menuconfig

Modify arch/arm64/Makefile (optional, probably not very useful):

FILE /usr/src/linux/arch/arm64/Makefile
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 #scripts/mkknlimg 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:

FILE /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:

FILE /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!



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
root #emerge -av dev-util/cmake dev-vcs/git
root #mkdir -p ~/git/build/ && cd ~/git/build
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
root #. ~/.bashrc

Run git clone ... the first time, then run git pull in future to check for updates

root #cd ~/git/build
root #cd rpi-eeprom

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