rk2aw loader
============

rk2aw loader program can be used on various modern Rockchip SoCs to change
apparent boot ROM bootloader load order from original and inflexible "SPI NOR
flash -> eMMC -> SD card" to "SD card -> eMMC -> SPI NOR flash" and to implement
robust, seamless A/B bootloader updates in SPI NOR flash with user selectable
fallback (via a pre-boot menu).

See https://xnux.eu/rk2aw/ for video demonstration.


Benefits of rk2aw
=================

Major benefits:

- Ability to run any bootloader from removeble SD card even if you break both
  primary and fallback bootloader in SPI NOR flash or in soldered on eMMC, without
  having to do anything other than inserting a SD card.

  (You can use this ability to easily test bootloaders, without having to erase
  the main bootloader you use on your device, or try distributions that provide
  their own bootloader. This is extremely valuable on devices that don't give
  easy access to disabling eMMC or SPI NOR flash during boot.)

  All bootloaders are supported in any combination without modification. You
  can have Pinebook Pro with FOSS U-Boot as a backup bootlaoder in SPI NOR flash
  for its extensive features and HW/OS support, along with Levinboot as main
  bootloader for its extreme boot speed loading Linux measured in low hundreds
  of milliseconds, and still be able to boot factory Android image from microSD
  card for HW testing using BSP U-Boot/kernel just by popping the SD card in.
  Distros that include their own GUI menu enhanced bootloader, like megi's
  multi-distro image for Pinephone Pro will also just work as expected, instead
  of failing miserably because some old Tow-Boot build on your device tries
  to boot them and fails, while perfectly suited bootloader on the SD card
  is ignored.
  
  rk2aw makes all this possible, and easy

- Button + LED based user interface (rk2aw boot menu):

  - Uniform UI across all supported devices. The control button is always the
    power button, and most devices have some kind of indicator LED that can
    be flashed, to provide visual feedback.

  - Perfect for handheld devices. To enter the menu, you just need to keep
    holding the power button when powering up the device, until the LED indicator
    stops flashing. Then you can short press the same power button to cycle
    through menu items, and long press it to confirm the selection.

  - Can be used to control boot order (eg. to select boot from fallback bootloader
    in SPI NOR flash) or enter Rockchip maskrom USB mode.

  - Only available on devices with enhanced rk2aw support, because UI depends
    on board specific features.

- Robust SPI NOR flashing tool for implementing primary/backup bootloader
  scheme, and for safe upgrades.
  
  - Updating bootloader in SPI NOR flash is very tricky. Between Rockchip SPI
    driver bugs that make the driver return fake data that were not written
    to the flash at all, or to refuse certain writes, and in general erases
    happening in large blocks of data and writes happening per individual bytes,
    it's very easy to just end up flashing just enough of a bootloader image
    that BROM thinks it's ok to boot it, but not enough so that it doesn not
    crash the CPU during boot, resulting in un-bootable system.

  - rk2aw includes a SPI NOR flashing tool, that works around the known Linux
    driver issues and performs bootloader updates in such an order that
    interruption of the process at any time can't result in unbootable system.
    
  - Even rk2aw is protected by first being flashed to a backup location, before
    erasing the primarly location for the update. If anything fails after erase
    and before flasing, rk2aw will just run from backup location.
  
  - Flashing tool also automatically adjusts layout of bootloader images to
    fit erase block sizes of the particular flash chip, so that bootloaders
    and rk2aw itself can always be erased independently without affecting
    each other.
  
  The whole flashing process is designed to be as safe as possible, so that
  it's possible to eg. work on Pinebook Pro bootloader from the notebook itself,
  and safely test the updates even without access to a micro SD card.

- Support for installation to eMMC, SD card and SPI NOR flash.

  - SD card can be used for rk2aw development / testing on new boards and
    experimentation.

  - eMMC installation is useful if the board doesn't have SPI NOR flash, and
    eMMC is soldered on board, and hard to disable from booting.

  - SPI NOR flash installation is preferred if the board includes SPI NOR flash,
    because SPI NOR is first in Rockchip BROM bootloader load order.

  In general, you want to install rk2aw to the highest priority boot device
  you have available on the board.

