From Gentoo Wiki
Jump to:navigation Jump to:search

I started installing Gentoo on my pine phone after booting the PostmarketOS with Sxmo from the multiboot image from Megi.

For this guide, let's assume we have:

  • / (root) on emmc of 16Go
  • /var of 32Go (Firefox needs almost 16Go of tmp space in order to compile, and, if you use flatpak, you will need a lot of space too) on sdcard
  • /var/tmp on zram
  • /tmp on zram
  • /home on the remaining space (on sdcard)

I choose to install the root filesystem on the emmc and to have /home and /var on sdcard. Indeed, I think it can be a good practice to create partition for /var of /tmp in the SDCARD because they are likely to have a lot of read/write cycle, particularly on Gentoo since Gentoo use tmp dirs in /var during compiling process. So you will preserve your EMMC memory.

Moreover, I will use zram (for ram, /var/tmp - to handle small packages -, and /tmp).

A the moment, I use bingch overlay to install kernel sources and Phosh. For sway for exemple, you can have a look on this git repo : I use p-boot for the boot process.

Finally, depending on your needs, I can suggest to install tar (the Sxmo version is limited), screen and btrfs-progs

Here are my installation steps.

prepare disks

For this steps the amd64 handbook helps : Handbook:AMD64/Installation/Disks

root #fdisk /dev/mmcblk0

Create filsystem

root #mkfs.btrfs /dev/mmcblk0p3
root #mkfs.btrfs /dev/mmcblk0p4
root #mkfs.ext4 /dev/mmcblk2p3


Prepare Chroot

root #mkdir /mnt/gentoo
root #mount /dev/mmcblk2p3 /mnt/gentoo && cd /mnt/gentoo


root #tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner
root #vi /mnt/gentoo/etc/portage/make.conf Safe_CFLAGS#ARM

TODO : list make.conf flags

root #mkdir --parents /mnt/gentoo/etc/portage/repos.conf
root #cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf
root #touch /mnt/gentoo/etc/portage/repos.conf/bingch.conf
root #vi /mnt/gentoo/etc/portage/repos.conf/bingch.conf
FILE /mnt/gentoo/etc/portage/repos.conf/bingch.confBingch repos
location = /var/db/repos/bingch
sync-type = git
sync-uri =
auto-sync = yes
root #mkdir /mnt/var-btrfs
root #mount -t btrfs /dev/mmcblk0p3 /mnt/var-btrfs
root #mkdir /mnt/home-btrfs
root #mount -t btrfs /dev/mmcblk0p4 /mnt/home-btrfs
root #btrfs subvolume create /mnt/var-btrfs/gentoo-var

Create subvolume '/mnt/var-btrfs/gentoo-var'

root #btrfs subvolume create /mnt/home-btrfs/gentoo-home

Create subvolume '/mnt/home-btrfs/gentoo-home'

root #mount -t btrfs -o subvol=gentoo-var /dev/mmcblk0p3 /mnt/gentoo/var
root #mount -t btrfs -o subvol=gentoo-home /dev/mmcblk0p4 /mnt/gentoo/home`
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 #test -L /dev/shm && rm /dev/shm && mkdir /dev/shm
root #mount --types tmpfs --options nosuid,nodev,noexec shm /dev/shm
root #chmod 1777 /dev/shm

Chroot itself

root #cp --dereference /etc/resolv.conf /mnt/gentoo/etc/
root #chroot /mnt/gentoo /bin/bash
root #source /etc/profile
root #export PS1="(chroot) ${PS1}"

Further configuration

root #eselect profile list Available profile symlink targets:
 [1]   default/linux/arm64/17.0 (stable)
 [2]   default/linux/arm64/17.0/desktop (stable)
 [3]   default/linux/arm64/17.0/desktop/gnome (stable)
 [4]   default/linux/arm64/17.0/desktop/gnome/systemd (stable)
 [5]   default/linux/arm64/17.0/desktop/plasma (stable)
 [6]   default/linux/arm64/17.0/desktop/plasma/systemd (stable)
 [7]   default/linux/arm64/17.0/desktop/systemd (stable)
 [8]   default/linux/arm64/17.0/developer (stable)
 [9]   default/linux/arm64/17.0/systemd (stable) *
 [10]  default/linux/arm64/17.0/big-endian (exp)
 [11]  default/linux/arm64/17.0/musl (exp)
 [12]  default/linux/arm64/17.0/musl/hardened (exp)
root #eselect profile set 4

Without systemd

root #echo "Europe/Brussels" > /etc/timezone
root #nano -w /etc/locale.gen
root #eselect locale set 9

See Handbook:AMD64/Installation/System#Networking_information for the network configuration

With Systemd


root #systemctl enable systemd-networkd.service

Created symlink /etc/systemd/system/dbus-org.freedesktop.network1.service → /lib/systemd/system/systemd-networkd.service. Created symlink /etc/systemd/system/ → /lib/systemd/system/systemd-networkd.service. Created symlink /etc/systemd/system/ → /lib/systemd/system/systemd-networkd.socket. Created symlink /etc/systemd/system/ → /lib/systemd/system/systemd-networkd-wait-online.service.

