Raspberry Pi

From Gentoo Wiki
Jump to: navigation, search
Chithanh 's Raspberry Pi 1 running Gentoo
Note
Since the Raspberry Pi hardware and setup process has not changed much over the years, this article supports both the Rpi 1 and the Rpi 2. The Rpi3 is supported in 32-bit mode via the Rpi 2 process, while Rpi3 in 64-bit mode has issues and remains unstable and is not recommended.

This document describes how to install Gentoo on the Raspberry Pi 1, 2 and 3.

The Raspberry Pi is series of single-board computers based on ARM devices. Raspberry Pi 1 is based on BCM2835 SoC and features a single core CPU (ARMv6), with 512 MB RAM. Earlier models had 256 MB RAM.

Raspberry Pi 2 is based on BCM2836 SoC and features a quad-core CPU (ARMv7) and 1 GB RAM. The model 1 uses an SD card for storage but the model 2 uses a microSD. All versions have a VideoCore IV GPU.

Raspberry Pi 3 B is based on BCM2837 SoC. According to #gentoo-arm, although the ARMv8 CPU in the Raspberry Pi 3 B is 64-bit, almost everything else is 32-bit, and therefore only 32-bit kernels are supplied from upstream for the machine.[1] To boot a 64-bit kernel, it is necessary to add the arm_control=0x200 parameters to the boot loader.[2] This is to enable 64-bit mode for the processor. The disable_commandline_tags=1 kernel boot argument is also needed, otherwise "the boot loader will otherwise overwrite the code (without -O2) at 0x100 with ATAGS[3]. Therefore, for the Raspberry Pi 3 B, those who want to build a 32-bit kernel, simply walk through the Raspberry Pi 2 options listed below. Those who want to try to build a 64-bit kernel will need the mainline Linux kernel. Be aware there are very few people who are able to provide assistance for 64-bit attempts. Proceeding down the 64-bit path may enter a world of pain.[4] Many things (such as Firefox[5]) may not work at all. Other things have issues but function (wifi)[6][7]. Be sure to remember to add the boot arguments!

Installation

Partitioning

The SD card must be properly prepared before installing Gentoo. Before partitioning, check to see if the SD card is listed as compatible in this list.

Create at least two partitions on the SD card. The /boot partition should be FAT32. The root (/ partition can be any preferred Linux filesystem, however since SD cards are flash-based media, there are many benefits to using F2FS.

Disk /dev/sdb: 16.6 GB, 16574840832 bytes
255 heads, 63 sectors/track, 2015 cylinders, total 32372736 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x1db42224

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *        2048      835379      416666    c  W95 FAT32 (LBA)
/dev/sdb2          835380    31889024    15526822+  83  Linux
/dev/sdb3        31889025    32372735      241855+   5  Extended
/dev/sdb5        31889088    32372735      241824   82  Linux swap / Solaris

For optimal compatibility, 255H/63S geometry is recommended.

Note
SD cards are very different from rotational devices. So it is non-trivial to achieve best I/O-performance. See example [1] to start understanding the difficulties. Also, be aware that there are a lot of contradicting advice regarding partitioning and suitable filesystems for SD cards.

Boot partition

The minimum setup for a correct /boot partition requires the following proprietary firmware files, provided by the Raspberry Pi foundation:

  • bootcode.bin
  • fixup.dat
  • start.elf

To boot the Raspberry Pi with gpu_mem=16 setting in config.txt, following files are required:

  • fixup_cd.dat
  • start_cd.elf

Create a file called cmdline.txt to specify any necessary kernel parameters. For example:

FILE /mnt/raspberrypiroot/boot/cmdline.txt
root=/dev/mmcblk0p2 rootdelay=2

The proprietary firmware files are just an emerge away:

root #emerge --ask sys-boot/raspberrypi-firmware
Note
The firmware files are installed in /boot. The boot partition of the SD card should be mounted on /boot before emerging the sys-boot/raspberrypi-firmware package.

Stage 3

Download appropriate Stage 3 tarball.

For Raspberry Pi A, A+, B, B+:

For the Raspberry Pi 2 or a Raspberry Pi 3 running in 32-bit mode (recommended):

For the Raspberry Pi 3 running in 64-bit mode (experimental, unstable, and not recommended):

root #wget http://distfiles.gentoo.org/experimental/arm64/stage3-arm64-YYYYMMDD.tar.bz2

Extract the root filesystem to SD card:

For the Raspberry Pi A, A+, B, B+:

root #tar xpjf stage3-armv6j_hardfp-YYYYMMDD.tar.bz2 -C /mnt/raspberrypiroot/

For the Raspberry Pi 2 or Raspberry Pi 3 running in 32-bit mode (recommended):

root #tar xpjf stage3-armv7a_hardfp-YYYYMMDD.tar.bz2 -C /mnt/raspberrypiroot/

For the Raspberry Pi 3 running in 64-bit mode (experimental, unstable, and not recommended):

root #tar xpjf stage3-arm64-YYYYMMDD.tar.bz2 -C /mnt/raspberrypiroot/

Adjust the make.conf file:

FILE /mnt/raspberrypiroot/etc/portage/make.conf
# Raspberry Pi A, A+, B, B+:
CFLAGS="-O2 -march=armv6j -mfpu=vfp -mfloat-abi=hard"
CXXFLAGS="${CFLAGS}"

# Raspberry Pi 2, or Raspberry Pi 3 running in 32 bit mode (recommended):
CFLAGS="-O2 -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard"
CXXFLAGS="${CFLAGS}"

# Raspberry Pi 3 running in 64 bit mode (experimental / unstable / not recommended):
CFLAGS="-march=armv8-a+crc -mtune=cortex-a53 -ftree-vectorize -O2 -pipe -fomit-frame-pointer"
CXXFLAGS="${CFLAGS}"

Do not forget to adjust the fstab file. The SD card is recognized as /dev/mmcblk0).

