How I tricked the cable mafia with PXE. Install OpenWRT on APU4d

06 Apr 2021 · Four minute read · hardware, homelab, openwrt, pixiecore, apu4

I am too lazy to buy a cable or another adapter. But not to buy an APU4d. A specialized for networking hardware with AMD Embedded G series GX-412TC, widely used for routers.

I got it directly from the manufacturer PC Engine. With a serial-USB cable and a Huawei Lte miniPCI chip.

I have also got the 16GB mSata SSD module because you never know, having a 16GB SSD, 4GB of RAM router sounds like an opportunity to run more tools on it!

Picture of the APU4D board from PC Engine

I assembled all of it nicely at my desk. It was too late when I realized I don’t know how to flash an mSATA SSD because I don’t have proper cabling…

No matter how big the box with all my cables and dongles is, I will never own the one I need. It is a mantra nobody can escape. The best you can do is to trick the system.

Luckily for me, the APU4d supports PXE booting, and we know how cool it is, perfect opportunity to try pixiecore and have some fun with netbooting.

It worked. If all of this sounds unreasonable, you need to remember that most likely you are right. But you know how much I like simple tools. Pixiecore was on my radar.

Get what you need

First of all, I installed Pixiecore. It is a Go binary, you can run it as a Docker container or, you can compile it with go build but I decided to use Nix shell:

nix-shell -p pixiecore

In practice, it is a program that helps you to serve what a piece of hardware needs to PXE boot over the network, it servers IPXE and a TFTP server for example. It is light and not intrusive. You can keep your DHCP server, and if you like, even implement an API to drive how and what to PXE boot dynamically. Today I have to boot only one server in a very boring network. My solution is already too overly engineered. I decided to run it in static mode:

sudo pixiecore boot ./vmlinuz-vanilla initramfs-vanilla \
    --cmdline='console=ttyS0,115200n8 alpine_repo= modloop='

The first two arguments of the command line are the Alpine init ramdisk and the kernel. I got them directly from the Alpine repository.

The --cmdline option can be used to pass configuration to the operating system. The Alpine netboot wiki page to know the various options supported by the init script.

Now that I have set the PXE distribution tool, I powered on the APU4d board. By default, it tries to boot from a couple of different devices. The last one is PXE mode.

sudo pixiecore boot ./vmlinuz-vanilla initramfs-vanilla --cmdline='console=ttyS0,115200n8 ssh_key= alpine_repo= modloop='
[DHCP] Offering to boot 00:0d:b9:5a:3e:10
[DHCP] Offering to boot 00:0d:b9:5a:3e:10
[TFTP] Sent "00:0d:b9:5a:3e:10/4" to
[DHCP] Offering to boot 00:0d:b9:5a:3e:10
[HTTP] Sending ipxe boot script to
[HTTP] Sent file "kernel" to
[HTTP] Sent file "initrd-0" to is the IP the APU4 got from my DHCP. Everything is working and from the serial port I see Alpine booting, the root password is root! Classy!

Time to install OpenWRT

I never used OpenWRT before. It is a Linux distribution for routers. You can even flash it to TP-LINK or Netgear devices if supported, at your own risk.

Anyway, since I am now running Alpine in memory on my APU4d I have a functional operating system and access to the device. I can use traditional tools like dd to write OpenWRT directly to disk, manipulate partitions and, so on… I followed the blog post “OpenWRT installation instructions for APU2/APU3/APU4 boards” written by TekLager.


My router looks up and running. I was able to reach the administrative Web UI. I didn’t use it yet because I have to relocate it to my new house. So I am sure you will read more about it in future articles.

Pixiecore was on my TODO list because those days hardware, datacenters automation are taking a good part of my daily working activity. Its support for external API makes it a great alternative to provide an installation environment like Hook (the one we developed with Tinkerbell) without having to onboard the full Tinkerbell stack, in particular, I can avoid boots when not needed.