root #systemctl enable systemd-resolved.service

Created symlink /etc/systemd/system/dbus-org.freedesktop.resolve1.service → /lib/systemd/system/systemd-resolved.service. Created symlink /etc/systemd/system/ → /lib/systemd/system/systemd-resolved.service.

Prepare network for reboot on Gentoo
root #emerge --ask net-misc/dhcpcd
root #emerge --ask net-wireless/iw net-wireless/wpa_supplicant
root #emerge -avq ssh
root #systemctl enable sshd

Created symlink /etc/systemd/system/ → /lib/systemd/system/sshd.service.`

Create file /etc/systemd/network/ :

FILE /etc/systemd/network/50-dhcp.networkNetwork configuration
root #systemctl enable systemd-networkd.service

Edit fstab

FILE /etc/fstabfstab
/dev/mmcblk2p3		/		ext4		noatime								0 1
/dev/mmcblk0p3		/var		btrfs		rw,noatime,ssd,space_cache,subvolid=256,subvol=/gentoo-var	0 0
/dev/mmcblk0p4		/home		btrfs		rw,noatime,ssd,space_cache,subvolid=256,subvol=/gentoo-home	0 0
tmpfs			/tmp		tmpfs           noatime,size=500M						0 0

Sync bingch repo

root #emaint -r bingch sync

Distcc setup

Since it can take a while to compile the entire system onboard, I should advice to use distcc.

The use of docker images makes it easy to configure on every systems.

As fas as I am concerned, I used the ksmanis Gentoo distcc image here:

Ksmanis provides a lot of different images that should suits your needs (for me: ksmanis/gentoo-distcc:arm64-tcp).

So once installed on every participating machines, you just have to follow theses simple steps:

  • configure distcc for participating hosts:


root #/usr/bin/distcc-config --set-hosts ""
  • adapt the make.conf file to indicates that the emerge process now have to use distcc


FILE /etc/portage/make.conf
MAKEOPTS="-j11 -l2"

Please note that you should not use -march=native or -mtune=native in the CFLAGS or CXXFLAGS variables of make.conf when compiling with distcc.

If you are running your participating host inside your own network, I think there is no need to configure ssh connection or ever compression.

Compile and install kernel

root #emerge -avq pinephone-sources
root #eselect kernel list

Available kernel symlink targets:

 [1]   linux-5.10.2-pinephone *
root #cd /usr/src/linux
root #make pinephone_defconfig #See arch/arm64/configs/pinephone_defconfig
root #make -j23 -l4 CC=distcc CXX=distcc Image dtbs modules #you need several hours
root #cp ./arch/arm64/boot/Image /boot/vmlinuz-5.10.2-pinephone-arm64
root #cp ./arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone*.dtb /boot
root #make modules_install
root #make firmware_install
root #make headers_install INSTALL_HDR_PATH=/usr

Or if you have cross build environment installed on your amd64 host, you can cross compile the kernel on your amd64 host much quicker, on my i5 laptop it takes about 10 mins. I use wrapper like this

$ cat /usr/local/bin/xmake 
exec make ARCH="arm64" CROSS_COMPILE="aarch64-unknown-linux-gnu-" INSTALL_MOD_PATH="${SYSROOT}" "$@"

Then run the xmake as you would use make for compiling the kernel for pinephone

$ ebuild /var/db/repos/bingch/sys-kernel/pinephone-sources/pinephone-sources-5.10.12.ebuild prepare
$ cd /path/to/portage_build_folder/portage/sys-kernel/pinephone-sources-5.10.12/work/linux-5.10.12/
$ cp arch/arm64/configs/pinephone_defconfig .config # or you can use the config files in sys-kernel/pinephone-sources/files/
$ xmake oldconfig; xmake menuconfig
$ xmake -j9 Image modules # adjust j number as needed
$ xmake DTC_FLAGS="-@" dtbs
$ mkdir /tmp/boot
$ xmake INSTALL_DTBS_PATH=/tmp/boot dtbs_install
$ xmake INSTALL_MOD_PATH=/tmp/boot modules_install
$ cp arch/arm64/boot/Image /tmp/boot
$ rsync -avP /tmp/boot pinephone_ip:/tmp # copy kernel files to pinephone

Then on pinephone move files /tmp/boot to /boot and /lib/modules folders and re-configure new kernel

Configure bootloader

Using p-boot

Follow the p-boot README to install p-boot binary and other files into pinephone's /boot folder.

$ ls -l /boot/
-rw-r--r-- 1 root root 15806472 Jan 31 10:42 Image-5.10.12
-rw-r--r-- 1 root root     1697 Jan 31 09:09 boot.conf
drwxr-xr-x 3 root root     3488 Jan 31 09:03 dtbs-5.10.12
drwxr-xr-x 2 root root     3488 Jan 15 20:51 files
-rwxr-xr-x 1 root root    61304 Sep 30 20:10 fw.bin
-rw------- 1 root root 23844428 Jan 31 10:45 initramfs-5.10.12.img
-rwxr-xr-x 1 root root   522128 Dec 31 17:30 p-boot-conf
-rwxr-xr-x 1 root root   509840 Dec 31 17:45 p-boot-select
-rwxr-xr-x 1 root root    66336 Dec 31 17:46 p-boot-start32
-rwxr-xr-x 1 root root      132 Dec 31 17:46 p-boot-start32.bin
-rw-r--r-- 1 root root    32768 Dec 31 17:19 p-boot.bin

You need the first partition of the boot media formatted as linux (83) partition, with enough space for kernel and other files, here's my SD card config

/dev/mmcblk0p1       62500   500000   437501 213.6M 83 Linux

Then write the p-boot.bin to boot media

$ sudo dd if=p-boot.bin of=/dev/mmcblk0 bs=1024 seek=8

Here's the boot config

$ cat /boot/boot.conf
device_id = pp3 (PP 1.2a)
no          = 0
  name      = 5.10.12 (EMMC)
  atf       = fw.bin
  dtb       = dtbs-5.10.12/allwinner/sun50i-a64-pinephone-1.2.dtb
  linux     = Image-5.10.12
  initramfs = initramfs-5.10.12.img
  bootargs  = console=tty1 console=ttyS0,115200 root=/dev/mmcblk2p4 rootfstype=f2fs rootflags=fastboot rw rootwait quiet
  splash    = files/xnux.argb

Command to write boot kernel and other files to boot partition

$ cd /boot
$ sudo ./p-boot-config . /dev/mmcblk0p1  

Boot into gentoo

Initial configuration for systemd

As a matter of fact, some steps can't be done on chrooted environment

root #hostnamectl set-hostname pinephone
root #localectl set-keymap fr # or whatever your keyboard is
root #timedatectl set-timezone Europe/Paris # or wathever your time-zone is
root #timedatectl
              Local time: mar. 2020-12-29 22:25:34 CET
          Universal time: mar. 2020-12-29 21:25:34 UTC
                RTC time: mar. 2020-12-29 21:25:34    
               Time zone: Europe/Paris (CET, +0100)   

System clock synchronized: no

             NTP service: inactive                    
         RTC in local TZ: no                          

At this point, I installed screen one again to gain confort for last steps

root #emerge -avq app-misc/screen

Enable zram


root #emerge -avq sys-block/zram-init
root #echo "zram" > /etc/modules-load.d/zram.conf
root #systemctl edit zram_swap

and modify startup command as follows:

FILE temporary file used for editing serviceservice override
ExecStart=/bin/sh -c "exec /sbin/zram-init -s4 -alz4 -d0 -Lzram_swap 1024"

This will reserve a 1Go swap space. Please note that -d0 is unnecessary since by default the zram-init script will use slot #0.

And the same for zram_tmp

root #systemctl edit zram_tmp


FILE temporary file used for editing serviceservice override
ExecStart=/sbin/zram-init -d1 -s4 -azstd -text4 -ostrictatime -m1777 -Ltmp_dir 124 /tmp

By this command you will mount a drive on /tmp of 124Mo in the ZRAM slot #1

root #systemctl edit zram_var_tmp


FILE temporary file used for editing serviceservice override
ExecStart=/sbin/zram-init -d2 -s4 -azstd -text4 -orelatime -m1777 -Lvar_tmp_dir 1024 /var/tmp

This command mount a drive on /var/tmp of 1Go in the ZRAM slot #2. Then mask tmp.mount as it is replaced by zram_tmp

root #systemctl mask tmp.mount

And finaly, enable the units

root #systemctl enable zram_swap zram_tmp zram_var_tmp

Created symlink /etc/systemd/system/ → /usr/lib/systemd/system/zram_swap.service. Created symlink /etc/systemd/system/ → /usr/lib/systemd/system/zram_tmp.service. Created symlink /etc/systemd/system/ → /usr/lib/systemd/system/zram_var_tmp.service.

Emerge stuff

At this time, compilation process can be very long. A usefull tip, if the compilation process is halted, is to continue by submitting

root #ebuild /path/to/package merge
root #ln -s /usr/bin/vapigen-0.48 /usr/bin/vapigen # seems to be requied by some packages
root #ln -s /usr/share/asciidoc /etc/asciidoc # seems to be requied by some packages
root #emerge pinephone phosh-meta --autounmask --autounmask-write -av
root #emerge -avquDN @world

Final configuration

Start Squeekboard at session startup

FILE /etc/xdg/autostart/sm.puri.Squeekboard.desktopSqueekboard launch
[Desktop Entry]
GenericName=Squeekboard Virtual Keyboard
Comment=Virtual Keyboard

Enable screen keyboard (if necessary)

root #gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true

Add various services

root #systemctl enable ModemManager
root #systemctl enable eg25-manager
root #systemctl enable bluetooth