2026–07–12:
levinboot-revived 1.0.0 release – Fastest Pinebook Pro and Pinephone Pro GUI
bootloader
I finally have a new levinboot release ready. It's a pretty big one, so
I gave it a version bump to 1.0.0 and a slightly different name:
levinboot-revived. :) I guess it's fair to call it that, because
original project has been quite dormant for a while, and this release brings it
back with a lot of new stuff.
For those who don't know, levinboot is a very fast bare-metal bootloader for
RK3399 platforms like RockPro64, Pinebook Pro, and now also Pinephone Pro. My
main goal was to make it much more practical to use on the Pine64 devices
I care about, by adding a standard boot flow, display support, and an on-screen
boot menu.
You can find the code at the usual place: https://xff.cz/git/levinboot/
The new version also comes with pre-built binaries, ready to use. It's best
used with rk2aw which will layer a few important features on top of levinboot,
or rather before it, like ability to have a backup bootloader, select USB mask
ROM recovery mode, and dead battery charging fix for Pinephone Pro.
What's new
The big theme of this release is making levinboot behave like a normal,
civilized bootloader, while keeping the speed that makes it interesting.
New levinboot versions probe storage and display boot menu instantly upon
pressing a power button, and with fast eMMC storage, levinboot can still achieve
200–400ms boot times even with large kernel or initramfs images.
FAT32 / extlinux.conf boot flow
The old levinboot expected a custom payload partition with a specific GUID
and a monolithic compressed blob that contained ATF, kernel, DTB and initramfs
all packed together. That was very fast to load, but also very annoying to set
up and modify, especially for multi-boot use cases.
Starting with this release, levinboot uses a standard FAT32 boot partition
with /extlinux/extlinux.conf, just like U-Boot or p-boot 2.0. It
scans GPT partitions with the legacy BIOS bootable attribute set, mounts the
first one read-only, and parses the config. Example:
default arch
timeout 30
label arch
menu label Arch Linux
linux /Image.gz
fdt /rk3399-pinebook-pro.dtb
initrd /initramfs.img
append console=ttyS2,1500000n8 root=PARTUUID=... rw
Compression is now selected per file by extension: .gz,
.lz4, or .zst. Uncompressed files work too. The old
--payload-initcpio option and the custom payload partition format
are gone. SPI payload loading from dramstage is also gone, though SPI flash can
still hold levinboot itself.
Pinebook Pro display
and graphical boot menu
The Pinebook Pro build now brings up the internal eDP panel and shows a
simple graphical boot menu. No more guessing which entry is going to boot, and
no serial cable required to pick a different one.
Here's what it looks like in action:
Pinephone Pro support
This is probably the most personally important part for me, since I've been
running my own private levinboot port on my Pinephone Pro phones for a long
time, although without display support. This release adds that support and
pushes the levinboot usability closer to p-boot.
The Pinephone Pro build boosts the USB input current limit early, drives the
notification LEDs, and uses the volume keys and power key to control a graphical
menu on the phone.
Pinephone Pro booting from eMMC:
USB boot for Pinephone Pro
For development, USB mask ROM loading is still the fastest way to iterate.
The release supports a new, convenient self-contained --boot mode
in usbtool that computes the payload layout for you dynamically,
and passes it to the dramstage bootloader. All you need to do is to select mask
ROM USB mode in rk2aw and then run usbtool with simple --kernel,
--dtb, --tfa, --initramfs, and
--cmdline parameters. No magic numbers to remember, and no need to
keep sramstage/dramstage blobs around, because those are embedded to
usbtool during build. Great for testing kernel changes when
debugging Linux kernel issues.
Here's a Pinephone Pro booting levinboot over USB:
Cleaner build and quieter boot
A few things that should make the project easier to build and use:
--board is now required and accepts a single board:
rp64, pbp or ppp. The old runtime board
detection is gone, which simplifies the code.
- a build no longer needs an external TF-A checkout.
- New
--no-info flag suppresses routine info messages, giving a
much quieter boot. Recommended for headless targets like RockPro64 for which
levinboot presents a nice serial console menu in this case (without all the
normal debug output clutter).
- The startup banner now includes the git version and build date.
I also removed some legacy levinboot behaviors that were getting in
the way:
- The 500 ms power-button hold that switched to the next boot medium is gone.
The boot menu and board-specific keys handle that now.
- The SAR-ADC recovery-mode check in early assembly is gone. Use rk2aw,
it's better for recovery anyway, because it allows you to select backup
bootloader or mask ROM USB mode via a LED menu with feedback and poweroff on
failure to select anything. (you really don't want silent mask rom mode to
trigger inadverently and drive your battery to 0% for no reason.)
- SD card initialization now checks the card-detect GPIO and skips the
controller probe when no card is inserted. Faster and less noisy in the long,
than trying to init a missing card.
Better DRAM payload layout
levinboot now relocates dramstage to 1 MiB from the start of DRAM and loads
the kernel Image at 2 MiB, correctly aligned. The DTB and initrd are packed
above the kernel's full runtime footprint on 2 MiB boundaries. This removes
the old silent 60-something MiB kernel size limit and fixes the „misaligned
image“ warning Linux used to print. Initramfs limit also radically increased,
because all scratchpad areas in DRAM are located at the end of DRAM, so
there's nothing in the way of real boot payloads from 2 MiB offset onwards
almost towards the end of DRAM anymore.
License change
Because the FAT32, vconsole, extlinux and other code is ported from p-boot
2.0 which is GPL-3.0 licensed project, and also due to massive amount of other
changes, I decided to re-license levinboot under GPL-3.0+. Original author made
this possible by the choice of releasing levinboot to public domain None of the
above would be possible without Jona Stubbe's (CrystalGamma) original work on
levinboot, and this will ensure the new project stays open.
Devices and status
- Pinebook Pro (
pbp): eDP panel boot menu,
SD/eMMC boot. Power button for menu entry selection and confirmation (long
press).
- Pinephone Pro (
ppp): MIPI DSI panel boot menu,
SD/eMMC boot, volume keys for entry selection.
- RockPro64 (
rp64): serial-console menu,
SD/eMMC boot.
NVMe boot is still configurable at build time but I did not have a way to
test it. Pinephone Pro doesn't have NVMe, so this only matters for
RockPro64/Pinebook Pro users who want to boot the kernel from NVMe after
levinboot itself loads from SD/eMMC/SPI. My only NVMe I had freely available
for random testing is bricked, and at todays prices, sorry, you'll have to test
it yourself if you care about this boot path. RockPro64 status is also somewhat
untested for this release. I tested it early before adding display support, and
I'm not sure it still works. It's not a primary target board for me, so I did
not want to delay release for it. Pinebook Pro build is tested on the older
Pinebook Pro variant I have access to, and I'm unaware of anything that would
prevent the build from working on newer variants. I just wanted to lay out
where the testing stands.
I've been using the Pinebook Pro and Pinephone Pro builds as my daily
bootloader for a while now and they're working well for me. If you try it out,
let me know how it goes.
Happy fast booting. :)
The code can be found at https://xff.cz/git/levinboot/
For installation instructions and pre-built binaries, go to: https://xff.cz/git/levinboot/tree/dist
(or git clone from https://xff.cz/git/levinboot/ and go to
dist/ directory)
And I'll be back soon with major updates about p-boot 2.0, release of which
I've been preparing early this year and is almost ready. :-)