(Almost) upstream boot for Pinebook Pro

Why, pray tell?

The Pinebook Pro is a pretty nifty device. A 200$ laptop. With an RK3399 SoC in it, a hex-core AArch64 chip from Rockchip. That’s just amazing.

The default OS it ships with is a Debian with a vendor kernel and U-Boot provided by Rockchip. For the shipped Debian this bootloader works well, but other OSes may have some problems. In the case we’re adressing here it is the Manjaro kernel booting very slowly, caused by the Rockchip bootloader not bringing up all CPU cores of the chip properly. There are a few workarounds for this (booting with nr_cpus=4 for example), but all of them have their drawbacks. Also, booting with an (almost) fully upstream bootloader is just, you know, more satisfying.

Procedure, overview of

The bootloader on the pinebook consist of two main parts:

  • ATF, the ARM Trusted Firmware, which provides platform functionality like power managemt of CPU cores, DDR frequency management, and other very low-level things that happen on the SoC itself.
  • U-Boot, which gets the ATF into the chip and actually boots the rest of the system. ATF itself cannot interact with the rest of the board and thus boot anything, or even turn on peripherals required for boot. U-Boot will do that.

We will have to build both of these. ATF needs no patches to work, although suspend/resume does not work at the time of writing. U-Boot needs a few patches to properly detect the Pinebook Pro hardware.

Preparation

This guide assumes that all compilation is done on a Pinebook Pro, running a recent Manjaro image.

First, install some tools necessary to build ATF and U-Boot. We will need the aarch64 gcc, a 32 bit arm gcc for some parts of ATF, and the device tree compiler for U-Boot:

$ sudo pacman -S bc base-devel arm-none-eabi-gcc dtc

Then clone both ATF and U-Boot. We will use upstream ATF and a patched version of U-Boot that is very close to mainline. ATF is locked to a specific version here because we know it works, aside from the known bugs such as suspend not working.

$ git clone https://github.com/ARM-software/arm-trusted-firmware.git atf
$ git -C atf checkout 22d12c4148c373932a7a81e5d1c59a767e143ac2
$ git clone https://git.eno.space/pbp-uboot.git uboot

The U-Boot repository we’ve checked out comes with all patches required and builds to something we may consider reasonable: boot order is SD first, USB second, eMMC third. The boot delay is short, and U-Boot will light the Pinebook LEDs early in the boot process to signal liveness of the Pinebook.

Building and Installation

Building ATF is very simple, but requires custom CFLAGS to build reliably on some machines. Yours may not need the CFLAGS, omitting them does no harm if the compilation succeeds.

$ make -C atf -j8 PLAT=rk3399 CFLAGS=‘-gdwarf-2’

Building on other platforms will require setting CROSS_COMPILE and possibly M0_CROSS_COMPILE, depending on the distribution you’re working with.

U-Boot requires a little more, but not much. It also requires the path of the ATF binary we built in the previous run.

$ make -C uboot -j8 pinebook_pro-rk3399_defconfig
$ make -C uboot -j8 BL31=../atf/build/rk3399/release/bl31/bl31.elf

This will produce two binaries, uboot/idbloader.img and u-boot.itb, that have to be written to eMMC or SD card. We will write them to eMMC here.

$ sudo dd if=uboot/idbloader.img of=/dev/mmcblk2 seek=64
$ sudo dd if=uboot/u-boot.itb of=/dev/mmcblk2 seek=16384

Now reboot your Pinebook, and you will be running with an (almost) upstream bootloader. Like the Rockchip bootloader used by the stock Debian install and many other distributions, this U-Boot supports /boot.scr and /boot/boot.scr scripts on the first partition of a storage device.