General full documentation
Android SDK for RK3566
Two Android SDKs are available from Pine64 for RK3566 devices:
QUARTZ64_SDK_android11
Android 11 SDK
For Quartz64 model A SBC and SOQuartz
- Direct Download from pine64.org
- MD5 (TAR-GZip file): 77c2ff57ea3372fb04da7fb49e17d12b
- File Size: 79.00GB
- Just the boot blobs (<1MB): https://wiki.pine64.org/wiki/File:Rk35-blobs.tar.gz
- Android build version:
QUARTZ64-model-A_eink.android11_SDK
Android 11 eink SDK
For PineNote and Quart64 model A SBC
- Direct Download from pine64.org
- MD5 (TAR-GZip file): 293a550584298de4fb95ceae18103672
- File Size: 72.88GB
- Just the boot blobs (<1MB): https://wiki.pine64.org/wiki/File:Rk35-blobs.tar.gz
- Android build version:
Compiling
Build machine
- 64 bit Linux (Manjaro tested)
- At least 16G RAM
- At least 250G free storage, preferably SSD based
- Use a POSIX compliant shell such as bash, not zsh (in Manjaro “chsh -s /bin/bash username”)
Manjaro packages
The following packages are needed (install with “sudo pacman -S packagename”):-
- make
- gcc
- python-pip
- dtc
- bison
- flex
- cpio
- unzip
- zip
Once this is done run
- pip install pyelftools
- sudo isnât needed
You will also need libncurses.so.5. The easiest way to install this appears to be using an Arch AUR package.
- Enable AUR
- pamac install ncurses5-compat-libs
- donât use sudo
Patches
QUARTZ64-model-A_eink.android11_SDK
For QUARTZ64-model-A_eink.android11_SDK the following files will need to be updated:-
- rk3566_ebook/u-boot/arch/arm/mach-rockchip/decode_bl31.py
- rk3566_ebook/u-boot/arch/arm/dts/Makefile
- rk3566_ebook/u-boot/scripts/dtc/dtc-lexer.l
- rk3566_ebook/u-boot/scripts/dtc/dtc-lexer.lex.c
- rk3566_ebook/u-boot/scripts/dtc/dtc-lexer.lex.c_shipped
- Download link QUARTZ64-model-A_eink.android11_SDK.patches.04112021.tar
- Only the PineNote target has been tested at this time.
Compilation process
- cd rk3566 (for non eink)
- cd rk3566_ebook (for eink)
- source build/envsetup.sh
- lunch
- ./build.sh -UCKAu
Cross-compiling
The Pinephoneâs triple for cross-compiling is aarch64-unknown-linux-gnu
.
C/++
Installing the Toolchain
important
Please add instructions for other distributions to this section if you know them!
First, youâll need to install the gcc cross-compilation toolchain.
On Arch Linux
$ sudo pacman -S aarch64-linux-gnu-gcc
On Ubuntu/Debian
$ sudo apt install gcc-aarch64-linux-gnu
On Void Linux
$ sudo xbps-install cross-aarch64-linux-gnu
Using the Toolchain
note
If you are trying to build an Arch Linux package with
makepkg
, also make sure toexport CARCH=aarch64
.
GNU Make
Kernel Makefile
For each invocation of make
, be sure to pass the options ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
like this:
$ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
Other
If you are using a handwritten Makefile (not autogenerated by a meta-buildsystem such as meson, automake, etc.) then simply override CC
and LD
as you need.
automake
$ ./configure --host=aarch64-linux-gnu
meson
See the official meson documentation on the topic. In general, the introduction is a good read for any cross-compiling novice.
Rust
In order to cross-compile Rust applications for the Pinephone, you need to have a gcc cross-compiler installed and the Rust dependencies, usually the std crate, cross compiled for the target system. A more extensive explanation can be found on https://github.com/japaric/rust-cross. This instruction is based on itâs description.
Installing a GCC Cross-Compiler
The cross-compiler might have a different name depending on the operating system. Further along this instruction the name for the gcc cross-compiler will be used. Replace all occurences of $gcc_name
with the name on your distribution.
For how to install the gcc cross-compilation toolchain on your distribution, please see Cross-compiling
Installing Rust Dependencies
The necessary dependencies can easily be installed with rustup:
$ rustup target add aarch64-unknown-linux-gnu
OR it can be installed with multirust [Is this still accurate???]:
$ multirust add-target nightly aarch64-unknown-linux-gnu
Compiling
rustc
When using rustc just add the two flags –target=aarch64-unknown-linux-gnu and -C linker=$gcc_name. Under Arch, this would look like:
$ rustc --target=aarch64-unknown-linux-gnu -C linker=aarch64-linux-gnu-gcc main.rs
To test it, run the program on your Pinephone
$ scp main user@ipadress:/home/user/Downloads
$ ssh user@ipadress /home/user/Downloads/main
Hello, world!
cargo
To cross-compile a project with cargo, open the folder of the project in a terminal. Then create a new folder and a file for cargo.
$ mkdir .cargo
$ cat >.cargo/config <<EOF
> [target.aarch64-unknown-linux-gnu]
> linker = "$gcc_name"
> EOF
Then you can compile it with
$ cargo build --target=aarch64-unknown-linux-gnu
To test it, copy the file on your Pinephone
$ scp target/aarch64-unknown-linux-gnu/debug/main user@ipadress:/home/user/Downloads
Then you can execute it by
$ ssh user@ipadress ./main -h
Hello, world!
Possible Errors
If you encounter an error saying
Cross compilation detected. Use PKG_CONFIG_ALLOW_CROSS=1 to override
just add that variable in front of your command e.g.
PKG_CONFIG_ALLOW_CROSS=1 cargo build --target=aarch64-unknown-linux-gnu
Mainline Hardware Decoding
note
This page is incomplete, you’re welcome to improve it.
Mainline Hardware Decoding refers to video decoding done using hardware accelerators on the mainline Linux kernel (i.e. what sits in Linus’ tree).
On most consumer-oriented SoCs, there is what is referred to as a VPU (Video Processing Unit). The VPU is responsible for power-efficient encoding and decoding of videos. Hardware-accelerated video decoding can be useful to get smoother video playback on your devices, lower power consumption, and lower CPU utilisation. Below is information regarding various hardware PINE64 uses and software that works with it.
Hardware
Here’s a table of the current support for different hardware. “In review” means the patch series to enable support has been posted to the mailing lists but is undergoing review, “linux-next” means it has been accepted and staged for the next Linux merge window.
RK3328 | RK3399 | RK3566 | RK3588 | |
---|---|---|---|---|
JPEG | No | Yes | No | No |
MPEG-2 | Yes | Yes | Yes | No |
MPEG-4 Part 2/H.263 | No | No | No | No |
VP8 | Yes | Yes | Yes | No |
H.264/AVC | Yes | Yes | YesÂč | No |
H.265/HEVC | In review | In review | No | No |
VP9 | Yes | Yes | No | No |
AVS2 | N/A | N/A | N/A | No |
AV1 | N/A | N/A | N/A | No |
Notes
Âč only Hantro, not rkvdec2, so with a maximum resolution of 1080p for now
Cedrus
In 2018, Bootlin launched a crowdfunding campaign to bring a open source Allwinner VPU driver to mainline Linux, which came to be called Cedrus. The Cedrus media driver (For Allwinner SOCs such as A64) supported by mainline Linux supports H.264 and H.265 video decoding as of Linux 5.10, and with 5.11 came VP8 decoding support and a H.264 stateless video decoder interface. For more information refer to the Sunxi wiki.
Hantro
The Hantro media driver supports Rockchip and NXP SoCs including the RK3399 used in the Pinebook Pro and RockPro64. In November 2020 it was announced that Bootlin was working on encoding support for the driver.
rkvdec
rkvdec is the video decoding hardware that’s developed by Rockchip presumably in house. It’s what Rockchip uses for decoding 4K H.264/AVC, VP9 and H.265/HEVC content. The driver in mainline linux for the first generation rkvdec (used in RK3328 and RK3399) supports VP9 and H.264, patches for HEVC support are also in the process of review.
RK3566, RK3568 and likely RK3588 use a second generation of rkvdec called rkvdec2. No mainline driver for this exists yet. The rkvdec instance on RK3588 additionally supports the AVS2 video codec.
rkdjpeg
rkdjpeg is Rockchip’s in-house hardware accelerated JPEG decoder. It can be found on the RK3566 and RK3568 as well as the RK3588.
No mainline driver exists for it so far.
Software
GStreamer
H.264 video decoding is possible when using GStreamer built from source, or an application utilizing it such as Clapper or ”Player. ”Player includes a indicator of when hardware acceleration is properly working and in use.
FFmpeg
Mainline FFmpeg currently lacks the necessary patches to use the v4l2-requests based API, but a fork that can utilise it exists.
With the patched ffmpeg, you can utilise hardware decoding using the -hwaccel drm
parameter, e.g.:
ffmpeg -hwaccel drm -i input.mp4 -f null - -benchmark
to measure how fast it decodes.
mpv
mpv v0.35 or later, built against the aforementioned FFmpeg fork, can be used to play back videos with hardware accelerated decoding. The hardware decoder path features interop with the GPU output, saving an expensive copyback operation. You can utilise the hardware decoding with e.g.:
mpv --hwdec=drm [FILE]
In mpv versions prior to 0.35, you can use the copyback hwdec with:
mpv --hwdec=drm-copy [FILE]
More Resources
- Megi’s Cedrus Information
- HW accelerated GStreamer playback on the PinePhone
- HW accelerated Clapper video player on the PinePhone
Mainline Hardware Encoding
Mainline Hardware Encoding of video can be achieved through the V4L2 user-space API, for which currently only GStreamer implements the required code.
SoC Support
The following table shows the current supported codecs for encoding for each SoC. Support for decoding is separate.
RK3328 | RK3399 | RK3566 | RK3588 | |
---|---|---|---|---|
JPEG | N/A | Yes | Yes | No |
VP8 | N/A | In review | No | No |
H.264/AVC | No | No | No | No |
H.265/HEVC | No | N/A | No | No |
Encoding With GStreamer
With GStreamer, in general, any V4L2 control can be set using the extra-controls=foo,name=value
syntax after the encode pipeline stage identifier, where foo
is any name you wish which GStreamer will promptly ignore, name
is the name of the V4L2 control as shown by v4l2-ctl --list-ctrls
(make sure to pick the right device with -d
), and value
is whatever value you want to set it to.
JPEG Encoding
This example converts an input MP4 file to an output MJPEG-inside-MKV file at JPEG quality 95, without any audio.
gst-launch-1.0 filesrc location=input.mp4 ! qtdemux name=demux demux.video_0 ! decodebin ! videoconvert ! v4l2jpegenc extra-controls=s,compression_quality=95 ! matroskamux ! filesink location=output.mkv
VP8 Encoding
tip
This requires a draft GStreamer merge request and the RFC kernel patchset applied.
This example converts an input MP4 file to an output VP8-inside-MKV file with a quantiser between 12 and 28, without any audio. The quantiser value goes from 0 (best quality, biggest filesize) to 63 (worst quality, smallest filesize).
gst-launch-1.0 filesrc location=input.mp4 ! qtdemux name=demux demux.video_0 ! decodebin ! videoconvert ! v4l2slvp8enc min-quality=12 max-quality=28 ! queue ! matroskamux ! filesink location=output.mkv
Alternatively, you can encode in variable bitrate mode with a target bitrate given in bits per second. Do note that Hantro doesnât seem to do target bitrates below 2 mbit/s. In this example, the file is transcoded at a target bitrate of 3 megabits per second.
gst-launch-1.0 filesrc location=input.mp4 ! qtdemux name=demux demux.video_0 ! decodebin ! videoconvert ! v4l2slvp8enc bitrate=3000000 ! queue ! matroskamux ! filesink location=output.mkv
Mali Driver
Here is the good DRM powerpoint presentation by Free Electron: https://free-electrons.com/pub/conferences/2017/kr/ripard-drm/ripard-drm.pdf
Here is the DRM video presentation by Free Electron: https://www.youtube.com/watch?v=LbDOCJcDRoo
Wayland MALI Driver
- MALI-400 R6P2 Kernel Mode Setting binary download (1.86MB, MD5 523276872A9A11D1831ACE42F95DBBB1)
- MALI-400 R6P2 WAYLAND 64-bit binary driver and binary download (179KB, MD5 1698E8C54BDC6FE0804699F545FFE793)
X11 MALI Driver
- MALI EULA document
- MALI-400 64-bit binary driver and binary download from pine64.org (1.7MB, MD5 4F56AE6FB793E7D946867942AF58FEAC)
X11 Notice
Attached are the implemented driver and library.
- lib_x11_r6p0.tar.bz2ïŒopengles upper layer libraryïŒ
- r6p0_kernel_driver.tar.bz2ïŒgpu driver codeïŒ
- sunxi_arm_video.tar.bz2ïŒ dri2 and exa video related accelerator implementationïŒ
- sunxi_drm_0622.tar.bz2ïŒdrm driverïŒ
UsageïŒ
Using drm driver not able to coexist with display driverïŒdue to utilize display relate BSP sectionïŒDrm driver able to integrate with sunxi_arm_video apply gem during cache and cache refreshïŒopen cache able to increase performanceïŒDrm driver utilize sunxi_tr BSP rotate sectionïŒnot able to public sharing with sunxi_trïŒ
Known issueïŒ
Due to rotate hardware not support crop, and majority exa accelerators operate using cropïŒsunxi_arm_video is reference code (features already verified)ïŒthis allow familiar with xorg hardware accelationïŒ If using web page and character appear vertical strip, this may not related to cache problem and may due to character library. This issue still need to further verified.
Overclocking
warning
There is the possibility of damaging your equipment by overclocking. Do so at your own risk!
note
This page is incomplete, youâre welcome to improve it.
note
All information regarding clock speeds, voltages and more are stored in the DTB (Device Tree Blob). You can learn more about it here.
Overclocking is a way to get more performance out of the system by running it at higher clock speeds than the factory default, usually while putting out more heat and using more power (You can also downclock to possibly reduce power consumption and thermals at the cost of performance). It is highly recommended that you avoid overvolting the device, as that has a high risk of damaging the hardware, hence the warning at the beginning of this page. However, just some slight overclocks without the added voltage can not only improve performance, but not carry as much risk (Still: Do at your own risk!). It should be noted however that overclocking can cause instability, so you will need to test and see what values work best with your device (There is a silicon lottery for the Pinephoneâs hardware).
A64-based devices
important
These instructions are targeting the PinePhone to simplify the explanation, however they can be used to also overclock other devices such as the Pinetab if you modify the proper DTB files.
Editing the PinePhone DTS
In order to overclock the PinePhone you will have to first convert the DTB file in /boot/dtbs/allwinner/
to a DTS file. You will see sun50i-a64-pinephone-1.2.dtb
, and also two other files with different PinePhone mainboard revisions (1.1 and 1.0). You will want to select the correct file for your PinePhone (Only choose 1.1 if you have a Braveheart, As all other consumer PinePhones use the 1.2 DTS).
Once youâve found the file, you can run the following command to convert the DTB to DTS:
dtc -I dtb -O dts /boot/dtbs/allwinner/sun50i-a64-pinephone-1.2.dtb -o /boot/dtbs/allwinner/sun50i-a64-pinephone-1.2.dts
Finally, modify the newly converted .dts file and change the clockspeeds you wish to modify. You can simply use a text editor to do so.
To convert back to DTB:
dtc -I dts -O dtb /boot/dtbs/allwinner/sun50i-a64-pinephone-1.2.dts -o /boot/dtbs/allwinner/sun50i-a64-pinephone-1.2.dtb
Afterwards you can simply reboot and check with sudo cat /sys/kernel/debug/clk/clk_summary
to see if the changes have correctly applied.
important
In the future it is possible that someone may make a driver to adjust clockspeeds of the A64 from userspace (using a config file) without the need to recompile. However, currently the only way to overclock is to either compile your own kernel, or modify just the DTB (instructions above).
GPU
Open /boot/dtbs/allwinner/sun50i-a64-pinephone-1.2.dts
(You will have to find the source of the kernel used by your distribution. There is the Pine64 kernel, and Megiâs) in a text editor following the PinePhone overclocking instructions.
Look for mali: gpu@1c4000 {
and within that block search for assigned-clock-rates = <432000000>;
The assigned-clock-rates
line should be set to 432000000
, this means that the GPU is clocked at 432MHz by default. So if you want 500MHz, set the value to 500000000
.
Save the DTS file, and recompile the DTB. In order to check if the overclock was successfully applied you can run: sudo cat /sys/kernel/debug/clk/clk_summary
.
important
The file may be slightly different and you may need to enter the values as hexadecimals
note
The GPU appears to run stable overclocked to 540 Mhz, however more testing with a wider group of devices is needed.
note
Remember to run a benchmark tool (such as glmark2-es2) to help check stability.
CPU
The stock speed of the A64 is 1.152 GHz. The A64 can be overclocked significantly, it is highly advisable not to do this unless you can also drop the voltage at the same time.
If the CPU is undervolted and overclocked at the same time, it is possible to reach similar thermals and power consumption to the stock configuration but with better performance.
Power consumption at different voltages and frequencies:
Configuration | Frequency | Voltage | Power (Screen 50%) |
---|---|---|---|
Stock | 1.152GHz | 1.30v | ~4.35w |
Stock + Undervolt | 1.152GHz | 1.18v | ~3.65w |
Overclock + Undervolt | 1.344Ghz | 1.28v | ~4.60w |
The table above contains measurements created in postmarketOS (SWMO/SXMO - postmarketOS 21.12 SP1) with the screen on (set to 50% brightness) under a threaded load.
AXP803 PMIC voltage steps on DCDC2:
Voltage range | Step size |
---|---|
0.50V-1.20V | 10mV |
1.22V-1.30V | 20mV |
The table above shows the valid voltages provided by the AXP803 PMIC on DCDC2 (used to power the cores). For example, setting the voltage to 0.60V is valid, but setting it to 1.23V is not. When overclocking, ensure that you only use valid voltages at each operation point (otherwise it will simply be dropped and ignored). You can use (after installing) cpupower to display all valid frequencies after boot.
important
The user somefoo was able to undervolt the PinePhone at each frequency operation point by at least -100mv. The A64 set to 1.152Ghz runs at 1.18v instead of the standard 1.3v, dropping the power usage by ~0.7w under full single threaded load|The silicon lottery will dictate how well you can undervolt.
note
The exact voltages and frequencies that you can achieve will depend on your device. Make sure to run stress tests (such as stress-ng) to ensure stability.
DRAM
warning
It is not recommended to exceed 667 MHz clockspeed on the DRAM. 648MHz is likely the upper limit.
note
Make sure to set your DRAM to a multiple of 24.
note
The current frequency your DRAM is running at can be found using this command:
cat /proc/device-tree/memory/ram_freq
When overclocking the GPU, it is a good idea to also overclock the DRAM, as the main bottleneck of the A64 SOC is the memory. The A64âs maximum ram clockspeed falls just short of 667MHz. This may be unstable on your device however.
Around 600 MHz (PC-1200) should work fine, however some people have reported instability at lower clockspeeds. Arch Linux Arm uses a default clockspeed of 552MHz, with U-Boot builds available to easily switch out for a higher (624) or lower (492) DRAM clockspeed.
It is possible that by reverse engineering the DRAM driver from Allwinner that auto tuning can be accomplished to get the best performance.
Setting the DRAM clock is accomplished by modifying pinephone_defconfig in U-Boot (https://gitlab.com/pine64-org/u-boot/-/blob/crust/configs/pinephone_defconfig)
You can find simple instructions on doing so here: U-Boot
VPU
In order to allocate more VRAM for the GPU you can add cma=256
to your kernel (or use kconfig with CONFIG_CMA_SIZE_MBYTES=256) cmdline in boot.scr which you will have to compile using mkimage. By default the kernel allocates only 64MB, and the maximum value is 256MB.
In order to compile boot.scr you can run mkimage -C none -A arm64 -T script -d boot.cmd boot.scr
important
You may not have a boot.cmd file in your boot directory and instead you may instead have a boot.txt
Cedrus
Overclocking cedrus is achieved by modifying the kernel source code: https://elixir.bootlin.com/linux/latest/source/drivers/staging/media/sunxi/cedrus/cedrus.c#L507
important
User 33yn2 is not particularly sure if this makes any difference, or if it might in fact have a negative impact. Probably not worth messing with.
RK3399-based devices
The RK3399 clocks are found in arch/arm64/boot/dts/rockchip/rk3399-opp.dtsi
More optimised voltages and clocks can be found in arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi These include a slight overclock and undervolt, they are intended for the OP1 CPU found in many Chromebooks but have worked fine in all recorded cases on regular RK3399 SoCs in other devices.
GPU
Any clock speeds can be added for the GPU in gpu_opp_table
The highest recommended voltage for the GPU is 1.2V as specified in the RK3399 schematic from Rockchip.
Segfault has found that the RK3399 in his Pinebook Pro can reach 950MHz on the GPU while being stable.
The stock speed for the GPU is 800Mhz.
Note that the GPU in the RK3399 is already bottlenecked by the memory bandwidth available to it, so overclocking generally yields no improvements.
CPU
A set of available clock speeds that can be added to the CPU clusters can be found in drivers/clk/rockchip/clk-rk3399.c
under rk3399_cpuclkl_rates
for the little cores and rk3399_cpuclkb_rates
for the big cores.
These clock speeds can be added to cluster0_opp
for the small cores and cluster1_opp
for the big cores respectively.
The maximum limit is 1.8GHz on the little cores and 2.2GHz on the big cores.
The highest recommended voltage for the little cores is 1.2V and for the big cores is 1.25V.
Segfault has found that the RK3399 in his Pinebook Pro can reach 1.7GHz on the little cores and 2.08GHz on the big ones.
The stock speed for the little cores is 1.4GHz and on the big cores it is 1.8GHz, the OP1 speeds default to 1.5GHz and 2.0GHz instead.
ROCK64
DTB is in /boot/dtbs/rockchip/rk3328-rock64.dtb
. CPU clock rates are inside opp_table0
as hexadecimal numbers in the opp-hz
field.
Check the achieved clock speed with sudo cat /sys/kernel/debug/clk/clk_summary | grep armclk
.
Thanks to Ayufan’s work (with their overclocking recipe), we know we can add a 1.392GHz operating point, and a 1.512GHz operating point (you should ensure you have a large heatsink for this last one). You can do so by adding the following in the opp_table0
object, after the opp-1296000000
operating point:
opp-1392000000 {
opp-hz = <0x00 0x52f83c00>;
opp-microvolt = <0x149970>;
clock-latency-ns = <0x9c40>;
};
opp-1512000000 {
opp-hz = <0x00 0x5a1f4a00>;
opp-microvolt = <0x162010>;
clock-latency-ns = <0x9c40>;
};
GPU needs investigating, but current mainline device tree does not try to clock up the GPU at all.
PineModems
PINE64 position on alternative firmware
PINE64 ships the PinePhone with a stock version of the Quectel EG25-G modemâs firmware. Some administrative regions, in the EU and Asia in particular, require the entirety of the modemâs firmware to be licensed. Therefore, the PinePhone cannot ship with an unlicensed firmware, and the PINE64 project cannot, officially encourage its userbase to use alternative modem firmware.
Quectel EG25-G Modem
Quectel EG25-G is an LTE Cat 4 module optimized specially for M2M and IoT applications. It is used in the PinePhone.
- Specifications: https://wiki.pine64.org/wiki/File:Quectel_EG25-G_LTE_Standard_Specification_V1.3.pdf
- Hardware design: https://wiki.pine64.org/wiki/File:Quectel_EG25-G_Hardware_Design_V1.4.pdf
- AT Interface reference manual:
- AT Interface file operations: https://wiki.pine64.org/wiki/File:Quectel_EC2xEG25-GEG9xEM05_FILE_AT_Commands_Manual_V1.0.pdf
- GNSS Application note: https://wiki.pine64.org/wiki/File:Quectel_EC2x&EG9x&EG2x-G&EM05_Series_GNSS_Application_Note_V1.3.pdf
Specifications
Processor Family | Qualcomm MDM9607 |
CPU | Qualcomm MDM9207 |
Cores | 1 ACPU Core, Qualcomm Hexagon DSP |
Total RAM | 256Mb |
Total flash space | 256Mb |
Available RAM for the ACPU | 160Mb |
NAND Partition table layout
Index | Name | Description |
---|---|---|
MTD0 | SBL | Secondary Bootloader, called from the BootROM. Used to start the TrustZone kernel and the Application Bootloader (LK). Also used to enter Quectelâs recovery mode |
MTD1 | mibib | NAND Partition table |
MTD2 | EFS2 | IMEI and settings used by the ADSP are stored here |
MTD3 | sys_rev | Unexplored |
MTD4 | rawdata | This is where FOTA update data exists before being commited to system or recoveryfs partitions |
MTD5 | tz | TrustZone kernel |
MTD6 | rpm | Resource / Power Manager |
MTD7 | cust_info | Unexplored |
MTD8 | aboot | Application Bootloader. Uses LK (LittleKernel, LK embedded kernel) as the bootloader. By default it allows flashing unsigned images but wonât allow booting them, soft-bricking the modem until you enter EDL mode |
MTD9 | boot | OpenEmbedded boot kernel + DTB |
MTD10 | recovery | Recovery kernel (used for FOTA updates) |
MTD11 | modem | ADSP firmware blobs |
MTD12 | misc | Some settings are stored here, along with commands that need to be picked by LK on next boot (to reboot to fastboot or recovery mode) |
MTD13 | recoveryfs | Recovery filesystem image (FOTA updates) |
MTD14 | usr_data | User data partition (/data when mounted by OpenEmbedded) |
MTD15 | sec | Used to blow fuses in the mdm9207 from images generated by Qualcomm Sectools |
MTD16 | system | Linux OpenEmbedded root image, formatted in UBIFS (Unsorted Block Image File System, Wikipedia) |
Firmware Recovery
warning
The following instructions are directed towards expert-level users and developers!
The System partition is mounted as read-only mode, but the data partition is writable. It might be possible, if thereâs an unexpected reset or power is lost while running, that the data partition gets corrupt and thus unable to boot.
The modem has 4 different boot modes:
- Normal boot
- Recovery mode (used by the modem usually to install a FOTA update)
- Fastboot mode
- Qualcomm EDL Mode
If the modem is unable to boot, depending on the type of crash, it might:
- not show anywhere (USB device missing)
- or malfunction (no radio but USB working)
- or enter EDL mode, if the entire flash is corrupt.
Boot the device in EDL mode
To check if the device is booted in EDL mode, run lsusb
(a part of the usbutils
package) in a terminal and inspect the output. You should see the following device listed:
Bus 003 Device 003: ID 05c6:9008 Qualcomm, Inc. Gobi Wireless Modem (QDL mode)
In any scenario, the modem can be triggered to enter EDL mode by shorting two test pins on the PinePhone motherboard.
- Power off the phone
- short the two test points
- boot the phone while keeping the test points shorted until fully booted up, at least until you hear the camera clicking twice (which is normally when the modem is powered).
Get the Firmware Recovery Package
The Firmware Recovery Package is at: https://github.com/Biktorgj/quectel_eg25_recovery
Either clone its repo with git, or download its archive & unzip it.
As you should have no access to the Internet on PinePhone when its modem need a Recovery, you can fetch it on other devices and copy it to the Pinephone.
Execute the Quectel QFirehose utility
Once in EDL mode, open a terminal, navigate to the root directory of the recovery package, and run:
- If you use an ARM64 distribution (most likely):
sudo ./qfirehose -f ./
orsudo ./qfirehose_arm64 -f ./
- If you use an ARMHF (32 bit) distribution:
sudo ./qfirehose_armhf -f ./
It will reboot the modem after finished. After about 30 seconds, it will get back up and running. To check the firmware version after that, use an AT command AT+QGMR
like at PinePhone.
Bootloader unlocking
warning
The following instructions are directed towards expert-level users and developers!
The Modem has a locked bootloader. It wonât allow to boot unsigned Kernel images, but will allow to flash them, making it easy to brick the modem. To fix this, you can flash an unlocked bootloader, which will then allow you to do as you please with the hardware.
Unlocked bootloader:
- Source code: https://github.com/Biktorgj/quectel_lk
- Prebuilt binary releases: https://github.com/Biktorgj/quectel_lk/releases
Custom Kernels and system images
warning
The following instructions are directed towards expert-level users and developers!
Custom kernel builds and system images can be created for the modem, though they require a couple of things to be correctly built and be bootable.
- The source code release for the kernel provided by the manufacturer is incomplete and wonât build
- Common Android tools like mkbootimg and dtbtool wonât build a bootable image, even if the kernel is correctly compiled and all the DTBs attached.
- Further, thereâs no source for the OpenEmbedded parts, so building a new system image must be done from scratch, and retrieving the mandatory binary blobs to use the ADSP part of the modem.
Thereâs a work in progress SDK to allow creating custom kernels and system images, which can be downloaded from the following repository: https://github.com/Biktorgj/pinephone_modem_sdk
See its readme for infomations and instructions. Once downloaded, you should run the init.sh
script, which will create all the base directories and download all the different repositories required to build. After the initial setup is complete, runmake
without arguments to list the available options.
Upgrade/switch firmware via fwupd
https://fwupd.org/ is an open-source tool for managing the installation of firmware on Linux systems.
fwupd >= 1.7.6 (with the ModemManager plugin) supports writing/upgrading the https://github.com/Biktorgj/pinephone_modem_sdk firmware on the Quectel EG25-G modem.
https://wiki.postmarketos.org/wiki/Fwupd discusses how to use fwupd to do this.
More context:
- https://dylanvanassche.be/blog/2022/pinephone-modem-upgrade/
- https://gitlab.com/postmarketOS/pmaports/-/merge_requests/2760
- https://gitlab.com/linux-mobile/tracker/-/issues/11
Modem management
To allow PinePhones to receive calls while the PinePhone is suspended, the modem should be kept running. ModemManager and a eg25-specific manager must be used for the eg25-manager to work correctly.
ModemManager
ModemManager “is a DBus-activated daemon which controls mobile broadband (2G/3G/4G) devices and connections”. Distributions should enable the --test-quick-suspend-resume
flag, per https://gitlab.com/linux-mobile/tracker/-/issues/12.
Context: https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/321
eg25-specific manager
Some functionality is not built into ModemManager, and is instead managed via eg25-specific software. There are two variants of this, but only one should be used.
- eg25-manager recommended, used in most distributions.
- modem-power
Testing
When a distribution makes a significant change to their modem management setup, they should consider testing the following:
- Modem is recognized by ModemManager on boot.
- Can make a call
- Can receive a call
- Can receive a call when asleep:
systemctl suspend
See also
RK3399 boot sequence
This article describes the boot sequence of the RK3399, the SoC on which the ROCKPro64 single board computer, Pinebook Pro laptop and the PinePhone Pro are based.
Boot ROM operation
After a hardware reset, the SoCâs boot ROM (BROM) starts running on CPU0, one of the Cortex-A53s on the chip. This code is stored on a block of read-only memory, likely hard-wired into the chip.
It employs 5 strategies, in order, to load a bootloader from off-chip:
- loading from NOR flash on SPI1
- loading from NAND flash on SPI1
- loading from eMMC
- loading from SD on the SDMMC controller
- bringing up the OTG0 USB controller in device mode and accepting control transfers to load programs
Loading a bootloader from storage is done in 4 steps:
- Probing the boot device
- Finding the ID block
- Loading the first stage of the bootloader to main SRAM and running it
- (if the first stage returned to BROM) Loading the second stage to low DRAM and running it
ID block
The ID block is a 512-byte block at one of several well-known locations (depending on boot device type) scrambled using RC4 with a well-known key, which begins with the bytes 0x3b 8c dc fc (ciphertext; plaintext: 0x55 aa f0 0f).
In addition to the magic number, it contains (all fields little-endian):
- a flag to RC4-scramble the bootloader images too (32b at offset 8)
- offset (in 512âŻB-sectors) of the first bootloader stage (16b at offset 12)
- the size (in 2âŻKiB blocks) of the first bootloader stage (16b at offset 506)
- the size (in 2 KiB blocks) of the second bootloader stage (16b at offset 508)
These fields can be seen in U-Boot tools/rkcommon.c.
SPI boot
The boot ROM tries to probe the device on SPI1 by issuing the SPI-NOR 0x9f (Read Identification) command.
If the type and capacity bytes are all-ones or all-zeroes, probe fails. If the first byte (manufacturer ID) is all-ones, the BROM uses NAND protocol, otherwise NOR protocol.
NOR protocol uses command 0x03 (low-frequency read without turnaround cycles) to read blocks, NAND protocol uses command 0x13.
The ID block is searched by loading the 32 bytes at the start of flash (TODO other load offsets) and testing for the magic number at any offset within those 32 bytes.
The SPI code has a bug that means that the 2âŻKiB blocks in which the bootloader is loaded have a stride of 4KiB, leaving the 2KiB inbetween as unused padding.
eMMC/SD boot
The boot ROM probes for eMMC on the eMMC controller using the normal MMC enumeration sequence (CMD0/1/2/3) at 375âŻkHz and runs the bus at 24âŻMHz, in 8-wide mode. The BROM does not support using the standard option for eMMC boot partitions.
SD is probed on the SDMMC (not the functionally equivalent SDIO) controller, using the normal SD enumeration sequence at 375âŻkHz and then runs the card at 12âŻMHz (TODO confirm) in 4-wide mode.
After initialization, eMMC and SD behave much the same. The ID block is searched by loading the blocks at sector 64 + 1024*n for n from 0 to 4 (inclusive) and checking for the magic number at the start of that sector. The BROM handles both byte- and block-addressed SD/MMC cards.
Hardware root of trust
The BROM theoretically supports SHA256/RSA2048 authentication with rollback protection.
The relevant data is stored in Secure eFuses: an enable flag, a SHA256 hash of the public key (which is stored on the boot medium) and a range of bits that are sequentially set for rollback protection.
In practice, the BROM does not verify the full length of the public key against the hash in eFuses, which means that it is most likely broken (expert review would be appreciated).
TOOD details
- FOSDEM 2023: Tomasz ƻyjewski (3mdeb) - Overview of Secure Boot state in the ARM-based SoCs, 2nd edition
- Rockchip Developer Guide Linux4.4 Secure Boot EN.pdf (zh_CN)
- Artur Kowalski (3mdeb) - Enabling Secure Boot on RockChip SoCs - December 2021
- RK3399 Efuse Operation Instructions V1.00 - 14 February 2019
USB gadget boot
If no ID block is found on SPI, eMMC or SD, the BROM sets up the OTG0 USB controller to act as a USB high-speed (480âŻMb/s) device with Vendor/Product ID of 2207:330c. In this state it supports most standard control requests, as well as 2 vendor control requests:
0x0471
The code is loaded to main SRAM. When the transfer is done, it does a function call to the load address.
0x0472
The code is loaded to low DRAM. When the transfer is done, USB is torn down and BROM jumps to the load address.
Transfer is performed by doing the requests on 4âŻKiB blocks. BROM considers the transfer complete as soon as a request supplies a block not 4096B long. (This means images a multiple of 4096 bytes long must be padded to achieve this condition.
U-Boot boot sequence
Bootloaders based on U-Boot (including Tow-Boot) run in 4 stages on the RK3399:
- TPL, loaded by the BROM into main SRAM. Its job is to initialize DRAM (main system memory). It returns to BROM. This job can alternatively be performed by proprietary Rockchip DDR blobs.
- SPL, loaded by the BROM into low DRAM. It loads the respective parts of TF-A BL31 into DRAM, main and PMU SRAM, and U-Boot proper into DRAM.
- TF-A BL31. It sets up EL2 to run U-Boot and stays resident until system shutdown.
- U-Boot proper. It can load EFI binaries (Grub, systemd-boot, âŠ) from a variety of block devices (SD, eMMC, NVMe, USB Mass Storage, âŠ).
For mainline-based U-Boots, these stages usually come in 2 images:
idbloader.img
contains TPL and SPL.
u-boot.itb
contains TF-A and U-Boot.
Load offsets
important
This section applies to BSP U-Boot. Mainline-based U-Boots pack TF-A into u-boot.itb.
There are 3 sections for the boot loader. They are in order, without gap, though their is no need to use all the space in each section.
Here are the details:
Start in sectors | Size in sectors | Name | Description |
---|---|---|---|
64 | 16320 | IDBLoader | SoC initialization code |
16384 | 8192 | OS loader | Generally U-Boot |
24576 | 8192 | TrustedFirmware-A | Â |
General maintenance
If a new U-Boot is supplied, it is generally installed similar to this:
# dd if=/boot/idbloader.img conv=notrunc seek=64 of=/dev/mmcblkX
# dd if=/boot/u-boot.itb conv=notrunc seek=16384 of=/dev/mmcblkX
Different devices
The RK3399 boots to multiple devices. Boot device selection is done in the following order, and it cannot be changed.
If a device is blank / unused, the SoC code moves on to the next device in the list.
- SPI
- eMMC
- SD card
However, whence the user boot code runs, it can then give priority to other devices, if available. The following devices are not directly bootable:
- NVMe
- USB 3
- WiFi
They can be made bootable by using one of the other devices as an initial bootloader. For example, several people have gotten their NVMe drives to be bootable with “/boot” and “/” on the NMVe. This either entails using the SPI or eMMC as the initial bootloader, with code to support PCIe NVMe devices.
Grub as the target of the bootloader
It is possible to use Grub as the target of U-Boot. This would allow;
- Selecting a different boot device
- Choosing a partition on a boot device for booting
- Different kernels
- Changes in kernel command line options
However, at present, Grub does not support the video & keyboard of the Pinebook Pro. So, any selection is done through the serial console.
Boot loader development
There are several projects that have their own versions of U-Boot, with different features. Here are some of the more common ones at present, 2020/06/14:
- Rockchip
- The original default Debian
- Manjaro
- U-Boot mainline
Bootloaders not based on U-Boot:
- coreboot runs on RK3399-based Chromebooks, it has not been ported to Pine64 boards yet.
- levinboot is a bootloader developed by CrystalGamma in the Pine64 community. It runs on RockPro64 and Pinebook Pro. Its development is on hiatus as of April 2022, but a fork porting it to the PinePhone Pro exists.
RK3566 EBC Reverse-Engineering
The RK3566 SoC, used in the Quartz64 SBC by PINE64, contains an eInk interface. This is referred to as ebc
by Rockchip apparently.
Unfortunately, the driver published for this eInk interface within the BSP kernel is an assembly dump produced by gcc. Fortunately, it contains quite a bit of debug information, which we can use to reverse engineer it.
Sources
Downstream
The ebc driver source is available from the quartz-bsp repository.
The files of interest are ebc_dev_v8.S
, which implements a DRM (Direct Rendering Manager) driver for the eInk panel, and the waveform files in the epdlut
subdirectory.
Thereâs also a simple driver for u-boot: drivers/video/rk_eink at JeffyCN/rockchip_mirrors
These two drivers show the two different programming interfaces exposed by the TCON. The U-Boot driver operates in “LUT mode”: it writes the waveform LUT to registers in the TCONâs MMIO space, and passes buffers of pixel data to the TCON. The Linux driver operates in “direct mode” uses the LUTs to compute waveforms in software, and passes buffers of waveform data to the TCON.
Some reversing of the downstream Linux driver has been done here: https://github.com/Ralim/ebc-dev-reverse-engineering
Reimplementation
A human-readable C reimplementation of the LUT and pixel data path is available from smaeul here. This provides everything needed to convert a framebuffer and a waveform data file into a series of “frames” for the panel. The new implementation includes a test suite to verify its output matches the output from the BSP assembly code. It is based on the downstream Linux driver.
In-Development Driver
rk356x-ebc-dev is the branch used for developing an upstreamable DRM driver based on mainline kernel sources. The driver currently functions well enough to get a virtual console and Xorg running, but it does not support features like multiple waveforms.
Documentation
Datasheets
EBC
The EBC TCON is documented in part 2 of the RK356x TRM.
TI TPS65185x
This is the PMIC used to drive the e-Ink panel, for which the downstream sources also implement a driver.
https://www.ti.com/lit/ds/symlink/tps65185.pdf
Waveform
The format of the waveform file is documented here:
https://www.waveshare.net/w/upload/c/c4/E-paper-mode-declaration.pdf
https://www.waveshare.net/w/upload/archive/c/c4/20190611032540!E-paper-mode-declaration.pdf
Utilities
The inkwave program is designed to parse waveform files. Currently it cannot fully handle the waveform files shipped with the PineNote. Adding support for this to the tool would be helpful.
Assembly Syntax and Semantics
The Syntax is GNU Assembler (GAS) syntax. This modexp article provides a good introduction to the syntax, calling convention, semantics and some often used instructions.
The ARM Architecture Reference Manual for ARMv8 should be used as reference for any instructions.
At the very least, you should read up on the registers and calling convention used.
Various Findings
The driver isnât really something that can be mainlined as-is once reversed, as it makes a number of questionable design decisions.
- Itâs technically a DRM subsystem driver, but doesnât really utilise what DRM provides at all.
- It seems to register a new ioctl to set buffer attributes like width and height, despite DRM more than likely having a way for clients to tell a driver what size the framebuffer should be.
- It directly interacts with the PMIC instead of going through regulators/hwmon.
However, reverse engineering to know how it works provides a good baseline from which we can rewrite it in a more sensible manner.
Debug Information
Quite a bit of debug info is left in the assembly dump, including function names, file names and line numbers. We can take this to our advantage.
.file _file-number_ _file-path_
Specifies a number to reference a file by, and its path. All following code until the next .file
or .loc
statement are to be understood as originating from this file. This is particularly useful to understand which code has been inlined from other files, for which the source is available.
.loc _file-number_ _line-number_ 0
Specifies that the following code is generated from _line-number_
stemming from file number _file-number_
. See the .file
directive for this file number to understand which source file it came from.
.type _function-name_, %function
This tells us that the following code belongs to function _function-name_
. Youâll usually see a .cfi_startproc
, which signifies the start of the function code, until the matching .cfi_endproc
.
A quick grep for %function
shows that we are dealing with 30 functions in this file.
.type _struct-name_, %object
This seems to signify a definition of a C struct named _struct-name_
.
A quick grep for %object
shows that we are dealing with around 27 structs in this file.
.Ldebug_info0:
TODO: This seems to contain the main bulk of the DWARF debug information, including enough info to reverse full structs and function signatures.
Finding Structs and Function Signatures
First, weâll need to assemble the file:
aarch64-linux-gnu-gcc -c -o ebc_dev_v8.o ebc_dev_v8.S
This gives us a ebc_dev_v8.o
which we can feed into analysis tools.
For both of these, keep in mind that weâre only interested in stuff from ebc_dev.c, or any other files for which we donât have the source. Thereâs no point in getting the struct description or reverse-engineering a function that we have the source code for. A lot more than ebc_dev will be in the object file due to inlining and such.
Also make sure that if you are looking up known struct accesses, that you use struct definitions from the BSP kernel, not from mainline. The kernel has no internal ABI for drivers!
Faster and Easier - Ghidra
Import the file into Ghidra, open the code browser. After analysis, you should be able to find structs in the “Data Type Manager” marked with an S icon. Youâll also find functions in the symbol tree.
Slow and Painful - readelf/objdump
Use this if you want to manually look up dwarf symbols for some reason.
readelf --debug-dump ebc_dev_v8.o
This will produce a lot of output, but weâre mainly concerned with the start of the dump. Weâll find things like:
<2><101f8>: Abbrev Number: 0 <1><101f9>: Abbrev Number: 79 (DW_TAG_subprogram) <101fa> DW_AT_name : (indirect string, offset: 0xa2b4): ebc_open <101fe> DW_AT_decl_file : 1 <101ff> DW_AT_decl_line : 1377 <10201> DW_AT_prototyped : 1 <10201> DW_AT_type : <0xc6> <10205> DW_AT_low_pc : 0x0 <1020d> DW_AT_high_pc : 0xc <10215> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa) <10217> DW_AT_GNU_all_call_sites: 1 <10217> DW_AT_sibling : <0x1023a> <2><1021b>: Abbrev Number: 88 (DW_TAG_formal_parameter) <1021c> DW_AT_name : (indirect string, offset: 0x1153): inode <10220> DW_AT_decl_file : 1 <10221> DW_AT_decl_line : 1377 <10223> DW_AT_type : <0x1c54> <10227> DW_AT_location : 0xd63 (location list) <2><1022b>: Abbrev Number: 106 (DW_TAG_formal_parameter) <1022c> DW_AT_name : (indirect string, offset: 0x8b06): file <10230> DW_AT_decl_file : 1 <10231> DW_AT_decl_line : 1377 <10233> DW_AT_type : <0x551f> <10237> DW_AT_location : 1 byte block: 51 (DW_OP_reg1 (x1))
This essentially tells us the full function signature of ebc_open
:
DW_TAG_subprogram
tells us of a function, with DW_AT_name
letting us know that this is ebc_open
. DW_AT_type
of 0xc6
letâs us know, once we jump to <c6>
, that this functionâs return type is a signed 32-bit integer.
The DW_TAG_formal_parameter
that follow tell us of each of the parameter the function takes. The first one is called inode
and is of type 0x1c54
. Referencing what this type is, we find:
<1><1c54>: Abbrev Number: 7 (DW_TAG_pointer_type)
<1c55> DW_AT_byte_size : 8
<1c56> DW_AT_type : <0x1970>
which in of itself goes on to reference 0x1970
, and looking this one up, weâll find a struct definition:
<1><1970>: Abbrev Number: 26 (DW_TAG_structure_type)
<1971> DW_AT_name : (indirect string, offset: 0x1153): inode
<1975> DW_AT_byte_size : 672
<1977> DW_AT_decl_file : 31
<1978> DW_AT_decl_line : 611
<197a> DW_AT_sibling : <0x1c4f>
<2><197e>: Abbrev Number: 27 (DW_TAG_member)
<197f> DW_AT_name : (indirect string, offset: 0x7d00): i_mode
etc.
Reverse-Engineered Stuff
Structs
ebc_info
See https://gitlab.com/smaeul/ebc-dev/-/blob/main/auto_image.h#L124, which is based on the v1.04 BSP Linux driver.
ebc
See https://gitlab.com/smaeul/ebc-dev/-/blob/main/auto_image.h#L200, which is based on the v1.04 BSP Linux driver.
rkf_waveform
note
all known waveform data files are the “PVI” variant, not the “RKF” variant.
struct rkf_waveform {
int length,
char[16] format,
char[16] version,
char[16] timeandday,
char[16] panel_name,
char[16] panel_info,
char[64] full_version,
char[64] reset_temp_list,
char[64] gc16_temp_list,
char[64] gl16_temp_list,
char[64] glr16_temp_list,
char[64] gld16_temp_list,
char[64] du_temp_list,
char[64] a2_temp_list,
uint[64] reset_list,
uint[64] gc16_list,
uint[64] gl16_list,
uint[64] glr16_list,
uint[64] gld16_list,
uint[64] du_list,
uint[64] a2_list
}
Enums
rkf_waveform_type
enum rkf_waveform_type {
RKF_WF_RESET = 0,
RKF_WF_DU = 1,
RKF_WF_GC16 = 2,
RKF_WF_GL16 = 3,
RKF_WF_GLR16 = 4,
RKF_WF_GLD16 = 5,
RKF_WF_A2 = 6
}
U-Boot
tip
It is helpful to have a debugging serial cable for this.
Building U-Boot manually
Prerequisites
These instructions are written with a host Arch Linux desktop system in mind.
This guide will be especially useful if you are looking to overclock the ram on your PinePhone following the information found here.
You must have these packages installed: dtc swig bc aarch64-linux-gnu-gcc
If you are using a different system such as Ubuntu, there are plenty of cross compilation instructions available online with which you can grab the needed package names from, however you should be able to follow these instructions with these packages installed: build-essential bison flex swig gcc-aarch64-linux-gnu
Compilation
tip
This guide is written with the PinePhone in mind. On other devices you will need to set a different platform variable and likely use a different U-Boot source with patches oriented towards your device.
Note by default these instructions utilize all of your computers cores to compile thanks to the -j
and $(nproc)
parameters. If you wish to only use one core to compile, or change the number of cores used for example to only two cores, then you can either completely remove the -j$(nproc)
parameter from the make commands, or just take off $(nproc)
and add the number of threads you want used in itâs place: -j4
First, You need to compile the ATF (Arm Trusted Firmware):
git clone https://github.com/crust-firmware/arm-trusted-firmware/
cd arm-trusted-firmware
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64
make PLAT=sun50i_a64 -j$(nproc) bl31
cd ..
After the ATF is compiled clone u-boot and copy the bl31.bin file into the u-boot directory.
git clone https://gitlab.com/pine64-org/u-boot.git
cd arm-trusted-firmware
cp build/sun50i_a64/release/bl31.bin ../u-boot/
cd ..
tip
You cannot build Crust if you do not have the or1k musl toolchain installed. This toolchain is not usually available in distribution repositories and will have to be manually installed to the system. The following text will show a simple way to install the toolchain.
Download the toolchainâs archive: https://musl.cc/or1k-linux-musl-cross.tgz
Extract the compressed archive: tar zxvf or1k-linux-musl-cross.tgz
Move the extracted archive to wherever you would like to install the toolchain to. In these instructions it will simply be installed to the users documents folder.
The final step is to edit your .bashrc
and add the following to the end:
# Path for or1k toolchain
export PATH="$PATH:/home/USER/Documents/or1k-linux-musl-cross/bin/"
After youâve completed that you can close out the terminal and reopen it and proceed to the following instructions.
git clone https://github.com/crust-firmware/crust
cd crust
export CROSS_COMPILE=or1k-linux-musl-
make pinephone_defconfig
make -j$(nproc) scp
cp build/scp/scp.bin ../u-boot/
cd ..
tip
If you do not wish to have Crust in your U-Boot build, then you can skip exporting SCP
cd u-boot/
git checkout crust
export CROSS_COMPILE=aarch64-linux-gnu-
export BL3bl31.bin
export ARCH=arm64
export SCP=scp.bin
make distclean
make pinephone_defconfig
make all -j$(nproc)
U-Boot installation
Once successfully compiled you can proceed to flash the device
warning
Replace [CHANGE THIS] with the location of your SD card and make sure you are using the proper location. Failure to do so can result in data loss.
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/[CHANGE THIS] bs=1024 seek=8
tip
If you are compiling U-Boot in order to overclock your DRAM you can check if it was successful by reading the values of /sys/kernel/debug/clk/clk_summary
p-boot multi-bootloader
One of the smallest and fastest PinePhone bootloaders, it was developed by Ondrej Jirman with the ability of booting multiple distributions on the PinePhone in mind.
More information can be found here