User:Dr41nU/PinePhone
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 : https://github.com/Dejvino/pinephone-sway-poc 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 on the installation host system.
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
Chrooting
Prepare Chroot
root #
mkdir /mnt/gentoo
root #
mount /dev/mmcblk2p3 /mnt/gentoo && cd /mnt/gentoo
Handbook:AMD64/Installation/Stage
root #
tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner
root #
vi /mnt/gentoo/etc/portage/make.conf
Edit your make.conf file to take advantage of Gentoo's powerfull customizing
[...]
# Example of flags that can be used for pinephone cpu. Be carefull, some of theses flag can cause the compilation process to fail
# COMMON_FLAGS="-Os -march=armv8-a -mtune=cortex-a53 -fomit-frame-pointer -mfloat-abi=hard -funsafe-math-optimizations -mneon-for-64bits -pipe"
# Theses later flags are safer
COMMON_FLAGS="-O2 -march=armv8-a -mtune=cortex-a53 -pipe"
# Theses flags are given by cpuid2cpuflags. Please note that neon flag is masked by profile (since it is 32 bit instruction set). So don't be upset if portage does not use it for compiling (firefox for example)
CPU_FLAGS_ARM="edsp neon thumb vfp vfpv3 vfpv4 vfp-d32 aes sha1 sha2 crc32 v4 v5 v6 v7 v8 thumb2"
VIDEO_CARDS="lima"
# Here I disable jumbo-build, that is used for webkit-gtk, since it increase the memory needed for compiling
USE="wayland -jumbo-build"
# Don't forget to adapt the rest of the file as your needs
You can find more information on CFLAG here:
Now you have to configure ebuild repositories.
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
[bingch]
location = /var/db/repos/bingch
sync-type = git
sync-uri = https://gitlab.com/bingch/gentoo_overlay.git
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/multi-user.target.wants/systemd-networkd.service → /lib/systemd/system/systemd-networkd.service.
Created symlink /etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /lib/systemd/system/systemd-networkd.socket.
Created symlink /etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service → /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/multi-user.target.wants/systemd-resolved.service → /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/multi-user.target.wants/sshd.service → /lib/systemd/system/sshd.service.`
Create file /etc/systemd/network/50-dhcp.network :
[Match]
Name=en*
[Network]
DHCP=yes
root #
systemctl enable systemd-networkd.service
Edit fstab
/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: https://hub.docker.com/r/ksmanis/gentoo-distcc
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:
Distcc#Specifying_participating_hosts
root #
/usr/bin/distcc-config --set-hosts "192.168.0.1 192.168.0.2 192.168.0.3"
- adapt the make.conf file to indicates that the emerge process now have to use distcc
[...]
MAKEOPTS="-j11 -l2"
FEATURES="distcc"
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
https://github.com/umiddelb/armhf/wiki/How-To-compile-a-custom-Linux-kernel-for-your-ARM-device
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 #!/bin/sh 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:
[Service]
ExecStart=
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
add
[Service]
ExecStart=
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
add
[Service]
ExecStart=
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/swap.target.wants/zram_swap.service → /usr/lib/systemd/system/zram_swap.service.
Created symlink /etc/systemd/system/local-fs-pre.target.wants/zram_tmp.service → /usr/lib/systemd/system/zram_tmp.service.
Created symlink /etc/systemd/system/local-fs-pre.target.wants/zram_var_tmp.service → /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
Add various services
root #
systemctl enable ModemManager
root #
systemctl enable eg25-manager
root #
systemctl enable bluetooth
Troubleshooting and tips
Keyboard not showing
Squeekboard should be running (even when it is not showing) and gnome should be configured to use screen keyboard.
Start Squeekboard at session startup:
[Desktop Entry]
Name=Squeekboard
GenericName=Squeekboard Virtual Keyboard
Comment=Virtual Keyboard
Exec=/usr/bin/squeekboard
Terminal=false
Type=Application
NoDisplay=true
Categories=GTK;Utility;
Enable screen keyboard (if necessary):
root #
gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true
Authorization asked for calling
It can be related to PolicyKit rules.
In that case you just have to edit a new file (starting with 00 to take precedence of /etc/polkit-1/rules.d/01-org.freedesktop.ModemManager1.rules)
// Let users in plugdev group modify ModemManager
polkit.addRule(function(action, subject) {
if (/^org\.freedesktop\.ModemManager1\.(Device\.Control|Contacts|Messaging|Location|Voice)$/.test(action.id) &&
subject.isInGroup("plugdev") && subject.active) {
return "yes";
}
});
Using other branch or version
Since many pinephone related ebuilds are relying on GIT, it is easy to change branch, version, commit and even source URL before merging an ebuild.
Here is a example:
root #
EGIT_OVERRIDE_BRANCH_LIBREM5_CHATTY="wip/sadiq/mm-account" EGIT_OVERRIDE_COMMIT_LIBREM5_CHATTY="" EGIT_OVERRIDE_REPO_LIBREM5_CHATTY="https://source.puri.sm/kop316/chatty" emerge -a1 =net-im/chatty-0.2.0-r6
Each environment variable that you will need starts with EGIT_OVERRIDE_. Then, you have the object (BRANCH, REPO, COMMIT, etc.) and finaly a text generated from the original repo URL