Generate the root password hash:

root #openssl passwd -1

Add the hash to the /etc/shadow file.

Stage 4

There is also an option of a self-booting Gentoo tarball (Stage 4), it can be downloaded from here. Please note this image appears to be outdated and unmaintained

NOOBS image. The NOOBS image will be created on a daily basis. I'd be pleased to get feedback...

NOOBS images can be downloaded from here: https://github.com/raspberrypi/noobs, then untar the NOOBS image from above in the OS directory (/os/Gentoo).

Portage tree

Download the latest Portage tree:

Ensure there are enough inode blocks free on the root partition. Portage takes up approximately 181K inodes.

root #df -ih | grep -E 'Mounted|mmc'

Extract Portage to the SD card:

root #tar xjvpf portage-latest.tar.bz2 -C /mnt/raspberrypiroot/usr

Cross compiling

To aid the Raspberry Pi's low power processor and hasten the Gentoo installation process, adding another machine to help the Rpi with compile jobs is preferred. Gentoo developers have created a cross compiling tool called crossdev in order to assist with toolchain generation. Once the toolchain is generated on a stronger machine, the stronger can help with complication tasks, which saves much time.

crossdev

First, install Layman. Please visit the article if instructions are needed.

Add the crossdev overlay:

root #layman -L && layman -a crossdev

Install the sys-devel/crossdev wrapper scripts:

root #emerge --ask sys-devel/crossdev

Create the cross toolchain for ARM, specifying the correct CPU architecture for the device as follows.

Note
The -S option can be omitted for those who wish to run an unstable or absolute bleeding-edge latest system.

For the Raspberry Pi A, A+, B, B+:

root #crossdev -S -v -t armv6j-hardfloat-linux-gnueabi

For the Raspberry Pi 2 or Raspberry Pi 3 B in 32-bit mode (recommended):

root #crossdev -S -v -t armv7a-hardfloat-linux-gnueabi

For the Raspberry Pi 3 B in 64-bit mode:

root #crossdev -S -v -t aarch64-unknown-linux-gnu --genv 'USE="cxx multilib fortran -mudflap nls openmp -sanitize"'
root #cd /usr/aarch64-unknown-linux-gnu/etc/portage && rm make.profile && ln -s /usr/portage/profiles/default/linux/arm64/13.0/desktop make.profile
Note
This will ensure a compile even if the host system is hardened, ie. defaults to sanitize (which does not yet work on arm64 architecture). A multilib profile may need toggled.

