Sbc Opi5p
Orange Pi 5 Plus (sbc-opi5p) Setup Guide
Complete installation and configuration guide for NixOS on the Orange Pi 5 Plus single board computer.
Hardware Overview
| Component | Specification |
|---|---|
| SoC | Rockchip RK3588 (4x Cortex-A76 + 4x Cortex-A55) |
| GPU | Mali-G610 MP4 (Valhall architecture) |
| NPU | 6 TOPS (RKNN) |
| RAM | 8 GB LPDDR5 |
| Storage | NVMe (PCIe 3.0 x4), eMMC, microSD |
| Networking | 2x 2.5GbE (RTL8125B), WiFi 6E (option) |
| USB | 2x USB 3.0, 2x USB 2.0, 1x USB-C |
| Video | 2x HDMI 2.1 out, 1x HDMI in |
| Other | SPI flash (32 Mbit), 40-pin GPIO, fan header |
What Works on NixOS
| Feature | Status | Notes |
|---|---|---|
| CPU (8 cores) | Working | Big.LITTLE scheduling via mainline |
| GPU (Mali-G610) | Working | Panthor driver (Linux 6.10+) |
| NVMe | Working | PCIe 3.0 native support |
| eMMC | Working | Standard MMC subsystem |
| SD card | Working | Boot medium for installation |
| 2.5GbE (both ports) | Working | Realtek r8169 driver |
| USB 3.0 | Working | xHCI native |
| USB-C | Partial | One orientation only, no PD negotiation |
| HDMI output | Working | Via DRM/KMS |
| WiFi 6E | Working | Requires armbian-firmware |
| NPU (RKNN) | Not working | Vendor-only rknpu driver, no mainline support |
| Hardware video decode | Partial | hantro/rkvdec2 improving, not full codec coverage |
Architecture Decisions
Kernel: Vendor BSP vs Mainline
This configuration uses a vendor kernel (Linux 6.14 with Armbian patches) rather than mainline. The reasons:
| Aspect | Mainline (6.10+) | Vendor (6.14 + Armbian patches) |
|---|---|---|
| CPU/GPU basic | Working | Working |
| Mali-G610 (Panthor) | Working (6.10+) | Working |
| PCIe/NVMe | Working | Working |
| WiFi/BT firmware | May need extra patches | Included via Armbian defconfig |
| USB-C | Buggy | Better Rockchip PHY support |
| Device tree quality | Good (upstream DTBs) | Good (Armbian-maintained DTBs) |
| Kernel config | Generic ARM64 | Tuned for Rockchip64 boards |
| Security patches | Fast (mainline) | Slower (Armbian backports) |
Trade-off: The vendor kernel provides better out-of-box hardware support (especially WiFi, USB-C, and Rockchip PHY drivers) at the cost of tracking a non-mainline tree. The Armbian project maintains the patches and defconfig, reducing maintenance burden.
The kernel is built from packages/rockchip-kernel/vendor.nix and applied via modules/profiles/hardware/cpu/rock.nix.
Boot Path: U-Boot vs edk2 UEFI
The RK3588 BootROM boot order is: SPI Flash > eMMC > SD Card > USB.
Two boot paths are available:
| Path | Mechanism | NixOS Bootloader |
|---|---|---|
| U-Boot (traditional) | BootROM > TPL/SPL > U-Boot > extlinux.conf | boot.loader.generic-extlinux-compatible |
| edk2 UEFI | BootROM > edk2-rk3588 UEFI > GRUB/systemd-boot | boot.loader.systemd-boot or boot.loader.grub |
This configuration uses edk2 UEFI flashed to SPI flash. Benefits:
- Standard NixOS UEFI boot flow (same as x86_64)
- systemd-boot or GRUB work natively
- NVMe boot supported (PCIe 3.0)
- No U-Boot-specific partition layout requirements
- edk2-rk3588 has Platinum tier support for Orange Pi 5 Plus
Cross-Compilation Strategy
Building a full NixOS desktop system on the Orange Pi (8 GB RAM) is impractical:
| Factor | Orange Pi 5 Plus | Workstation (id3-eniac) |
|---|---|---|
| RAM | 8 GB | 32+ GB |
| Build speed | Slow (ARM big.LITTLE) | Fast (x86_64, many cores) |
| Swap pressure | High (OOM risk) | Minimal |
Strategy: Build on the x86_64 workstation using binfmt QEMU emulation, then
deploy to the Orange Pi. Both hey ops bootstrap (initial install) and
hey ops deploy (updates) default to building on the workstation and copying
the closure to the target — the Orange Pi never compiles.
The storage.nix configuration enables image-based builds for VM testing:
disko.imageBuilder = {
enableBinfmt = true; # Use QEMU binfmt for aarch64 builds on x86_64
pkgs = hey.inputs.nixpkgs.legacyPackages.x86_64-linux;
};
Installation Flow Overview
┌─────────────────────────────────────────────────────────────────┐
│ Workstation (id3-eniac, x86_64 with binfmt) │
│ │
│ 1. Download Joshua Riek's Ubuntu for Orange Pi 5 Plus │
│ 2. Flash to SD card │
│ 3. Download edk2 UEFI firmware │
│ 4. (Optional) Pre-seed kexec tarball for slow-GitHub regions │
└─────────────────────────────────────────────────────────────────┘
│
▼ SD card
┌─────────────────────────────────────────────────────────────────┐
│ Orange Pi 5 Plus (first boot from SD) │
│ │
│ Stock/empty SPI → skips to SD → Ubuntu boots │
│ SSH server starts (default: ubuntu/ubuntu) │
│ Flash edk2 to SPI while running from SD │
└─────────────────────────────────────────────────────────────────┘
│ SSH (from workstation)
▼
┌─────────────────────────────────────────────────────────────────┐
│ Workstation (via hey ops bootstrap / nixos-anywhere) │
│ │
│ 5. hey ops bootstrap partitions NVMe via disko, installs NixOS │
└─────────────────────────────────────────────────────────────────┘
│
▼ Reboot (remove SD)
┌─────────────────────────────────────────────────────────────────┐
│ Orange Pi 5 Plus (final: edk2 UEFI → NVMe → NixOS) │
└─────────────────────────────────────────────────────────────────┘
Key Concepts
SPI (Serial Peripheral Interface) — A 16 MB NOR flash chip on the board. The RK3588 SoC reads it first on boot. Stores the first-stage firmware (U-Boot or edk2 UEFI).
edk2 UEFI — A standard UEFI firmware for RK3588. Once flashed to SPI, it replaces the stock U-Boot and provides a familiar UEFI boot manager (same as your x86_64 PC). Supports NVMe boot natively.
Boot order — RK3588 BootROM tries: SPI → eMMC → SD → USB. If SPI is empty/blank, it falls through to SD. If SPI has edk2, edk2 takes over and presents a UEFI boot manager.
Cross-compilation — Your x86_64 workstation uses binfmt/QEMU to build aarch64-linux packages. The Orange Pi (8 GB RAM) cannot build a full desktop NixOS in reasonable time.
Prerequisites
- Orange Pi 5 Plus with NVMe disk installed
- microSD card (8 GB minimum)
- Ethernet connection (WiFi not supported by nixos-anywhere)
- USB drive (for edk2 firmware, optional — can also use scp)
Step 1: Download Bootstrap Image (on workstation)
The SD card is a throwaway bootstrap medium — it only needs to boot the board
so you can SSH in, flash edk2 to SPI, and run nixos-anywhere. There is no
reason to cross-compile a full NixOS SD image for this.
Recommended: Joshua Riek’s Ubuntu for Orange Pi 5 Plus.
Armbian’s TPL/SPL bootloader has known DRAM-init compatibility issues on some Orange Pi 5 Plus boards (boot hangs with solid red LED, no green heartbeat). Joshua Riek’s Ubuntu uses a Rockchip-optimized bootloader that boots reliably.
# Download Joshua Riek's Ubuntu for Orange Pi 5 Plus
# https://github.com/Joshua-Riek/ubuntu-rockchip/releases
# Choose: ubuntu-24.04-preinstalled-server-arm64-orangepi-5-plus.img.xz
curl -LO https://github.com/Joshua-Riek/ubuntu-rockchip/releases/latest/download/ubuntu-24.04-preinstalled-server-arm64-orangepi-5-plus.img.xz
Alternative: Armbian — Download from https://www.armbian.com/orange-pi-5-plus/ (choose CLI minimal). If the board fails to boot from Armbian (red LED only), switch to Joshua Riek’s Ubuntu — it’s a known bootloader incompatibility.
Alternative: NixOS sd-aarch64 image — The flake provides
nix build .#nixosConfigurations.sbc-opi5p.config.formats.sd-aarch64which builds a bootable NixOS SD image from your configuration. This is not recommended: it cross-compiles the full system closure (Niri, Emacs, VS Code, etc.) for a temporary medium, and the board profile’s systemd-boot conflicts with the SD image’s extlinux bootloader.
Step 2: Flash Image to SD Card
# Decompress and flash (replace /dev/sdX with your SD card device!)
xz -d ubuntu-24.04-preinstalled-server-arm64-orangepi-5-plus.img.xz
sudo dd if=ubuntu-24.04-preinstalled-server-arm64-orangepi-5-plus.img \
of=/dev/sdX bs=4M status=progress conv=fsync oflag=direct
SD card size: The RK3588 BootROM supports SDXC cards up to 2 TB. 8 GB minimum, 32 GB or larger recommended. Some card models are incompatible — if boot fails, try a different brand/size card.
After writing, fix the GPT table to match the physical card size (the image is smaller than the card, leaving a broken backup GPT):
sudo sgdisk -e /dev/sdX
Note: The backup GPT mismatch doesn’t prevent booting, but fixing it prevents confusing warnings from
fdisklater.
Step 3: Download edk2 Firmware
On your workstation:
# Download edk2 UEFI firmware for Orange Pi 5 Plus
curl -LO https://github.com/edk2-porting/edk2-rk3588/releases/download/v1.1/orangepi-5plus_UEFI_Release_v1.1.img
# Copy to USB drive (FAT32 formatted) for transfer to Orange Pi
cp orangepi-5plus_UEFI_Release_v1.1.img /media/usb/
Step 4: First Boot (from SD card)
- Insert SD card into Orange Pi 5 Plus
- Connect Ethernet cable
- Power on
- What happens: RK3588 BootROM checks SPI (empty/stock), skips to SD, boots Ubuntu
- SSH: Joshua Riek’s Ubuntu defaults to
ubuntu/ubuntu— SSH is enabled by default - Find the IP: check your router’s DHCP leases, or
nmap -sn 192.168.31.0/24
# SSH into the board (replace IP with the actual address)
ssh ubuntu@<orange-pi-ip>
# Default password: ubuntu
Troubleshooting: Board Doesn’t Boot from SD
If the board shows only solid red LED (no green heartbeat, no HDMI output, no DHCP lease), one of two things is happening:
Symptom → Root cause → Fix
-
Board enters maskrom mode (appears on
lsusbas2207:350bwhen SD is removed, but not when SD is inserted) → BootROM found the SD card and tried to execute TPL/SPL, but the bootloader crashed → Try a different bootstrap image (switch Armbian ↔ Joshua Riek’s Ubuntu). -
Board enters maskrom mode (appears on
lsusbeven with SD inserted) → BootROM rejected the SD card entirely → Try a different SD card (the RK3588 is picky about certain card models). -
Board shows nothing on HDMI, no USB device on lsusb → BootROM is hanging on corrupt SPI data → Erase SPI (see below).
Diagnostic: lsusb test — This is the most reliable way to determine what’s happening:
# On workstation, with Orange Pi powered OFF and SD removed:
# Connect USB-C data port (near MASKROM button) to workstation.
# Power on Orange Pi.
lsusb | grep -i -E "rock|2207|3588"
# Expected: ID 2207:350b Fuzhou Rockchip Electronics Company
# This proves BootROM is alive and SPI is empty.
# Now power off, insert SD, power on.
# If maskrom STILL appears → BootROM rejected the SD (bad card/image).
# If maskrom does NOT appear → BootROM executed the SD bootloader,
# but it crashed (wrong image for this board).
# If nothing appears AND no HDMI → SPI not actually empty (re-erase).
Fix — Erase SPI flash:
Method A: Windows RKDevTool (recommended — reliable GUI tool)
1. On a Windows PC, download:
- RKDevTool v2.96:
https://dl.radxa.com/tools/windows/RKDevTool_Release_v2.96_zh.zip
- DriverAssistant v5.14:
https://dl.radxa.com/tools/windows/DriverAssitant_v5.14.zip
2. Install driver: unzip DriverAssitant, run DriverInstall.exe as admin,
click "安装驱动" (Install Driver)
3. Unzip and open RKDevTool.exe
4. Connect Orange Pi USB-C (data port, near MASKROM button) to PC
5. Enter Maskrom mode: hold MASKROM button, power on, hold 5s, release
6. RKDevTool shows "发现一个MASKROM设备" (Found One MASKROM Device)
7. Click "高级功能" (Advanced) tab
8. In "存储" (Storage) dropdown, select SPINOR ← CRITICAL: must be SPINOR!
9. If it shows "获取Capability失败", first load a Loader:
click "..." on the Boot row, select an RK3588 MiniLoaderAll.bin,
then retry SPINOR selection
10. Click "擦除所有" (Erase All)
11. Power off, then power on normally — SPI is empty, board boots from SD
Verify: remove SD, power on, run lsusb. Should show 2207:350b (maskrom).
If not, the erase didn't work — retry or use Method C.
Method B: Linux rkdeveloptool (fallback — may segfault)
The rkdeveloptool on Linux can be unstable with RK3588 maskrom (segfault
bugs). If it detects the device (rkdeveloptool ld → Maskrom) but fails on
write operations, switch to Method A.
# rkdeveloptool ld # verify detection
# rkdeveloptool ef # erase SPI (may fail)
Method C: SPI chip short (last resort — hardware method)
Locate the 8-pin SPI flash chip (SOIC-8, ~3x4mm, labeled W25Q256 or similar)
on the top side of the board near the 40-pin GPIO header. Short pin 1 (CS#)
to pin 8 (VCC) with tweezers, power on, release when green LED blinks.
This physically disables the chip, forcing BootROM to fall through to SD.
Once SPI is erased and Ubuntu boots from SD (green LED blinking, SSH reachable), proceed to Step 5 — flashing edk2 to SPI will write a clean UEFI firmware, permanently fixing the issue.
Step 5: Flash edk2 to SPI (from the running Orange Pi)
This writes a clean UEFI firmware to SPI, overwriting whatever was there before (stock U-Boot, corrupt data, or an older edk2 version). After this step, SPI is fixed and the board will boot NVMe normally.
SSH into the Orange Pi, then:
# Download edk2 UEFI firmware directly on the Orange Pi
curl -LO https://github.com/edk2-porting/edk2-rk3588/releases/download/v1.1/orangepi-5plus_UEFI_Release_v1.1.img
# Flash to SPI (mtdblock0 is the SPI NOR flash — same chip you erased earlier)
sudo dd if=orangepi-5plus_UEFI_Release_v1.1.img of=/dev/mtdblock0 bs=4K status=progress
# Verify
cat /proc/mtd # Should show mtd0: 01000000 00001000 "spi5.0"
Ignore fdisk warnings! Running
fdisk -l /dev/mtdblock0will complain about a “corrupt backup GPT table.” This is a false alarm —/dev/mtdblock0is raw SPI NOR flash. fdisk is misinterpreting the UEFI firmware binary as a partition table. No fix is needed.
Reboot and connect HDMI — you should see the edk2 logo and UEFI setup screen. The edk2 boot manager will detect any bootable EFI partitions on NVMe or SD.
Alternative: If
/dev/mtdblock0doesn’t exist (kernel lacks MTD support), userkdeveloptoolfrom your workstation via USB-C:# On Orange Pi, enter maskrom mode (hold recovery button + power cycle) # On workstation: rkdeveloptool ld # Detect maskrom device rkdeveloptool db rk3588_spl_loader.bin # Load DRAM init rkdeveloptool ef # Erase flash rkdeveloptool wl 0 orangepi-5plus_UEFI_Release_v1.1.img # Write rkdeveloptool rd # Reboot
Step 6: Bootstrap NixOS to NVMe (from workstation)
With native cross-compilation enabled (via the sbc-opi5p-cross target) and by using the --no-kexec flag, we can bootstrap NixOS on the NVMe SSD from the workstation in a single command.
This flow boots Ubuntu from the SD card (which has fully working network drivers) and uses it to format the NVMe and install NixOS, avoiding kexec network loss and QEMU compilation crashes.
Step 6a: Install Nix on the running Ubuntu (on Orange Pi)
For nixos-anywhere to perform the installation without rebooting the SD card kernel, Nix must be installed on the target. SSH into the Orange Pi and install Nix:
# SSH to Orange Pi (default pass: ubuntu)
ssh ubuntu@<opi-ip>
# Install multi-user Nix
curl -L https://nixos.org/nix/install | sh
# Enable flakes and nix-command
mkdir -p ~/.config/nix
echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
# Restart SSH session or source the nix profile so nix commands are in PATH
source ~/.nix-profile/etc/profile.d/nix.sh
Step 6b: Run the Bootstrap Command (on workstation)
There are two primary methods to build the system closure on the workstation during bootstrap. Pass the --no-kexec flag to skip the kexec kernel reboot:
Method A: Native Emulated Build (Recommended)
This uses your workstation’s QEMU emulator (binfmt_misc) to build standard native aarch64-linux packages.
# From your workstation dotfiles directory
hey ops bootstrap sbc-opi5p-hybrid root@<opi-ip> -- --no-kexec
- Pros:
- Cache Hits: All standard packages (e.g. bash, openssl, git, etc.) are fetched pre-compiled directly from the official
cache.nixos.orgbinary cache (takes seconds to download). - No Cross-compilation Bugs: Avoids toolchain-specific build errors of complex language ecosystems (Go, Rust, Haskell, Zig).
- Speed: Fastest bootstrap method overall.
- Cache Hits: All standard packages (e.g. bash, openssl, git, etc.) are fetched pre-compiled directly from the official
- Cons: Any uncached package that must compile from source runs under slower QEMU emulation (note that the custom kernel is still cross-compiled natively via
pkgsKernelfor speed).
Method B: Cross-compiled Build (Debugging & Testing)
This uses cross-compilers on the workstation (x86_64-linux compiling for aarch64-linux without QEMU).
# From your workstation dotfiles directory
hey ops bootstrap sbc-opi5p-cross root@<opi-ip> -- --no-kexec
- Pros:
- Fast compilation: Compiling from source runs at native host speeds (no emulation).
- Cons:
- Cache Misses: Cross-compiled derivation hashes do not match native ones, so Nix cannot use the public binary cache, forcing everything to compile from source.
- Toolchain Bugs: Highly likely to hit cross-compilation bugs in fragile packages (like Go
gh, Haskellshellcheck, Zigncdu). - Debugging Tool: Running this is a great way to verify which package configurations/derivations have cross-compilation toolchain errors. We can selectively skip or gate those packages using
stdenv.hostPlatform == stdenv.buildPlatformchecks in Nix.
Expected output: installation finished!
Step 6c: Reboot into NixOS
ssh root@<opi-ip> 'reboot'
During the reboot, remove the microSD card. The SPI flash UEFI firmware (edk2) will boot directly from the NVMe ESP, launching systemd-boot into your new NixOS system.
Step 7: Managing the System After Bootstrap
Daily Updates & Upgrades
You can update and deploy configurations to the Orange Pi using two remote target commands on the workstation:
Option A: Native Emulated Deploy (Recommended)
hey ops deploy sbc-opi5p-hybrid opi5p_root
- Mechanism: Leverages your workstation’s QEMU emulation (
binfmt_misc) to fetch nativeaarch64-linuxpackages from the NixOS binary cache. The custom kernel continues to be cross-compiled natively onx86_64(no QEMU) for speed. - Speed: Extremely fast (minutes). Almost all packages are downloaded pre-compiled from the cache.
Option B: Cross-compiled Deploy (Debugging & Source Compiling)
hey ops deploy sbc-opi5p-cross opi5p_root
- Mechanism: Compiles the entire configuration using cross-compilers on the workstation (
x86_64compiling foraarch64). - Speed: Slow (hours). Nix cache lookup fails because cross-compiled derivation hashes differ from standard native ones. Everything compiles from source, making it a great debugging target to verify which packages lack cross-compilation gates.
Safety: The --boot Flag
Both deploy options support the --boot flag (e.g. hey ops deploy sbc-opi5p opi5p_root --boot).
- When passed, Nix builds the configuration and registers it as the default entry in the UEFI bootloader, but does not activate it on the running system immediately.
- The changes only activate upon the next reboot. This is a crucial safety mechanism: if the new configuration has a bug that locks you out of the network/SSH, a simple power cycle or hard reboot rolls back the system to the previous working generation.
Do I need to buy an M2 Ultra Mac to build ARM packages?
No. You do not need to buy any high-end Apple Silicon hardware to construct a native ARM builder server. Here are the three best ways to build aarch64-linux configurations:
- Local QEMU Emulation + Cross-compiled Kernel (Default - Free & Fast):
Your workstation uses QEMU
binfmt_miscto fetch pre-compiledaarch64-linuxbinaries directly fromcache.nixos.org. For the custom kernel, the dotfiles cross-compile it natively onx86_64. You compile almost nothing under emulation, keeping deployments fast and completely free. - Use the Orange Pi 5 Plus itself as a Remote Builder (Free):
Nix natively supports distributed builds. Once the SBC is bootstrapped and running NixOS, you can configure your workstation to offload
aarch64-linuxpackage compilations to the SBC over SSH. The SBC compiles natively and copies the output back to the workstation. While 8GB RAM is not enough for giant compiles (e.g. Chromium), it is excellent for standard package updates. - Oracle Cloud Free Tier Ampere VPS (Free): Oracle Cloud Infrastructure (OCI) offers an Always-Free tier that includes Ampere Altra ARM VM instances. You can create a VM with up to 4 ARM cores and 24 GB of RAM for free. Running Nix on this VPS and adding it as a remote builder for your workstation gives you a powerful, dedicated ARM builder server without spending any money.
Troubleshooting & Common Bootstrap Pitfalls
During bootstrap (running from the Ubuntu SD card environment), several network and storage issues can occur. Here is how to diagnose and resolve them:
1. Sing-box TUN Proxy & Firewall Blocks (TCP Connect Timeouts)
- Symptom:
curl -I https://cache.nixos.orgornixcommands on the Orange Pi hang and timeout. - Root Cause: The Ubuntu SD card runs
ufw(Uncomplicated Firewall) with a default policy ofdeny (incoming). Whensing-boxruns in TUN mode using the OS TCP stack ("stack": "system"), packets loop back from the TUN interface gateway (172.18.0.2) to the host (172.18.0.1). UFW treats this as unconfigured incoming traffic ontun0and drops it. - Diagnostics: Run
sudo dmesg | grep -i ufwon the Orange Pi. If you see[UFW BLOCK] IN=tun0 OUT= SRC=172.18.0.2 DST=172.18.0.1, it is blocking the tunnel loopback. - Fix: Allow incoming traffic on the virtual
tun0interface:
(Note: This is only needed on the temporary Ubuntu environment. Once booted into NixOS, the firewall module automatically trustsssh opi5p_root "sudo ufw allow in on tun0"tun0.)
2. Nix Settings on Running Ubuntu SD Card
- Symptom: Nix commands on the Ubuntu host complain that
nix-commandorflakesare disabled, or hit GitHub rate limits. - Fix: Update the Orange Pi’s
/etc/nix/nix.confto align with the workstation settings (enabling flakes, caches, trusted users, and including the GitHub access token):- Write a configured
nix.conf:build-users-group = nixbld experimental-features = nix-command flakes substituters = https://nix-community.cachix.org https://cache.nixos-cuda.org https://cache.nixos.org/ https://cache.numtide.com https://microvm.cachix.org trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= cache.nixos-cuda.org:74DUi4Ye579gUqzH4ziL9IyiJBlDpMRn9MBN8oNan9M= niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g= microvm.cachix.org-1:oXnBc6hRE3eX5rSYdRyMYXnfzcCxC7yKPTbZXALsqys= trusted-users = root ubuntu alienzj http2 = true warn-dirty = false - Copy your local decrypted GitHub token from the workstation to the target and link it:
sudo cat /run/agenix/dotfiles-github-access-token.conf | ssh opi5p_root "sudo tee /etc/nix/github-token.conf > /dev/null && sudo chmod 0400 /etc/nix/github-token.conf" ssh opi5p_root "sudo tee -a /etc/nix/nix.conf <<< '!include /etc/nix/github-token.conf' && sudo systemctl restart nix-daemon"
- Write a configured
3. LVM2 Setup on Target (E: Repository no longer has a Release file)
- Symptom: During
diskopartition execution,lvcreatefails with:lvcreate --yes -l 30%VG -n nix nixos /dev/nixos/nix: not found: device not cleared Aborting. Failed to wipe start of new LV. - Root Cause: The Ubuntu SD card image does not have the
lvm2tools/daemon installed. When LVM commands are executed, the kernel registers the logical volumes, butudevand the LVM daemon are not active to create the device nodes under/dev/nixos/automatically. As a result,lvcreatecannot open the newly created logical volume to wipe its signature and aborts. - Fix: Install
lvm2on the target Ubuntu system. Since Joshua Riek’s Ubuntu Server image for Orange Pi 5 Plus is based on EOL Ubuntu 24.10 (oracular), you must point the package manager toold-releases.ubuntu.com/ubuntufirst:ssh opi5p_root "sudo sed -i 's|http://ports.ubuntu.com|http://old-releases.ubuntu.com/ubuntu|g' /etc/apt/sources.list.d/ubuntu.sources /etc/apt/sources.list && sudo apt-get update && sudo apt-get install -y lvm2"
4. Clearing Existing LVM / GPT Signatures
- Symptom:
diskofails because the volume groupnixosalready exists or has conflicting metadata. - Fix: Run commands to completely wipe LVM structures and GPT tables from
/dev/nvme0n1:ssh opi5p_root "sudo vgremove -y nixos ; sudo pvremove -y /dev/nvme0n1p2 ; sudo wipefs -a /dev/nvme0n1"
5. nixos-install: not found (sh: nixos-install: not found)
- Symptom: During the installation phase,
nixos-anywherefails with:sh: 27: nixos-install: not found - Root Cause: When skipping
kexec(e.g. via--phases disko,install),nixos-anywhereexpects the target host to already be running an environment withnixos-installavailable in its PATH. On a standard Ubuntu host, this utility is missing. - Fix: Install
nixos-install-toolsin the target’s root user environment:ssh opi5p_root "nix-env -f '<nixpkgs>' -iA nixos-install-tools"
Bootstrap FAQ
-
Password is managed by agenix, not
passwd. The full config referencesconfig.age.secretsfor password hashes. Ifpassword.modeis set to"bootstrap", the root password defaults to"nixos"and password-based login is dynamically permitted over SSH (along with SSH key authentication). Once the host is bootstrapped and operational, you should map your new SSH public keys to the user files (such asmodules/profiles/user/alienzj.nix) and changepassword.modeto"deploy"(which disables password logins over SSH, enforcing key-only access). -
Why does the full config need —build-host on the Orange Pi?
hey ops deployand plainnixos-rebuild switch --target-hostbuild on the workstation by default. For aarch64 targets, this means QEMU binfmt cross-compilation. Rust packages (vscode-lldb-adapter,rust-analyzer, etc.) crash QEMU withSIGSEGV/SIGILL. Building natively on the Orange Pi (--build-host root@opi5p_root) avoids this. With--use-substitutes, most packages come from the binary cache anyway. -
How to repair or re-install the system without wiping data (skipping Disko format)? If you hit configuration issues (like SSH lockout) or need to repair a broken system after a bootstrap, you do not need to re-format the NVMe drive. You can boot into the Ubuntu recovery SD card environment, manually mount the existing partitions, and run only the installer phase of
nixos-anywhereviahey. This skips the disk partitioning phase entirely, preserving your data and persistent files.- Step 1: Boot the Orange Pi from the Ubuntu SD card environment and SSH in.
- Step 2: Manually activate the LVM volume group and mount the target partitions under
/mnt:sudo vgchange -ay nixos sudo mount /dev/mapper/nixos-nix /mnt sudo mkdir -p /mnt/boot /mnt/persist sudo mount /dev/nvme0n1p1 /mnt/boot sudo mount /dev/mapper/nixos-persist /mnt/persist - Step 3: On your workstation, run the bootstrap command specifying
--phases install:
This will compile your updated NixOS configuration (e.g. with the correct SSH keys/password configurations) and re-runhey ops bootstrap sbc-opi5p opi5p_root -- --phases installnixos-installover the existing/mntlayout without re-partitioning or erasing/mnt/persist.
Method 2: Build on Orange Pi (Not Recommended)
If you must build locally on the Orange Pi (e.g., no workstation available):
# Boot from SD (same as Step 2-4 above)
# Then install locally:
sudo nixos-install --flake .#sbc-opi5p
# Or use hey:
hey install --host sbc-opi5p
Warning: A full desktop build (Niri, VS Code, Emacs, etc.) on 8 GB ARM will likely take 2-4+ hours with heavy swapping. Consider reducing the configuration for local builds:
- Disable VS Code, Emacs, and other large packages
- Use a simpler desktop or headless configuration
- Add swap on the SD card during build
Method 3: Remote Builder (Hybrid)
Configure the Orange Pi as a thin build target that delegates heavy compilation to your workstation:
# On the Orange Pi, configure the workstation as a remote builder:
# /etc/nix/machines:
ssh://alienzj@id3-eniac aarch64-linux /home/alienzj/.ssh/id_ed25519 8 1 big-parallel,kvm
# Then build normally:
hey sync --host sbc-opi5p
This sends build jobs to the x86_64 workstation (which uses binfmt to produce aarch64 outputs), keeping the Orange Pi cool and responsive.
Disk Layout
The disko configuration in hosts/sbc-opi5p/modules/storage.nix defines:
/dev/nvme0n1 (Lexar NM620 1TB)
├── ESP (2 GB, FAT32) → /boot systemd-boot
└── LVM PV (remaining)
VG "nixos"
├── lv_nix (30%VG, ext4) → /nix Nix store
├── lv_swap (8 GB, swap) → [swap] discard + hibernate resume
└── lv_persist (100%FREE, ext4) → /persist Impermanence state
nodev."/" = tmpfs (no size cap, ~200 MB actual) Impermanent root
Partition Details
| Volume | Size | Format | Mount | Purpose |
|---|---|---|---|---|
| ESP | 2 GB | FAT32 | /boot | systemd-boot, initrd, kernel |
| lv_nix | 30%VG (~300 GB) | ext4 | /nix | Nix store (cross-compiled closures) |
| lv_swap | 8 GB | swap | [swap] | Hibernate resume + discard |
| lv_persist | 100%FREE (~690 GB) | ext4 | /persist | Persisted state (impermanence) |
| tmpfs | — | tmpfs | / | Wiped on every boot |
Why ext4 + LVM? ext4 is the most-tested filesystem on ARM/RK3588 (Armbian’s default). LVM adds btrfs-like flexibility (online resize, dynamic allocation) without the ARM-specific stability risks of btrfs. The VG uses 30%VG for /nix so it scales from a 42 GB test VM (~12 GB) to the full 1 TB NVMe (~300 GB).
Why tmpfs root without size=? Following the vps-pacman pattern: the kernel default is 50% RAM cap, but actual usage is ~200 MB (empty dirs + symlinks to /nix/store). Unlike lab-matrix which pins size=5G, omitting the cap lets tmpfs use only what it needs. Impermanence is enabled (persist.enable = true).
Why no LUKS? The Orange Pi 5 Plus has no TPM chip, and a DNS server must auto-recover from power loss without manual passphrase entry. Physical access is required to steal the NVMe (internal to the board).
Changing the NVMe Device Path
The current config hardcodes the NVMe device by ID:
device = "/dev/disk/by-id/nvme-Lexar_SSD_NM620_1TB_PAA0694103795P111D";
If replacing the NVMe disk, update this path. You can find the correct path with:
ls /dev/disk/by-id/nvme-*
Or use a more generic path:
device = "/dev/nvme0n1"; # Less stable across reboots
Kernel: Build, Test, Update, Maintain
Architecture
The kernel is built from packages/rockchip-kernel/vendor.nix. It combines:
| Component | Source | Purpose |
|---|---|---|
| Kernel source | git.kernel.org (mainline) | Base Linux kernel |
| Defconfig | Armbian linux-rockchip64-edge.config | Hardware-tuned kernel config |
| Patches | Armbian patch/kernel/archive/rockchip64-<ver>/ | Rockchip64 hardware fixes |
| Extra config | structuredExtraConfig in vendor.nix | NVMe, USB-C, DM_CRYPT, etc. |
| Board DTB | Selected by board parameter | Device tree for specific board |
| Driver trimming | = no overrides in structuredExtraConfig | Disable unused drivers (~70 families) |
The board parameter (opi5plus, opi5, opi5b) selects the correct device tree blob.
Build Methods
The Rockchip vendor kernel is the heaviest compilation task. In this configuration, both the standard sbc-opi5p target (Option A) and the sbc-opi5p-cross target (Option B) cross-compile the kernel natively on the workstation when evaluated from an x86_64 host.
1. Cross-Compiled Kernel on Workstation (Recommended / Default)
Building the configuration on your x86_64 workstation automatically cross-compiles the kernel natively using target-specific toolchains (aarch64-unknown-linux-gnu-gcc), bypassing slow QEMU emulation entirely for the kernel.
- For standard deploy (
sbc-opi5p): Standard packages are cachedaarch64-linuxbinaries (downloaded pre-compiled), and only the kernel compiles natively. This is the recommended target. - For cross-compiled target (
sbc-opi5p-cross): All packages are cross-compiled from source (no cache hits). Used primarily for testing.
2. Native Kernel Build on Orange Pi (Option C)
When evaluated directly on an aarch64-linux system (the Orange Pi itself or a dedicated native ARM builder):
- The kernel evaluates natively as a pure
aarch64-linuxpackage (no cross-compilation is triggered). - Reliable, but takes ~1.5h to build from source on the SBC’s CPU.
Driver Trimming
The Armbian defconfig enables drivers for all Rockchip64 boards (20+
WiFi chips, 30+ Ethernet NICs, touchscreens, CAN bus). For OPI5+, most are
unnecessary. vendor.nix disables ~70 driver families via
structuredExtraConfig, keeping only what OPI5+ actually uses:
- WiFi: AP6275P (brcmfmac) — disable ath*, mt76*, rtl*, wil*
- Ethernet: r8169 — disable intel, broadcom, aquantia
- Audio: HDMI only — disable all codec drivers
- Touchscreen, CAN bus, ATM, FDDI, HIPPI, etc.
Add = no entries to structuredExtraConfig when adding more driver families
to trim. Run make menuconfig in the kernel source to find config symbol names.
DTB Install for UEFI Boot
NixOS natively handles the device tree setup through the hardware.deviceTree option. When hardware.deviceTree is configured (e.g. name = "rockchip/rk3588-orangepi-5-plus.dtb"), the NixOS systemd-boot builder automatically copies the DTB to the ESP partition (under /boot/EFI/nixos/) and registers it in the systemd-boot entry via the devicetree configuration line.
Older configurations manually copied all DTB files to /boot/dtb/base/ via extraInstallCommands. This is redundant and has been removed, as the UEFI systemd-boot bootloader handles loading and overriding the DTB natively.
Building the Kernel
The Rockchip vendor kernel is the heaviest compilation task in the configuration. To avoid running GCC inside slow QEMU emulation, this repository uses a hybrid cross-compilation setup.
The flake configuration (lib/nixos.nix) defines a special pkgsKernel package set. When building the hybrid sbc-opi5p-hybrid configuration, Nix evaluates other packages as native aarch64-linux derivations, but configures the kernel package with system = "x86_64-linux" and crossSystem = "aarch64-linux". This allows the kernel to compile natively on your workstation’s x86_64 CPU using an optimized cross-compiler, running at full speed without any emulation overhead.
Here are the scenarios for building the kernel and the system:
Scenario A: Build on Workstation (Recommended / Default)
When you build the system or the kernel directly on your workstation without specifying --build-host:
# Build just the kernel (cross-compiled natively on your workstation's x86_64 CPU)
nix build .#nixosConfigurations.sbc-opi5p-hybrid.config.boot.kernelPackages.kernel
# Check the output
ls -la result/
# → vmlinuz (kernel image), dtbs/ (device trees), modules/
- Kernel Build: Cross-compiled natively in
x86_64(takes ~15-20 minutes, no QEMU). - Standard Packages: Downloaded directly from the binary cache. QEMU emulation is only used as a local fallback to compile custom/uncached packages from source.
Scenario B: Distributed Build (Advanced / Optional)
If you want standard packages to compile natively on the Orange Pi’s ARM CPU but keep the kernel cross-compiling natively on the workstation (x86_64):
[!WARNING] Do not pass
--build-host root@opi5p_rootdirectly tonixos-rebuild/hey ops deploy. Doing so forces all tasks—including thex86_64-linuxcross-compiled kernel—to run on the Orange Pi, which fails with aplatform mismatcherror.
Instead, configure the Orange Pi as a distributed builder on your workstation:
- Add
opi5p_rootto/etc/nix/machineson your workstation. - Run deployment without the
--build-hostflag:
Nix will automatically execute thehey ops deploy sbc-opi5p-hybrid opi5p_root --boot -- --use-substitutesaarch64compile tasks on the Orange Pi, while keeping thex86_64kernel compile task on the workstation.
Scenario C: Build natively on the Orange Pi (Headless / Standalone)
Only if you have no workstation available and must build locally:
# Executed directly on the Orange Pi
hey sync --host sbc-opi5p
- Kernel Build: Evaluates natively on the board itself, so the kernel is compiled natively as a pure
aarch64-linuxpackage (no cross-compilation is triggered, avoiding platform mismatch). - Speed: Expect 2-3+ hours of compilation with heavy swapping if cache misses occur.
Testing the Kernel
Option 1: Test on Real Hardware (recommended)
# 1. Build SD card image with new kernel
nix build .#nixosConfigurations.sbc-opi5p.config.formats.sd-aarch64
# 2. Flash to SD card
xz -d result/sd-image/*.img.xz
sudo dd if=*.img of=/dev/sdX bs=4M status=progress conv=fsync
# 3. Boot Orange Pi from SD card
# 4. Verify kernel:
uname -r # Should show new version
dmesg | grep -i rockchip # Check SoC initialization
dmesg | grep -i pcie # Check NVMe detection
dmesg | grep -i mmc # Check SD/eMMC
ls /dev/dri/ # Check GPU (card0, renderD128)
ip link # Check 2.5GbE interfaces
Option 2: Test in QEMU (limited — no real hardware)
# Build a VM image (uses virtio, not real RK3588 hardware)
hey build vm --host sbc-opi5p
# Run the VM
result/bin/run-sbc-opi5p-vm
Note: QEMU VMs use virtio devices, not real RK3588 hardware. This tests the NixOS configuration but NOT the kernel’s hardware support (GPU, NVMe PHY, WiFi, etc.).
Option 3: Verify Kernel Config
# Extract and inspect the kernel config
nix build .#nixosConfigurations.sbc-opi5p.config.boot.kernelPackages.kernel.configfile
zcat result/.config | grep -E "PANTHOR|PCIE_ROCKCHIP|MMC_DW|TYPEC|PHY_ROCKCHIP"
# Key options to verify:
# CONFIG_PANTHOR=y (GPU driver)
# CONFIG_PCIE_ROCKCHIP_DW_HOST=y (NVMe)
# CONFIG_MMC_DW=y (eMMC)
# CONFIG_TYPEC=y (USB-C)
# CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY=y (USB/DP PHY)
Updating the Kernel
Update to a New Linux Version (e.g., 7.1, 7.2)
When a new stable kernel is released and Armbian adds patches for it:
Step 1: Check Armbian support
# Check if Armbian has patches for the new version
# Visit: https://github.com/armbian/build/tree/main/patch/kernel/archive/
# Look for: rockchip64-<new-version>/
# Also check the defconfig still exists:
# https://github.com/armbian/build/blob/main/config/kernel/linux-rockchip64-edge.config
Step 2: Find the latest Armbian commit
# Get the latest commit from Armbian build repo
git ls-remote https://github.com/armbian/build HEAD
# Note the commit hash
Step 3: Update packages/rockchip-kernel/vendor.nix
# Change these three values:
version = "7.1"; # ← New Linux version
src = fetchurl {
url = "https://git.kernel.org/torvalds/t/linux-${version}.tar.gz";
hash = "sha256-XXXX"; # ← Will be updated by nix build error
};
armbianBuild = fetchFromGitHub {
owner = "armbian";
repo = "build";
rev = "NEW_COMMIT_HASH"; # ← Latest Armbian commit
hash = "sha256-XXXX"; # ← Will be updated by nix build error
# ...
};
Step 4: Get correct hashes
Nix will tell you the correct hash when you build with a wrong one:
# Build and let nix tell you the correct hash
nix build .#nixosConfigurations.sbc-opi5p.config.boot.kernelPackages.kernel 2>&1 | grep "got:"
# Output example:
# specified: sha256-XXXX=
# got: sha256-YYYY= ← Use this hash
Step 5: Verify patches exist
# After nix fetches the Armbian source, check the patch directory exists
ls /nix/store/*-source/patch/kernel/archive/rockchip64-7.1/
# Should contain board-*.patch and general-*.patch files
Step 6: Build and test
# Build the kernel
nix build .#nixosConfigurations.sbc-opi5p.config.boot.kernelPackages.kernel
# Build SD image and test on hardware (see Testing section above)
Update Armbian Commit (same kernel version)
If Armbian updates patches for the same kernel version (e.g., bug fixes):
# Just update the rev and hash in vendor.nix
# Same process as above, skip the version change
Maintaining Extra Kernel Config
The structuredExtraConfig in vendor.nix adds options on top of the Armbian defconfig. When adding new hardware support:
structuredExtraConfig = with lib.kernel; {
# Existing options...
# Add new options here, e.g. for a new USB WiFi adapter:
RTL8852BU = module; # Realtek RTL8852BU WiFi
};
Finding the right option name:
# Search the kernel source
grep -r "CONFIG_.*OPTION_NAME" linux-7.0/
# Or use the kernel's menuconfig (requires building first)
nix develop .#nixosConfigurations.sbc-opi5p.config.boot.kernelPackages.kernel
make ARCH=arm64 menuconfig
Kernel Release Schedule
| Branch | Update Frequency | When to Update |
|---|---|---|
| Stable (7.0.x) | Weekly patches | When security fixes land |
| Edge (7.1, 7.2…) | Every 2-3 months | When Armbian adds support |
| LTS (6.12, 6.18) | Monthly patches | For servers needing stability |
Current setup: Tracks Armbian’s edge branch (latest stable kernel). This gives the best hardware support but requires periodic updates.
Recommended update cadence: Every 1-2 kernel releases (every 2-4 months), or when a critical security fix is released.
Version History
| Date | Version | Armbian Commit | Notes |
|---|---|---|---|
| 2026-06-06 | 7.0 | 78b0feed | Updated Armbian patches (latest fixes) |
| 2026-04-29 | 7.0 | 73a3e49 | Upgraded from 6.14 (unmaintained) |
| 2026-04-14 | 6.14 | 84447a0e | Initial vendor kernel |
Device Tree
The device tree blob is selected by modules/profiles/hardware/cpu/rock.nix:
hardware.deviceTree = {
name = "rockchip/rk3588-orangepi-5-plus.dtb";
overlays = [];
};
This DTB is provided by the kernel build (Armbian defconfig includes it).
Firmware
Armbian firmware blobs (WiFi, Bluetooth, etc.) are provided by packages/armbian-firmware:
hardware.firmware = [ hey.packages.armbian-firmware ];
This includes firmware for:
- Realtek RTL8852BE WiFi 6E
- Bluetooth 5.2
- Various Rockchip codec/PHY blobs
To update firmware:
# Update the armbian-firmware package
# Edit packages/armbian-firmware/default.nix
# Update rev and hash from https://github.com/armbian/firmware
Bootloader: edk2 UEFI
Why edk2 Instead of U-Boot?
| Aspect | U-Boot | edk2 UEFI |
|---|---|---|
| Boot method | extlinux.conf | GRUB/systemd-boot |
| NixOS integration | generic-extlinux-compatible | Standard UEFI loaders |
| NVMe boot | Requires SPI U-Boot | Native UEFI support |
| systemd-boot | Not supported | Supported |
| Secure Boot | Not supported | Possible (future) |
| Community support | Good | Platinum for OPI5+ |
Flashing edk2 to SPI
Download from: https://github.com/edk2-porting/edk2-rk3588/releases
# From a running Linux system on the Orange Pi (recommended):
curl -LO https://github.com/edk2-porting/edk2-rk3588/releases/download/v1.1/orangepi-5plus_UEFI_Release_v1.1.img
sudo dd if=orangepi-5plus_UEFI_Release_v1.1.img of=/dev/mtdblock0 bs=4K status=progress
# Or via rkdeveloptool (USB-C recovery mode):
# 1. Hold recovery button, connect USB-C, power on
# 2. Flash:
rkdeveloptool db rk3588_spl_loader_*.bin
rkdeveloptool write 0 orangepi-5-plus_*.img
Verifying edk2 Boot
After flashing, connect HDMI and power on. You should see the edk2 UEFI shell. From there:
- NVMe disks are detected automatically
- SD cards are detected automatically
- Boot order: NVMe > SD > USB
Post-Installation
First Boot Verification
After installing to NVMe and rebooting:
# Check system is running from NVMe
mount | grep / # Should show /dev/nvme0n1p2 on /
# Check kernel version
uname -r # Should show 7.0.x
# Check GPU
ls /dev/dri/ # Should show card0, renderD128
# Check networking
ip addr # Should show two 2.5GbE interfaces (eth0, eth1)
# Check NixOS generation
nixos-rebuild list-generations
Enabling the Desktop
The configuration includes Niri (Wayland compositor) with a DIY shell mode. To start:
# If greetd is configured, it starts automatically
# Otherwise, from TTY:
niri-session
Remote Access
SSH is enabled by default (modules.services.net.ssh.enable = true):
ssh alienzj@<orange-pi-ip>
Updating
From the Orange Pi:
# Pull latest flake inputs
hey pull
# Rebuild and switch
hey sync --host sbc-opi5p
Or remotely from your workstation (builds on workstation, pushes closure to target):
hey ops deploy sbc-opi5p opi5p_root
# Equivalently: hey ops sync sbc-opi5p opi5p_root
Troubleshooting
Orange Pi Doesn’t Boot from NVMe
- Verify edk2 is flashed to SPI: connect HDMI, check for UEFI boot screen
- Check NVMe detection: in edk2 shell, run
mapto list block devices - Verify ESP has bootloader: mount NVMe ESP, check for
EFI/BOOT/BOOTAA64.EFI - If NVMe is blank (bootstrapped but edk2 can’t find a bootloader):
# Boot from SD card (rescue disk), mount NVMe ESP, verify: sudo mount /dev/nvme0n1p1 /mnt ls /mnt/EFI/BOOT/ # Should contain BOOTAA64.EFI ls /mnt/loader/ # systemd-boot entries
Board Shows Red LED Only (No Boot)
| Symptom | Root Cause | Fix |
|---|---|---|
| Red LED only, SD inserted | Wrong bootstrap image (TPL/SPL crashes) | Try Joshua Riek’s Ubuntu (known-working) |
| Red LED only, SD removed | SPI has corrupt/broken firmware | Erase SPI (Step 4 troubleshooting) |
| Red LED only, tried multiple SD cards | SD card incompatible with RK3588 BootROM | Try a different brand/size |
| Red → green cycling, never boots | SPI has partial edk2 (corrupt flash) | Re-flash edk2 from a working system |
Diagnostic lsusb test — definitive way to determine where boot is failing:
# Remove SD, connect Orange Pi USB-C data port to workstation, power on
lsusb | grep -i rock
# → "2207:350b" = BootROM is alive, SPI is empty. ✓
# → No output = BootROM is hanging on SPI. Erase SPI.
# Insert SD, power on
lsusb | grep -i rock
# → Shows maskrom = BootROM rejected the SD card. Try different card.
# → No maskrom, but no green LED = TPL/SPL loaded but crashed. Try different image.
# → No maskrom, green LED blinking = SUCCESS. Booted.
Kexec Tarball Downloads Too Slowly (China / restricted networks)
The 416 MB kexec tarball from GitHub takes hours over slow connections. Pre-seed it locally — see bootstrap Step 6 § “Slow GitHub Access”.
No WiFi
# Check firmware is loaded
dmesg | grep -i wifi
dmesg | grep -i rtl8852
# Check firmware path
ls /run/current-system/firmware/rtw89/
# If missing, verify armbian-firmware is in hardware.firmware
nix eval .#nixosConfigurations.sbc-opi5p.config.hardware.firmware
Build Fails with “platform mismatch”
You’re building on x86_64 without binfmt. Verify:
ls /run/binfmt/aarch64-linux # Should exist
# If not, enable in your NixOS config:
# boot.binfmt.emulatedSystems = ["aarch64-linux"];
Build Fails with OOM on Orange Pi
The Orange Pi has only 8 GB RAM. Full desktop builds require 16+ GB. Solutions:
- Build on workstation (recommended)
- Add swap:
sudo fallocate -l 8G /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile - Reduce configuration (disable VS Code, Emacs, browsers)
edk2 USB-C Limitations
edk2-rk3588 has limited USB-C support:
- Only one orientation works (flip the cable if no display)
- No USB PD negotiation (use a USB-C cable with fixed power)
- USB-C is not recommended as a primary boot device
Soft Router & Gateway Setup
The Orange Pi 5 Plus features dual 2.5 Gbps Ethernet ports, making it a superb soft router or transparent bypass gateway. To configure this board to handle routing, NAT forwarding, or transparent sing-box proxying, please refer to the detailed configuration steps in router.md.
Related Files
| File | Purpose |
|---|---|
hosts/sbc-opi5p/default.nix | Host entry point |
hosts/sbc-opi5p/modules/modules.nix | System configuration |
hosts/sbc-opi5p/modules/storage.nix | Disko disk layout |
packages/rockchip-kernel/vendor.nix | Custom kernel build |
packages/armbian-firmware/default.nix | WiFi/BT firmware |
modules/profiles/hardware/cpu/rock.nix | Rockchip hardware profile |
modules/profiles/role/board.nix | Board role profile |
docs/storage-disko.md | Disko documentation |