Producing a bootable Alpine image for Macchiatobin SIngle and Double Shot
Use proper error message when failing signature validation
Remove unnecessary kernel download
Bump to kernel 5.10.19


browse  log 



You can also use your local clone with git send-email.


Produces a router-focused Alpine build for AARC64 systems.

#Supported Systems

Most of the work involved in adding a new system is just tuning the kernel configuration for that system.

Currently, we can produce images for:

Note that for the RockPro64, the kernel is tuned specifically for my needs, and it may not work for you.


  1. Debian running on an existing AARCH64 system to use for building (cross-compiling has been problematic).
  2. Some way to write data to a MicroSD card.
  3. Oh right: a spare MicroSD card, with an MSDOS partition table (GPT can cause issues), and a single partition of at least 550MB in size, formatted as either ext4 or FAT32.
  4. Some spare time
  5. Decent knowledge of Linux. Lots of things won't be covered, like how to connect to a serial console.
  6. If using a RockPro64: you almost certainly want to pick up one of their eMMC modules (>=4GB)


  1. (Optional) Update U-Boot for your system. Solid Run provides instructions for the Macchiatobin, and for the RockPro64, you should just use Ayufan's latest release
  2. Get your Debian-based arm64 building system online
  3. Check out this source tree, and copy it to the host (or just check it out directly on the host, your call)
  4. Kick off the build by running bash build-image.sh -t <platform>
  5. Explode the tarball produced by the build into the root of the partition on your MicroSD card

(When upgrading, you want to wipe everything from the partition and explode into an empty filesystem.)

You should now be able to put this MicroSD card into your system, power it on, and 30-45 seconds later, you'll have an Alpine prompt! For the RockPro64, there will be a console on both HDMI and the serial console. For the Macchiatobin, this will only be on serial.

From here on, you can follow the usual Alpine installation instructions.

#POLA Violations

This is very much a self-serving project, so there's a very good chance you'll be surprised by some things in here. Specifically:

  1. This is using nftables only. No iptables support is in the kernel.
  2. If it's not a networking-related technology, there's a pretty good chance it's not supported. This is designed as a router specifically, so there's nothing like audio support included.
  3. Most NICs aren't supported. For self-contained systems, all built-in hardware should work. For SBCs with expansion ports, I'm adding only the devices I use.


All the things I'd like to change but haven't gotten around to yet:

  1. Add more packages in the base distribution. Specifically, I'm looking at adding nftables for firewall management, tcpdump and ethtool to troubleshoot network issues, and ... I forget the rest, but I have them noted down ... somewhere.
  2. Clean up the kernel configuration a bit.
  3. Produce an SD card image, instead of a tarball.
  4. Tune up the base install to mount the on-board mmc device automatically (to be used for LBU)
  5. Really clean up that build script. It's pretty rough.
  6. In newer versions of Alpine, the vlan package conflicts with ifupdown-ng, and including it in the base package set results in a broken world. This should be reported/fixed, as vlan is important to us, but not ifupdown.
  7. Figure out what's going on with the 10GbE SFPs in the Macchiatobin. The interfaces are detected, but the PHY doesn't attach properly.
  8. Investigate appropriate compiler/linker flags for building kernels.


#Why is there a FAQ? Nobody uses this but you.

Well, yeah. This is more of a "Fun and Anticipated Questions" than a "Frequently Asked Questions".

#What's a Fun question?

Depends on your perspective -- but I find asking people about their grandmothers to be fun.

#The 10GbE SFP interfaces don't work!

