PineNote Development

From PINE64
Jump to navigation Jump to search

This article seeks to provide general development information for the PineNote. If you are new and down to try a new installation process, the easiest way to get linux is likely to install Debian -- NOTE THAT THIS INSTALLATION PROCESS IS VERY NEW. While many people have been using the kernel that will be installed safely at this point, the instructions for installing Debian via rootfs are very new. Take backups!

The more stable recommended approach is described below:

Start with Dorian's guide which will guide you through getting Arch installed. For instructions on building the latest kernel, see PineNote Development/Building Kernel. For helpful configurations, see PineNote Development/Apps. For ways to pitch in, see PineNote Development/TODOs. To boot Linux by default instead of Android, see PineNote Development/Booting Linux. Here is a video of a user running Manjaro and some apps on their PineNote on 9/10/2022.

More Information

High-level developer new to embedded linux?

Here are some resources I have found helpful in learning to develop on embedded linux devices:

Notes Written by Some Developers

Building the most recent kernel

See here.


Video of Factory Android OS

PineNote Developer Edition w/Tech Demo Android OS (Video Only)

Informal walkthrough of the factory Android installation on the PineNote Developer Edition, recorded by a community member (Apr 2022). This is useful to look back at the original OS after erasing it from your device, or to get some additional detail before your device arrives.

The video also includes a chapter at the end showing how to enable Android Debug Bridge (`adb`) over USB. Once enabled, keep the device powered and connect a USB cable directly to the PineNote (i.e. no UART breakout) to a computer running `adb`.

Emulator for Developing/Testing Pinenote Apps

https://github.com/michaelshiel/picom-epaper

Flashing Software

Currently, the only ways to flash software are from the factory Android installation (UART shell, adb, or fastboot) or by using rkdeveloptool.

Side-by-side setup

It is possible to set up a partition for mainline development without disturbing the factory Android installation. This allows updating a mainline kernel, DTB, and initramfs over Wi-Fi until WiFi or USB OTG is working in mainline Linux.

Without Repartitioning

The recommended partition for this is mmcblk0p11 aka /cache. It is large and already formatted as ext4, so it is readable from U-Boot. Here are some general steps:

  1. From the UART or adb shell, set up your chroot in /cache. I used the Alpine Linux rootfs tarball.
  2. Copy in your kernel and DTB, using for example scp or wget inside the chroot.
  3. Finally, create and boot an extlinux.conf as described below.

With Repartitioning

It is possible to shrink the userdata partition, and create a new partition at the end for use with mainline Linux. This provides much more space than cache. However, because userdata is formatted with f2fs, and that filesystem cannot be shrunk, resizing the partition requires wiping userdata.

  1. Back up any necessary files from userdata
  2. Boot to a mainline kernel from mmcblk0p11, either using that partition as rootfs (see above), or using an initramfs with repartitioning tools
  3. Modify the partition table with your favorite tool, e.g. fdisk, gdisk, or parted
  4. Reboot into fastboot and wipe userdata.
  5. Reboot into Android, where you can now chroot in and install your favorite distribution to the new partition.

Using rkdeveloptool

rkdeveloptool is a command line utility built on libusb.

Downloading and Building rkdeveloptool

PINE64 develops its own updated fork of rkdeveloptool on GitLab.

You will need to have libusb 1.0, its development headers and scdoc installed.

git clone https://gitlab.com/pine64-org/quartz-bsp/rkdeveloptool.git
cd rkdeveloptool
mkdir build
cd build
cmake ..

This sets up all the build files. You can then compile with make inside the build directory.

After you're done, you'll likely also need to install the udev rules, or else your user won't have permission to access the USB devices:

sudo cp 99-rk-rockusb.rules /etc/udev/rules.d/
sudo udevadm control --reload

Copying the udev rules is also performed automatically when you make install.

Building Downstream U-Boot

While in maskrom mode, we need to have a u-boot to download onto the device for any of the other commands to work. To build you'll also need to install device-tree-compiler.

You also need to install Python and pyelftools.

Note that rkbin is a >5GB download! This will take some time to clone and process the deltas.