- Fixes for BROM bugs and general SoC issues:

  - Fix for RK3399 boot ROM SPI NOR flash access bug. (You don't need special
    TPL/SPL image for SPI, you can use the same image you use for SD card/eMMC).
    This saves 50% of valuable space in SPI NOR flash, that would otherwise be
    wasted.

  - Fix for JTAG mis-detection on RK3588 on SDMMC0 pins.

- Device specific enhancements and quality of life features:

  - Some devices are by HW design unable to stay powered off when plugged to
    a power source. (eg. Pinephone Pro) This by itself can lead to issues ranging
    from annoying, to severe (boot loops and inability to charge a completely
    discharged battery). rk2aw builds for these devices detect the situation
    when the device is powered up by plugging it to a power source (as opposed
    to powerup due to user pressing a power button) and pause the boot in a
    very low power state, waiting for either user input (to continue boot),
    or for power cable unplug, at which point rk2aw powers off the device.

    This by itself solves charging issues on Pinephone Pro even without any
    bootloader involvement. You can use your old broken Tow-Boot, and not
    worry about low battery at all.    

    On Pinephone Pro, rk2aw also raises USB input current limit to 850 mA, which
    is safe for USB 3.0 ports and all charges, improves charging speed greatly,
    and makes boot process more stable when the battery is fully discharged.

  - Very fast hard reboot on devices that require it after soft reset (RK3399
    devices). This speeds up U-Boot boot times, because hard reset can be done
    very early during boot. Normally it would be done quite late in U-Boot
    SPL after DRAM initialization, necessitating a useless DRAM retraining.


Supported boards / SoCs
=======================

Basic support for any RK3399, RK3566, or RK3588 based device, and enhanced
support for many existing Rockchip SoC based devices:

  - Pinephone Pro
  - Pinebook Pro
  - Pinetab 2
  - Quartz 64 Pro
  - Quartz 64 A
  - RockPro 64
  - Orange Pi 5 Plus


How rk2aw works
===============

rk2aw extends BROM (boot ROM) with a simple user interface, that you can use to
affect the boot process in various ways. Access to the user interface is board
specific, but usually the menu is controlled via the same button you power on
the device with, and feedback is provided by blinking an onboard LED.

If supported, rk2aw will first consult PMIC (power management IC) to check
the power on reason. If power on was due to USB power plug in, rk2aw will
hold boot in an initial fairly low power state, and it will just blink the
indicator LED in a 1s period with 50% duty cycle, until one of these two
things happen:

  - power button is pressed
  - USB power is removed

Absent any user interaction, rk2aw will try loading a bootloader from SD card,
then from eMMC and last from SPI NOR flash. (this is a normal rk2aw boot mode)

The menu can be entered by holding the power button during powerup. First you'll
see and indication that rk2aw is present and is detecting an intent to enter the
boot menu (indicator LED will flash very fast for 1.5s). You can release the button
at any time during this period to proceed with normal boot and to not enter the
menu.

After 1.5s, rk2aw will indicate that you can release the button, by stopping
the LED flashing. If you'll hold the button too long, you'll typically just force
power off the board via a PMIC power key long press poweroff feature (typically
after 6s). If you release the button before forced power off, indicator LED will
flash N times quickly each second to indicate currently selected menu item.

Menu items have a fixed meaning:

  1) Perform a normal rk2aw boot.

  2) Boot from a primary bootloader on a boot device rk2aw was installed to
     (SPI NOR flash or eMMC). SD card boot will be skipped, even if there's
     a working bootloader there.

  3) Boot from a backup bootloader on a boot device rk2aw was installed to.

  4) Enter Rockchip mask ROM USB mode.

You can confirm the menu item by long pressing the power button. The same mechanism
applies as for menu entry: fast flashing indicates that you should keep pressing
the button, and you can release it any time after the flashing stops. Very long
power key press will again cause a forced power off of the device. rk2aw waits
until you release the power button. This is meant to make it compatible with
bootloaders that have their own use for power button, like Levinboot. Without
this feature, it would be hard for you to time the power button presses to make
both rk2aw and Levinboot happy.