If there are any errors or Portage warnings here, please fix them. It will take a while for the cross toolchain to be successfully built. Go grab a coffee!

Kernel and modules

Download kernel sources for Raspberry Pi from GitHub [2]

root #emerge --ask sys-kernel/raspberrypi-sources

Alternatively, to get the 'bleeding edge' Raspberry Pi kernel sources:

root #git clone --depth 1 git://github.com/raspberrypi/linux.git
Note
For Raspberry Pi 3 B in 64-bit mode, things are unfinished. See for example this patch set or this kernel tree. Wifi now reportedly works but has issues.

Manual compilation

Configure and install kernel manually:

For the Raspberry Pi A, A+, B, B+:

root #make ARCH=arm bcmrpi_defconfig
root #make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- oldconfig
root #make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- -j$(nproc)
root #make ARCH=arm CROSS_COMPILE=armv6j-hardfloat-linux-gnueabi- modules_install INSTALL_MOD_PATH=/mnt/raspberrypiroot/

For the Raspberry Pi 2 or Raspberry Pi 3 B in 32-bit mode (recommended):

root #make ARCH=arm bcm2709_defconfig
root #make ARCH=arm CROSS_COMPILE=armv7a-hardfloat-linux-gnueabi- oldconfig
root #make ARCH=arm CROSS_COMPILE=armv7a-hardfloat-linux-gnueabi- -j$(nproc)
root #make ARCH=arm CROSS_COMPILE=armv7a-hardfloat-linux-gnueabi- modules_install INSTALL_MOD_PATH=/mnt/raspberrypiroot/

genkernel

genkernel can be used to cross-compile the kernel for Raspberry Pi. With genkernel all the preferences can be saved in genkernel.conf file for later use. The values of these variables need to be changed in /etc/genkernel-rpi.conf:

FILE /etc/genkernel-rpi.conf
# install kernel manually
INSTALL="no"

# Set arch to arm
ARCH_OVERRIDE="arm"

# No need to mount BOOTDIR and make symlink as the kernel is
# installed manually
MOUNTBOOT="no"
SYMLINK="no"

# Adjust this as needed for the machine.
MAKEOPTS="-j3"

# For Raspberry Pi A, A+, B, B+
UTILS_CROSS_COMPILE="armv6j-hardfloat-linux-gnueabi-"
KERNEL_CROSS_COMPILE="armv6j-hardfloat-linux-gnueabi-"

# For Raspberry Pi 2, or Raspberry Pi 3 B in 32-bit mode (recommended)
UTILS_CROSS_COMPILE="armv7a-hardfloat-linux-gnueabi-"
KERNEL_CROSS_COMPILE="armv7a-hardfloat-linux-gnueabi-"

# Change this to the path of raspberrypi linux kernel sources.
# It is possible to make this a symlink pointing to the
# /usr/src/linux-rpi like it's done with a normal kernel.
# For example: ln -s /usr/src/linux-3.6.11-raspberrypi /usr/src/linux-rpi
DEFAULT_KERNEL_SOURCE="/usr/src/linux-rpi"

# Point this variable to the directory where the SD card is mounted.
# Note that the location needs to be mounted manually before running genkernel.
INSTALL_MOD_PATH="/mnt/raspberrypiroot"

After saving the configuration file (for example to /etc/genkernel-rpi.conf), mount the RaspberryPi SD card to the INSTALL_MOD_PATH configured above. Assuming the Raspberry Pi root partition device is /dev/sdd3, run:

root #mount /dev/sdd3 /mnt/raspberrypiroot

Now execute genkernel. For the Raspberry Pi A, A+, B, B+:

root #ARCH=arm genkernel --config=/etc/genkernel-rpi.conf --kernel-config=/usr/src/linux-rpi/arch/arm/configs/bcmrpi_defconfig kernel

For the Raspberry Pi 2 or Raspberry Pi 3 B in 32-bit mode (recommended):