git clone -b quartz64 https://gitlab.com/pgwipeout/u-boot-rockchip.git
git clone -b rkbin https://github.com/JeffyCN/rockchip_mirrors.git rkbin
cd u-boot-rockchip
# If using Arch Linux, export CROSS_COMPILE=aarch64-linux-gnu-
export CROSS_COMPILE=aarch64-none-linux-gnu-
make rk3566-quartz64_defconfig
./make.sh

In the version I cloned (current as of 2022-01-02), I had to make a change to one line to get a clean compilation:

diff --git a/lib/avb/libavb/avb_slot_verify.c b/lib/avb/libavb/avb_slot_verify.c
index 123701fc3b..64a1ce6450 100644
--- a/lib/avb/libavb/avb_slot_verify.c
+++ b/lib/avb/libavb/avb_slot_verify.c
@@ -296,7 +296,7 @@ static AvbSlotVerifyResult load_and_verify_hash_partition(
   bool image_preloaded = false;
   uint8_t* digest;
   size_t digest_len;
-  const char* found;
+  const char* found = NULL;
   uint64_t image_size;
   size_t expected_digest_len = 0;
   uint8_t expected_digest_buf[AVB_SHA512_DIGEST_SIZE];

For systems where the global python executable points to python2, compilation fails with an error related to pyelftools not being installed (even if it is). To fix this:

diff --git a/make.sh b/make.sh
index 2bba05b4e4..cfe5b0afd5 100755
--- a/make.sh
+++ b/make.sh
@@ -758,7 +758,7 @@ function pack_fit_image()
        fi
 
        if [ "${ARM64_TRUSTZONE}" == "y" ]; then
-               if ! python -c "import elftools" ; then
+               if ! python3 -c "import elftools" ; then
                        echo "ERROR: No python 'pyelftools', please: pip install pyelftools"
                        exit 1
                fi

Entering Maskrom/Rockusb Mode

There are two ways to get into Maskrom/Rockusb mode:

The easy way

  1. Flip the device around so that the display faces down
  2. Lay the pen on the right side, with its tip pointing towards the speaker grill, and its magnet pointing towards the upper right corner of the label on the back.
  3. Turn the device on and wait for it to show up in lsusb. It should now be in Loader mode, according to rkdeveloptool list-devices (note that "Loader" here indicates U-Boot's Rockusb; separately, booting with an erased eMMC displays "Maskrom" [not "Loader"] from the RK3566).
  4. Unplug the device and plug it back in. It should now be in Rockusb mode.

This can be a bit fiddly to get right, and may need a few tries.

Shorting test points

If the bootloader is broken/corrupted, you cannot get to Maskrom without opening up the device (it can be opened using spudger and a bit of patience).

Once inside, short TP1301 and TP1302 with a small tweezers, this is how it looks on board view (credit to Caleb):

PineNote Maskrom TP.png

Then plug the device to the computer and if you see the device with VID=2207/PID=350a then it should be in Maskrom mode, you can verify by typing rkdeveloptool list-devices.

Jan 07 15:04:13 melttower kernel: usb 1-14: New USB device found, idVendor=2207, idProduct=350a, bcdDevice= 1.00
Jan 07 15:04:13 melttower kernel: usb 1-14: New USB device strings: Mfr=0, Product=0, SerialNumber=0

$ rkdeveloptool list-devices
DevNo=1 Vid=0x2207,Pid=0x350a,LocationID=10e    Maskrom


If nothing shows up, you can try to hold down the power button for 5 seconds and then try again.

Running rkdeveloptool

First, you'll want to make sure the device you've connected is in maskrom mode:

./rkdeveloptool list

It should output something like DevNo=1 Vid=0x2207,Pid=0x350a,LocationID=202 Maskrom. If it doesn't, see PineNote Development#Entering Maskrom Mode.

You can now download u-boot onto it:

./rkdeveloptool boot ../u-boot-rockchip/rk356x_spl_loader_v1.08.111.bin

This should output Downloading bootloader succeeded..

We can now verify that this worked using e.g. the "read flash info" command:

./rkdeveloptool read-flash-info

TODO: finish this section

Creating a mainline boot image

You can create a filesystem image that replaces the Android boot or recovery partition by doing roughly the following:

  1. Erase boot and dtbo with rkdeveloptool or fastboot (back them up first!!!)
  2. Create an ext2 partition image and mount it (fallocate, mkfs.ext2)
  3. Build your mainline kernel
  4. Copy the kernel, dtb and an initramfs to the root of the mounted image (use any old postmarketOS initramfs)
  5. Create a file in the root of the mounted image called extlinux.conf as described below
  6. Unmount the image and then use rkdeveloptool to flash it to the "recovery" partition on the pinenote (it's about the right size until we get around to replacing the partition layout).

Using fastboot

Follow the steps for "Creating a mainline boot.img", but instead of flashing it with rkdeveloptool, use fastboot. You can enter fastboot in either of two ways:

  1. Use "reboot bootloader" from adb or a UART console.
  2. Get a U-Boot prompt and run fastboot usb 0.

Mainline development

Status

Some work happening here: https://gitlab.com/calebccff/linux, the idea is to import the parts of the eink/ebc drivers which are open source and use the downstream u-boot framebuffer driver as a reference to create a basic framebuffer driver.

Currently mainline struggles to boot due to weird issues while probing fixed regulators (?). It also fails to detect eMMC.

Further work is being done here: https://github.com/smaeul/linux/commits/rk356x-ebc-dev. This has a complete device tree, with working eMMC. Pen input also works out of the box. Wi-Fi and BT work with firmware copied from the factory Android image.

How to boot mainline

UART is currently REQUIRED for this to work! We depend on u-boot falling back to console. Once we have a prebuilt u-boot which will use extlinux by default, UART won't be needed anymore.

You can compile a u-boot that uses extlinux by default by following the instructions here.

Getting to a U-Boot prompt

You can get to a U-Boot prompt by:

  1. Holding Ctrl-C while the display panel initializes.
  2. Wiping the "boot" partition.

Using sysboot

extlinux.conf should have the following contents:

timeout 10
default MAINLINE
menu title boot prev kernel

label MAINLINE
  kernel /vmlinuz
  fdt /rk3566-pinenote.dtb
  initrd /initramfs
  append earlycon console=tty0 console=ttyS2,1500000n8 fw_devlink=off PMOS_NO_OUTPUT_REDIRECT

At the u-boot console, run the following command to boot your mainline kernel:

sysboot ${devtype} ${devnum}:9 any ${scriptaddr} extlinux.conf

Booting with individual commands

Booting with individual commands can be useful when you need to temporarily add some kernel command line arguments. Use these or similar commands at the U-Boot shell:

load mmc 0:b ${kernel_addr_r} boot/Image
load mmc 0:b ${fdt_addr_r} boot/rk3566-pinenote.dtb
setenv bootargs ignore_loglevel root=/dev/mmcblk0p11 rootwait init=/bin/bash
booti ${kernel_addr_r} - ${fdt_addr_r}

Configuration

Firmware

Copy WiFi/BT firmware from Android:

mkdir -p /cache/lib/firmware/brcm
cp /vendor/etc/firmware/fw_bcm43455c0_ag_cy.bin /cache/lib/firmware/brcm/brcmfmac43455-sdio.bin
cp /vendor/etc/firmware/nvram_ap6255_cy.txt /cache/lib/firmware/brcm/brcmfmac43455-sdio.txt
cp /cache/lib/firmware/BCM4345C0.hcd /cache/lib/firmware/brcm/BCM4345C0.hcd

Copy waveform partition (via previously dumped file):

adb root
adb push waveform.img /cache/lib/firmware/waveform.bin

Or via dd within Linux:

dd if=/dev/mmcblk0p3 of=/lib/firmware/waveform.bin bs=1k count=2048

Touchscreen and Pen In X.org

By default the pen config is flipped 180° (which makes it unusable) and the touchscreen doesn't work. Placing the following config in /etc/X11/xorg.conf.d/50-touchscreen.conf will fix both problems:

Section "InputClass"
    Identifier "evdev touchscreen"
    MatchProduct "tt21000"
    MatchIsTouchscreen "on"
    Driver        "evdev"
EndSection
Section "InputClass"
    Identifier    "RotateTouch"
    MatchProduct    "w9013"
    Option    "TransformationMatrix" "-1 0 1 0 -1 1 0 0 1"
EndSection