This is Gentoo's testing wiki. It is a non-operational environment and its textual content is outdated.
Please visit our production wiki at https://wiki.gentoo.org
Gentoo Raspberry Pi 3 Model B 64-bit Installation: Jon Wilder
Preparing The Disks
Prior to installing Gentoo on a Raspberry Pi 3 Model B, the SD card must be prepared first. We can use either fdisk or Parted to accomplish this. But before we go into that, we must first figure out what the SD card identifies as on your Gentoo system. We can do this using lsblk -
root #
lsblk
If your SD card still has NOOBS installed on it, the output from lsblk should look something like this -
In this example, this Gentoo host system uses /dev/sda as the Gentoo host system block device. /dev/sdb is the NOOBS SD card. We'll use that for our example throughout this article.
If you're using a brand new pre-formatted SD card, the output from lsblk would look like this -
For our partition table, our boot partition must be a primary partition and it must be a FAT32 partition for the Raspberry Pi to boot. For the swap and root partitions, we can use standard Linux formats. Optionally, we can create an extended partition and make the swap and root partitions as logical partitions if we wish. For this installation example, all partitions will be primary partitions.
fdisk
root #
fdisk -w always /dev/sdb
The -w always switch will wipe all signatures as we create partitions. Once fdisk starts, pass the 'p' option to see the partitions currently present on the SD card.
First we will pass the o command to create a new MS-DOS disk label. This will delete all partitions currently in the table.
'"`UNIQ--pre-00000009-QINU`"'
As you can see, the o command created our new DOS disklabel and deleted all partitions.
Next, we're going to make the boot partition. First, we'll use the 'n' command to make a new partition. Then, press enter for the following three prompts. This gives you the default options of -
p - Primary Partition
Partition number 1
First sector at 2048
For the last sector, we'll set it at +128M. This gives us a boot partition size of 128MiB.
Then, we'll use the 't' command to change the partition type. Select hex code 'c' to change it to a 'W95 FAT32 (LBA)' partition type. Finally, use the 'a' command to toggle on the bootable flag on partition 1.
Using the 'P' command, print the partition table to verify that the boot partition has been made correctly -
As we can see, we have created a bootable partition starting at sector 2048 that is 128MiB in size and is a FAT32 partition type.
Next, we'll create the swap partition. Pass the 'n' command again to create a new partition. Again, we'll press enter for the next 3 prompts to get the following default options -
p - Primary Partition
Partition number 2
First sector at sector 264192
Then we will set a swap size of 2GiB by passing +2G for the last sector/size. Finally, once the second partition is created, we'll use the 't' command to change the partition type, and select hex code 82 to change our partition type to 'Linux swap / Solaris'.
Now print your partition table using the 'p' command and it should look like this -
Now for the root partition. Use the 'n' command for a new partition. Then press Enter 3 more times to go with all default options. This will set us up with a primary partition on partition 3 with the rest of the available space as the root partition.
And finally, print the partition table once more and your table should look like this -
If your partition table looks like the above, pass the 'w' command to write the table to the SD card and exit fdisk.
If all is good, skip down to Create Filesystems.
Create Partitions Using Parted
Alternatively, we can also use Parted to prepare our SD card. Let's set up for optimal alignment using the -a optimal command line option. Once on the Parted command line, type 'print' to see the current partition layout:
root #
parted -a optimal /dev/sdb
GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: Mass Storage Device (scsi)
Disk /dev/sdb: 15.9GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 4194kB 15.9GB 15.9GB primary fat32 lba
(parted)
Create Filesystems
Now that our new partition table has been created, it's time to format the partitions with our file systems. We will be formatting the boot partition with FAT32 and the root partition EXT4. Finally, we will also initialize the swap partition.
Create the FAT32 boot filesystem.
root #
mkfs.vfat -F 32 /dev/sdb1
mkfs.fat 4.1 (2017-01-24)
Create the ext4 root filesystem. If you get the "/dev/sdb3 contains `gzip compressed data, max compression, from Unix' data Proceed anyway? (y,N)", hit 'y' and press enter.
root #
mkfs.ext4 -i 8192 /dev/sdb3
mke2fs 1.43.4 (31-Jan-2017)
/dev/sdb3 contains `gzip compressed data, max compression, from Unix' data
Proceed anyway? (y,N) y
Creating filesystem with 7234432 4k blocks and 3617328 inodes
Filesystem UUID: c229e329-f512-4e07-a7d9-b5e1f62f33a7
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
Finally, initialize the swap partition.
root #
mkswap /dev/sdb2
Setting up swapspace version 1 size=2 GiB (2147479552 bytes)
no label,UUID=8625c597-3a09-4aa9-aa15-38b0d713d00f
Mount Filesystem
Now that we have our file systems in place, we want to create a mount point in the host system's /mnt directory. We'll call this mount point /pi3-gentoo.
root #
mkdir -v /mnt/pi3-gentoo
mkdir: created directory '/mnt/pi3-gentoo'
Mount the SD card root partition to our new mount point -
root #
mount -v /dev/sdb3 /mnt/pi3-gentoo
mount: /dev/sdb3 mounted on /mnt/pi3-gentoo.
Change into our new pi3-root directory -
root #
cd /mnt/pi3-gentoo
Get Latest Stage 3
Now we'll fire up the lynx command line browser and go to the Gentoo download mirrors to grab the latest arm64 stage3 tarball -
root #
lynx https://www.gentoo.org/downloads/mirrors/
Select the mirror nearest you and browse to releases/arm/autobuilds/current-stage3-arm64. Select stage3-arm64-yyyymmdd.tar.bz2, press 'D', then hit Enter twice to download and save to the pi3-gentoo directory. Once downloaded, exit lynx by pressing 'Q', then press Y.
Now extract the downloaded tarball. At the time of this writing, the current stage3 is stage3-arm64-20161219.tar.bz2 -
root #
tar xvjpf stage3-arm64-20161219.tar.bz2 --xattrs --numeric-owner
Once extraction completes, /mnt/gentoo/tmp needs to be emptied. Clear it now or the the Pi will do it at boot. That may take a long time.
root #
rm -rfv /mnt/pi3-gentoo/tmp/*
Portage Tree
Download the latest Portage snapshot -
Extract Portage to SD Card -
root #
tar xjvpf portage-latest.tar.bz2 -C /mnt/pi3-gentoo/usr
=Base System Configuration
Copy DNS Info
Copy the host system's DNS info to the target system -
root #
cp -L /etc/resolv.conf /mnt/pi3-gentoo/etc
Configure make.conf
Configure make.conf as follows -
Configure fstab
Configure /mnt/pi3-gentoo/etc/fstab as follows -
Using Crossdev to Build A Cross Compiler
root #
crossdev -t aarch64-unknown-linux-gnu
You may need to nominate an overlay to store the cross ebuilds, crossdev will let you know.
There are other parameters you can pass to crossdev too.
Do not use -S to build a stable toolchain, arm64 moves quickly
Crossdev insists that many of the files in /etc/portage/ are directories
Convert files as crossdev asks e.g.
error: please convert /etc/portage/package.env to a directory
by appending _file to the existing filename
root #
mv /etc/portage/package.env /etc/portage/package.env_file
making the directory
root #
mkdir /etc/portage/package.env
then moving package.env_file into the directory.
root #
mv /etc/portage/package.env_file /etc/portage/package.env
Rinse and repeat until crossdev is happy.
crossdev will take a while. Its building
binutils: binutils-[latest] gcc: gcc-[latest] headers: linux-headers-[latest] libc: glibc-[latest]
When crossdev completes you will have a cross toolchain
user $
$ gcc-config -l
[1] aarch64-unknown-linux-gnu-5.4.0 *
[2] x86_64-pc-linux-gnu-5.3.0
[3] x86_64-pc-linux-gnu-5.4.0 *
It will also create an arm64 target root in /usr/aarch64-unknown-linux-gnu/ This is used by cross emerge.
Pure cross compiling, other than the kernel, is out of scope of this guide.
Fetch the Raspberry Pi Firmware
The Raspberry Pi Firmware is maintained in a git repository. You will need to install git if you don't have it.
root #
emerge -av git
Don't do anything you don't need to do as root.
As your normal user, make some space in the home directory for raspberry pi
user $
mkdir raspberrypi
will do nicely.
This will be for the Raspberry Pi Firmware and kernel
user $
cd raspberrypi
user $
git clone https://github.com/raspberrypi/firmware
will fetch the Pi firmware into a directory called firmware
It will actually fetch all the history too. If you are short of space or bandwidth, a shallow clone is all that's needed.
Receiving objects: 100% (484760/484760), 6.32 GiB
A full clone is 6.3G and growing, we only need the /boot directory out of the master branch.
There is nothing to build. ~/raspberrypi/firmware/boot is used as is.
Fetch, Configure and Build the Raspberry Pi Kernel
Fetch the Raspberry Pi Kernel
Stay in raspberrypi and
user $
git clone https://github.com/raspberrypi/linux
will fetch the kernel into a directory called linux.
With absolutely no fanfare at all, 64 bit support was added to this kernel tree late in 2016. No more searching for odd patches.
Not everything has been accepted by the mainline kernel yet but its getting closer. Feel free to test for yourself.
The master branch may be broken as its commit by commit as it happens. Test if you want to. Its better to use an identified tag. At the time of writing that is rpi-4.10.y. The 4.10 mainline kernel is still at -rc status.
user $
cd linux
user $
git checkout rpi-4.10.y
Checking out files: 100% (33079/33079), done.
Branch rpi-4.10.y set up to track remote branch rpi-4.10.y from origin.
Switched to a new branch 'rpi-4.10.y'
That's the kernel source tree in place, ready for configuring and cross compiling.
Configure The Kernel
ARCH=arm64 must be specified everywhere or the kernel build system will use the HOST arch. This will destroy the arm64 .config file
As your user
user $
cd raspberrypi/linux
The bcmrpi3_defconfig is almost right as it stands. It defaults to the powersave CPU governor, which runs the Pi at 600MHz. All the governors are there. Ondemand is recommended.
user $
ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- make bcmrpi3_defconfig
Either use menuconfig to change the default CPU governor, add something to the kernel command line, or change it after booting.
user $
ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- make menuconfig
Search for CPU_FREQ_DEFAULT_GOV go to that location and set the default to Ondemand. Exit menuconfig, saving the change.
.config - Linux/arm64 4.10.0-rc6 Kernel Configuration > CPU Power Management > CPU Frequency scaling ────────────────────────────────── ┌────────────────────────── CPU Frequency scaling ───────────────────────────┐ │ Arrow keys navigate the menu. <Enter> selects submenus ---> (or empty │ │ submenus ----). Highlighted letters are hotkeys. Pressing <Y> includes, │ │ <N> excludes, <M> modularizes features. Press <Esc><Esc> to exit, <?> │ │ for Help, </> for Search. Legend: [*] built-in [ ] excluded <M> module │ │ ┌────────────────────────────────────────────────────────────────────────┐ │ │ │ [*] CPU Frequency scaling │ │ │ │ [*] CPU frequency transition statistics │ │ │ │ [ ] CPU frequency transition statistics details │ │ │ │ Default CPUFreq governor (powersave) ---> │ │ │ │ <*> 'performance' governor │ │ │ │ -*- 'powersave' governor │ │ │ │ <*> 'userspace' governor for userspace frequency scaling │ │ │ │ <*> 'ondemand' cpufreq policy governor │ │
The kernel .config contains lots of support for hardware you don't have and possibly have never heard of. More confident readers may be tempted to trim things out now. A word of advice - don't, at least, not until the system boots.
Cross Compiling The Kernel
The kernel will not link with the gold linker. It ends with
aarch64-unknown-linux-gnu-ld: fatal error: -shared and -pie are incompatible
If you don't know what the gold linker is, you are not using it.
The build is conventional, other than telling the build system to build for arm64 and use the cross compiler.
user $
ARCH=arm64 CROSS_COMPILE=aarch64-unknown-linux-gnu- make -jX
Change X to the number of parallel MAKE jobs you want to run. Convention is cores+1.