At this point, rk2aw is completely gone from the system, overwritten by whatever
bootloader was now loaded by BROM to replace it, and perform the actual boot of
the OS. rk2aw is not a memory resident software during the runtime of the OS.


Overall, this gives you great bootloader flexibility, safe bootloader updates and
very simple recovery options. If bootloader update fails, you can just press
a power button a bit longer and boot using a known working backup bootloader
from SPI NOR flash. You can also easily test bootloader builds or recover the
board by placing flashing bootloader to SD card and using it directly, without
having to erase or disable your primary bootloader. It also frees you from all
device specific, error prone hacks (shorting data pins, or clock signals to
ground, for not too short, but not too long either, etc.) that are used by board
makers to froce boot from SD card for recovery or bootloader installation
purposes.

Basically, this makes Rockchip SoCs behave like Allwinner SoC's as far as boot
order goes. Thus the name of the project. :)


Technical details
=================

There are many boot block locations that Rockchip BROM tries to boot from.
All these locations are tried by boot ROM in the given order:

- 13 locations on SPI NOR flash at sectors (4 << (N-1)) & ~7  for N = 1..13
- 5 locations on eMMC at sectors 64 + ((N-1) * 1024)  for N = 1..5
- 5 locations on SD card at sectors 64 + ((N-1) * 1024)  for N = 1..5

(sector size is 512 bytes)

rk2aw is primarily meant to be flashed to the first boot location on SPI NOR flash,
or if SPI NOR flash is absent, to the first boot location on eMMC.

That way it will always be executed by BROM immediately after powerup, before
any other boot locations are tried. It will then make BROM try to boot from
locations 1-5 of uSD card, 1-5 of eMMC, and 2-13 of SPI NOR flash (only when
booted from SPI NOR flash) in that order.

Boot process is identical to a normal Rockchip SoC boot process. You flash TPL+SPL
(idbloader.img) to a boot block and U-Boot (u-boot.itb) to a regular location.
There are no special requirements or limits placed on the bootloader by rk2aw.
rk2aw is completely transparent to the bootloader during the boot process.

Beware that U-Boot SPL has location of main U-Boot hardcoded in SPL code and
optionally also in SPL device tree. If you want to have multiple U-Boot builds
on a single storage device, you'll need to flash idbloader.img images to two
different boot blocks, and point each SPL build to a unique location where
you flashed each u-boot.itb image.

Typeical U-Boot builds configure SPL to look for u-boot.itb at sector 16384
of the same storage device SPL itself was loaded from (in case of SD card or
eMMC).

For example, you can have this layout on SPI NOR flash:

  - rk2aw at sector 0
  - idbloader.img for U-Boot 1 at sector 512
  - idbloader.img for U-Boot 2 at sector 1024
  - u-boot.itb for U-Boot 1 at sector 2048
  - u-boot.itb for U-Boot 2 at sector 6144

rk2aw doesn't care, but U-Boot SPL must be able to locate the correct u-boot.itb.

rk2aw flashing tool automatically adjusts SPL device tree during flashing, to make
U-Boot SPL find u-boot.itb at the location it was actually flashed to. You don't
need to configure U-Boot build in any special way to use U-Boot with rk2aw
"dual bootloader in SPI" setup.

On eMMC, or SD card you can use boot location 1 (sector 64) for your bootloader,
so you don't need any special U-Boot configuration either. Default U-Boot build
for your board will work fine.

Levinboot doesn't have these issues, because it's very lean. You can just flash
it to any boot location directly, and that's it. It's a single image bootloader.


Author / Distribution
=====================

rk2aw was written by Ondrej Jirman <megi@xff.cz> 2023

See LICENSE file for licensing information.

See https://xff.cz/kernels/rk2aw/ for updates.

See https://xnux.eu/log/ for various mostly Pinephone related low level development news.

PGP key: https://xff.cz/key.txt

You can donate money, if you appretiate the project: https://xnux.eu/contribute.html
