Running postmarketOS on Orange Pi 3


See bottom of the page for useful links.


Because Armbian (which is the only real distribution with mainline kernel for that board) stands on my way with all that unneedeD garbage. And because I like small and simple systems.


When I initially understood that Armbian is definitly not for me, I tried to find an alternative - but there was no other distros available for my board except LibreELEC, which doesn’t suit my needs.

First, I tried to port Void Linux, which I was using on my laptop back then, but I quickly figured out that it’s mklive infrastructure is pain to work with, and I gave up.

Then, after a few month, when I was already familiar with Alpine (which is now my favorite distro) and postmarketOS, I decided to give it a try.

Introduction to porting

Previously I have ported pmOS with downstream kernel to Samsung Galaxy Premier, so I already knew where to start.

Generally, checklist for porting pmOS to device with pre-existing mainline support is as follows:

  1. setup your environment
  2. create a device package
  3. build and test
  4. sumbit patches to pmaports

In my case everything was a lot harder.


There was a few things required for port to work:

  1. U-Boot built for that board
  2. Kernel with some out-of-tree patches


I had to add support for orangepi_3 to Alpine’s u-boot aport. That was fairly easy, but I had to refactor Alpine’s (and pmOS’ as well) arm-trusted-firmware to get TF-A for sun50i_h6.


There was already a linux-postmarketos-allwinner package in pmaports built from Megi’s tree with some useful patches included for Orange Pi 3, namely for HDMI audio and Ethernet support. I just had to spend a few hours finding out and enabling required kernel config paremeters.


Everything was ready, so I quickly wrote a device-xunlong-orangepi3 and firmware-xunlong-orangepi3 packages and fired up pmbootstrap install, but board didn’t boot. Fortunately, I bought a USB-TTL cable beforehand, so I could get U-Boot and kernel logs. In two evenings I figured out that Linux doesn’t see both SD and eMMC and found a patch in LibreELEC’s tree that fixes an issue.

Now the port was functional, and I began using my board as a router and IRC bouncer.

However, later, when I got to my PC and wanted to connect it to Orange Pi 3 via Ethernet, I found that Ethernet is broken.

There was some kernel options missing, but enabling them didn’t solve the issue completely. After an evening of troubleshooting and searching, I found the issue (TF-A was enabling aldo2 regulator when it must be enabled strictly simuletaneously with another one by Linux kernel), and the workaround, which was unacceptable (using old ATF 2.2), so I emailed Megi to ask if there was anything better:


On Mon, Aug 23, 2021 at 07:49:08PM +0300, Maxim Karasev wrote:
> Hi, sorry for troubling, but it seems that you're the most aware of this. I've
> ran into an issue with stmmac faililng to attach to PHY. I found downgrading
> arm-trusted-firmware to 2.2 as a possible workaround, but is there still no
> better fix?

No fix. Mainline TF-A has a broken behavior - it enables all used AXP regulator
outputs, without much reason.

I carry around this patch to make it not do that:

diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
index e98b16fdb..111a4d0d7 100644
--- a/drivers/allwinner/axp/common.c
+++ b/drivers/allwinner/axp/common.c
@@ -98,8 +98,9 @@ static int setup_regulator(const void *fdt, int node,

 static bool should_enable_regulator(const void *fdt, int node)
-       if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
-               return true;
+//XXX: no need to enable referenced regulators
+//     if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
+//             return true;
        if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
                return true;
        return false;

And that fixes the issue for me.

This patch has been rejected upstream because it would break booting some other
boards via U-Boot, that rely on having some regulators enabled indiscriminately
by TF-A, because U-Boot lacks the regulator driver that TF-A implements.


That was not so terrible as previous workaround, but still unacceptable for packaging.

After some evenings of unsuccessfull attempts to package this mess, I took a look at TF-A’s sources and came up with a better solution: it’s possible to disable a regulator in U-Boot’s DTB and then TF-A won’t touch it. This way I’ve built a correctly working U-Boot and got Ethernet fixed…

…Well, not actually. Link was up, but there was completely no data flow. After yet another evening of troubleshooting, I found and adapted for pmOS another patch from LibreELEC’s tree. This time, everything finally started working.

Ethernet patch to linux-postmarketos-allwinner was accepted quickly, but U-Boot patch is still pending. I’ve sent it to aports, and after recieving feedback sent it to U-Boot’s mailing list as well. Port may be considered fully functional when one of this is accepted.

For installation instructions and more info, read below.

See also