Gentoo Linux on Raspberry Pi 4, Revisited
Published on
Information for installing Gentoo on the Pi 4 device is scattered here and there in the Gentoo wiki. Two main sources were used as reference during the installation.
- Raspberry Pi 3 64 Bit Install, which includes the full installation process, but is for Pi 3 instead of Pi 4 (they’re quite similar, anyways).
- Raspberry Pi 4 64 Bit Install, which includes only the Pi4-specific bits.
- Official kernel building guide from the Raspberry Pi Foundation.
The installation was done from Void Linux, but should work on other distros as well. Get the necessary files first.
$ git clone -b stable --depth 1 https://github.com/raspberrypi/firmware
$ git clone -b rpi-5.10.y --depth 1 https://github.com/raspberrypi/linux
Kernel
We’re going to compile the kernel with a cross-compile toolchain. On Void the cross-aarch64-linux-gnu
package from XBPS would suffice. The CROSS_COMPILE
environment variable in the following commands would depend on the host distribution we’re building the kernel from, and may need changes.
Inside the linux
directory, load the default vendor configuration first.
$ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make bcm2711_defconfig
One config entry that’s recommended to be tweaked is CPU_FREQ_DEFAULT_GOV
, which defaults to staying on the lowest possible frequency pernamently. Fire up make nconfig
, search for it, and set the value to ondemand
instead. Now compile the kernel.
$ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make "-j$(nproc)"
Partition and FS
Use your favorite tool (I recommend cfdisk
or fdisk
) to partition the SD card. The first partition should be bootable vfat primary partition. An example output of fdisk
looks like this.
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 * 2048 526335 524288 256M b W95 FAT32 /dev/mmcblk0p2 526336 125042687 124516352 59.4G 83 Linux
Format the first partition as FAT32 (don’t forget that -F 32
!).
$ sudo mkfs.vfat -F 32 /dev/mmcblk0p1
As for the rootfs, originally I thought using F2FS may be a great idea since it’s specifically designed for flash memory-based devices including SD cards. However, it seems that F2FS doesn’t handle power outages well, so eventually I still went for the classical ext4. Both journaling and CRC32C metadata checksuming are enabled here to make it more robust against corruptions. -i 8192
to create an inode for every two 4KB blocks.
$ sudo mkfs.ext4 -i 8192 -O has_journal,metadata_csum /dev/mmcblk0p2
Installation
Now mount both the rootfs and boot partition. I’ll call them /mnt/rpigentoo
and /mnt/rpigentoo/boot
. Download stage3 tarball as usual and then unpack it inside the rootfs.
$ links 'https://www.gentoo.org/downloads/mirrors/'
$ # Choose a mirror, navigate to latest stage3-arm64 tarball, press `d` and wait
$ sudo tar xpvf stage3-*.tar.xz \
--xattrs-include='*.*' --numeric-owner \
-C /mnt/rpigentoo
Install the Portage tree.
$ curl -LO 'http://distfiles.gentoo.org/snapshots/portage-latest.tar.bz2'
$ tar xvpf portage-latest.tar.bz2 --strip-components=1 \
-C /mnt/rpigentoo/var/db/repos/gentoo
Install the kernel. All kernel images present before installtion should be removed beforehand to ensure that the device actually boot with kernel8.img
. The firmware will happily load the 32-bit kernel7.img
by default, so this is necessary.
$ sudo rm /mnt/rpigentoo/boot/kernel*.img
$ sudo cp arch/arm64/boot/Image /mnt/rpigentoo/boot/kernel8.img
Install the firmware. Copy content of /boot/
from the firmware repository directly.
$ sudo cp -rv firmware/boot/* /mnt/rpigentoo/boot/
Install the device tree.
$ sudo cp -v arch/arm64/boot/dts/broadcom/bcm2711-rpi-4-b.dtb \
/mnt/rpigentoo/boot/
The Gentoo wiki suggests to also install fresh copy of device tree overlays from the kernel repository, while the firmware we’ve just installed already include them. Their SHA1 digests seem to be identical, so this step was skipped.
Configurations before Boot
Of course we need /mnt/rpigentoo/etc/fstab
.
/dev/mmcblk0p1 /boot vfat noauto,noatime 1 2 /dev/mmcblk0p2 / ext4 defaults,noatime 0 1
text
And for the Pi to boot properly we need cmdline.txt
and config.txt
.
# cmdline.txt
root=/dev/mmcblk0p2 rootfstype=ext4 console=tty1 fsck.repair=yes rootwait
# config.txt
disable_overscan=1
hdmi_drive=2
Additional: Get Online
Ethernet
For ethernet, no additional firmware is needed, but unfortunately the conventional
dhcpcd
isn’t present in the stage 3 tarball. Busybox comes to the rescue.$ busybox udhcpc -i eth0
One may be tempted to install dhcpcd at this point, but
emerge
exploded with some crypticTypeError: 'NoneType' object is not iterable
messages. It turned out to be triggered by wrong system datetime, since the Pi lacks an RTC. Usedate --set yyyy-mm-dd
to manually adjust datetime and it worked.WiFi
Additional firmware needed. The firmware files resides in the
sys-firmware/raspberrypi-wifi-ucode
package, but some files inside it conflicts withkernel/linux-firmware
. The Gentoo Wiki suggests to(Re-)emerge
linux-firmware
withsavedconfig
USE flag set.Comment out several broadcom-related files from
/etc/portage/savedconfig/sys-kernel/linux-firmware-*
.$ for name in brcmfmac43430 brcmfmac43436 brcmfmac43455 brcmfmac43456 \ \ do -i '/www/ s/^#*/#/' "$name" \ sed done
Re-emerge
linux-firmware
.Finally emerge
raspberr-wifi-ucode
After a reboot
wlan0
shows up inip -a
output.