root #ARCH=arm genkernel --config=/etc/genkernel-rpi2.conf --kernel-config=/usr/src/linux-rpi/arch/arm/configs/bcm2709_defconfig kernel

Save the above command to the custom script:

FILE /usr/local/bin/genkernel-rpi.sh
#!/bin/sh
ARCH=arm genkernel --config=/etc/genkernel-rpi2.conf --kernel-config=/usr/src/linux-rpi/arch/arm/configs/bcm2709_defconfig kernel
root #chmod +x /usr/local/bin/genkernel-rpi.sh

Now simply create kernel for the Raspberry Pi by executing:

root #genkernel-rpi.sh

Installing kernel image

For Raspberry Pi A, B, B+ (not 2 B!) create a kernel.img file by:

root #emerge --ask sys-boot/raspberrypi-mkimage
root #imagetool-uncompressed.py arch/arm/boot/Image /mnt/raspberrypiroot/boot/kernel.img

or using the Raspberry Pi mkimage tool from GitHub:

root #chmod a+x imagetool-uncompressed.py
root #./imagetool-uncompressed.py arch/arm/boot/Image
root #cp kernel.img /mnt/raspberrypiroot/boot/

Raspberry Pi 2 B just copy arch/arm/boot/zImage to /boot/kernel7.img:

root #cp arch/arm/boot/zImage /mnt/raspberrypiroot/boot/kernel7.img

It may be necessary to copy updated dtb files into the boot partition:

root #cp arch/arm/boot/dts/*.dtb /mnt/raspberrypiroot/boot/
root #cp arch/arm/boot/dts/overlays/*.dtb* /mnt/raspberrypiroot/boot/overlays/
root #cp arch/arm/boot/dts/overlays/README /mnt/raspberrypiroot/boot/overlays/
Note
Copying the dtb files was necessary for me to get the official Raspberry Pi 7" touchscreen (input device) working.

That's it!

Tips and tricks

  • Storage is rather slow, even with the couple of compatible SDHC class 10 cards. If emerge will be running on the Raspberry Pi, putting /usr/portage on squashfs will speed up things dramatically.
  • There is no hardware RTC on the Raspberry Pi. Use the ntp-client service to set the correct system time on boot. A fallback incremental clock can be archived by the swclock service (replaces the hwclock service).
  • If more RAM is required for Linux, set the option gpu_mem in config.txt. The smallest amount that can be set is 16 MB, default is 64 MB [3]
  • More recent, unofficial kernel releases for the Raspberry Pi might be found at Chris Boot's repository: [4]
  • Be sure to test the performance - if the numbers don't match up (for instance in the LINPACK benchmark), something is very wrong.
  • For instructions on how to build binary packages for the Raspberry Pi on an Android phone see this blog post: [5]
  • If it is not possible to create a working ARM cross-toolchain, a precompiled kernel image is available from the firmware repository. The boot/kernel.img needs to be places in the boot partition and the contents of the modules directory copied to /lib/modules/ on the SD card.
  • Put the root-fs on a NFS share and put only the kernel image on SD card (PXE boot client).

Troubleshooting

  • Problem: dmesg is full of smsc95xx 1-1.1:1.0: eth0: kevent 2 may have been dropped and/or page allocation failure messages:
    • Solution: Try to update all firmware files in /boot, especially fixup.dat.
    • Solution: If the former fails, add smsc95xx.turbo_mode=N to kernel parameters, or vm.min_free_kbytes=4096 to /etc/sysctl.conf
  • Problem: The following error shows up when running the command:
    root #crossdev -S -v -t armv6j-hardfloat-linux-gnueabi
    (...) configure: error: cannot compute suffix of object files: cannot compile (...)
    • Solution: Try the following command instead[8]:
      root #CFLAGS="-O2 -pipe -march=armv6j -mfpu=vfp -mfloat-abi=hard" crossdev --stage3 -S -v -t armv6j-hardfloat-linux-gnueabi
  • Problem: On-board audio is inaccessible / non-functional.
    • Solution: Ensure that your /boot/config.txt contains the line dtparam=audio=on, then reboot. Ensure that the PCM channel is unmuted.

See also

External resources

Books

References