Yeah, that just seems to be broken right now. Which kinda breaks the whole point of the board, but right now, the PHY isn't attaching properly. I'm not entirely certain why, but at least the copper NIC is working. (The 2.5GbE interface is theoretically working, but that's not tested.)

#How do I create an MSDOS partition table?


If you think you might possibly have something stored on that MicroSD card that maybe you, or your grandmother, will want to access at some point in the future, please back it up now. You will lose that data during this process.

  1. Insert the MicroSD card into your computer, using whatever mechanism you have: native MicroSD reader, SD reader and a MicroSD adapter, or some new-fangled USB dongle of some sort that maybe does both
  2. Launch Powershell as admin (Search Bar -> "Windows Powershell" -> Right-Click -> "Run as administrator")
  3. Say that "Yes", you want to allow this program to make changes to your computer
  4. Type diskpart (followed by the enter button, of course) to launch the disk partition manager
  5. Type list disk to show the available disks, and figure out which one is your MicroSD card (hint: it will not be Disk 0)
  6. Type select disk <n>, where n is the number of the disk assigned to your MicroSD card
  7. Type clean (this is the step that removes all your data)
  8. Type convert mbr to create a new MSDOS partition table
  9. Type create partition primary to create a new partition (diskpart will also magically select this partition for us, which is one less thing for us to type out!)
  10. Type format quick fs=fat32 label="ALPINE" to format this new partition
  11. Sometimes Windows doesn't like to make the drive actually be available (¯_(ツ)_/¯), so we gotta do that part for us. Pick a drive letter that isn't in use -- in my case, let's use J -- and assign it: assign letter=j

Voila! You now have a blank, MSDOS-compatible, FAT32-formatted MicroSD card at your chosen drive letter (J:, if you followed everything verbatim).

  1. Insert the MicroSD card into your computer. Since you're running Linux, you probably have a homebrew MicroSD reader attached to a breadboard somewhere in the back of a project drawer.
  2. Launch whatever newfangled partition manager all the Linux kids are using these days: fdisk? cfdisk? gdisk? parted? debug?
  3. Refer to whatever documentation exists to figure out how to create an MSDOS partition table. Create it.

Yeah, okay, this is less than helpful. But it's late, I'm tired, and I don't want to admit to the world that I still use fdisk and don't know how to use any of the newer partition managers.

#I've previously mucked about with u-boot and things are a bit weird now -- help!

The boards are pretty forgiving, thankfully. If you trash u-boot in the SPI, you can flash it to an MMC card directly (instructions can be found in the Update the U-Boot link above), and re-flash to SPI from there. This is a bit too complicate for me to toss as an answer in a light-hearted FAQ, so feel free to hit me up if you need help (open an issue, @-me on Twitter, whatever).

If you think it's just the u-boot environment that needs cleaning, that's an easy fix! Get on your console, power up the board, interrupt the boot process, and then just type env default -a followed by env save. That's it! Your U-Boot configuration is reset to defaults. At this point, I would recommend removing power from the board -- a simple reset doesn't always work as expected here.

#This kernel configuration looks ... strange.

Yeah. Well, as I noted above, SD cards are slow. Almost the entirety of the boot time is spent reading the initramfs from the SD card, so I'm trying to cut out as many kernel modules as I possible can. The first successful boot I had took almost a full minute, and I managed to cut that down to about 30 seconds just by stripping unnecessary cruft from the kernel (do you really need Android driver support on this thing?).

I still have a fair bit of work to do here: some more modules to cut out, some others to add back in, then finally actually going over the configuration and making sure it actually makes sense. I'm targeting usage as a wired router: no wireless cards, no GPU support, just passin' packets.

#I'd really like Package X to be in the root

So would I, probably. Thankfully it's pretty easy to add a package to your system once it's up and running, so modifying the base system is a lower priority right now.

#Why do we build on Debian?

Because all my cross-compiling efforts were failing, and using a pre-existing Debian install on an AARCH64 platform was the easiest way to get a stable build system up and running, with a reasonably current version of gcc available. This configuration is also most likely to be supported in various cloud-provider CI systems, making it a reasonable target.

This will probably work on any Debian derivative (i.e. Ubuntu) with no modifications, but I haven't tested it. Using this script with any other distribution will require some slight modifications -- probably just to the package installation stuff, and the build flags we use when building the kernel. It will not work on anything that is not a Debian-derivative, mostly because it is flat-out expecting apt to be the package manager.

#Why not just use UEFI?

Alpine's preferred boot manager (syslinux) doesn't support AARCH64, and the U-Boot support is perfectly functional. I'll admit to actually liking UEFI, but in the spirit of keeping things simple, there's no particularly compelling reason to move away from U-Boot at this time.

#You're missing compilation flags !

Yes, I certainly am! I have a list of things to look at, but if there's anything in particular you'd like to see, please let me know!