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

ComponentSpecification
SoCRockchip RK3588 (4x Cortex-A76 + 4x Cortex-A55)
GPUMali-G610 MP4 (Valhall architecture)
NPU6 TOPS (RKNN)
RAM8 GB LPDDR5
StorageNVMe (PCIe 3.0 x4), eMMC, microSD
Networking2x 2.5GbE (RTL8125B), WiFi 6E (option)
USB2x USB 3.0, 2x USB 2.0, 1x USB-C
Video2x HDMI 2.1 out, 1x HDMI in
OtherSPI flash (32 Mbit), 40-pin GPIO, fan header

What Works on NixOS

FeatureStatusNotes
CPU (8 cores)WorkingBig.LITTLE scheduling via mainline
GPU (Mali-G610)WorkingPanthor driver (Linux 6.10+)
NVMeWorkingPCIe 3.0 native support
eMMCWorkingStandard MMC subsystem
SD cardWorkingBoot medium for installation
2.5GbE (both ports)WorkingRealtek r8169 driver
USB 3.0WorkingxHCI native
USB-CPartialOne orientation only, no PD negotiation
HDMI outputWorkingVia DRM/KMS
WiFi 6EWorkingRequires armbian-firmware
NPU (RKNN)Not workingVendor-only rknpu driver, no mainline support
Hardware video decodePartialhantro/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:

AspectMainline (6.10+)Vendor (6.14 + Armbian patches)
CPU/GPU basicWorkingWorking
Mali-G610 (Panthor)Working (6.10+)Working
PCIe/NVMeWorkingWorking
WiFi/BT firmwareMay need extra patchesIncluded via Armbian defconfig
USB-CBuggyBetter Rockchip PHY support
Device tree qualityGood (upstream DTBs)Good (Armbian-maintained DTBs)
Kernel configGeneric ARM64Tuned for Rockchip64 boards
Security patchesFast (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:

PathMechanismNixOS Bootloader
U-Boot (traditional)BootROM > TPL/SPL > U-Boot > extlinux.confboot.loader.generic-extlinux-compatible
edk2 UEFIBootROM > edk2-rk3588 UEFI > GRUB/systemd-bootboot.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:

FactorOrange Pi 5 PlusWorkstation (id3-eniac)
RAM8 GB32+ GB
Build speedSlow (ARM big.LITTLE)Fast (x86_64, many cores)
Swap pressureHigh (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-aarch64 which 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 fdisk later.

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)

  1. Insert SD card into Orange Pi 5 Plus
  2. Connect Ethernet cable
  3. Power on
  4. What happens: RK3588 BootROM checks SPI (empty/stock), skips to SD, boots Ubuntu
  5. SSH: Joshua Riek’s Ubuntu defaults to ubuntu / ubuntu — SSH is enabled by default
  6. 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:

SymptomRoot causeFix

  1. Board enters maskrom mode (appears on lsusb as 2207:350b when 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).

  2. Board enters maskrom mode (appears on lsusb even with SD inserted) → BootROM rejected the SD card entirely → Try a different SD card (the RK3588 is picky about certain card models).

  3. 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/mtdblock0 will complain about a “corrupt backup GPT table.” This is a false alarm — /dev/mtdblock0 is 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/mtdblock0 doesn’t exist (kernel lacks MTD support), use rkdeveloptool from 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:

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.org binary 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.
  • 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 pkgsKernel for 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, Haskell shellcheck, Zig ncdu).
    • 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.buildPlatform checks 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:

hey ops deploy sbc-opi5p-hybrid opi5p_root
  • Mechanism: Leverages your workstation’s QEMU emulation (binfmt_misc) to fetch native aarch64-linux packages from the NixOS binary cache. The custom kernel continues to be cross-compiled natively on x86_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_64 compiling for aarch64).
  • 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:

  1. Local QEMU Emulation + Cross-compiled Kernel (Default - Free & Fast): Your workstation uses QEMU binfmt_misc to fetch pre-compiled aarch64-linux binaries directly from cache.nixos.org. For the custom kernel, the dotfiles cross-compile it natively on x86_64. You compile almost nothing under emulation, keeping deployments fast and completely free.
  2. 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-linux package 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.
  3. 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.org or nix commands on the Orange Pi hang and timeout.
  • Root Cause: The Ubuntu SD card runs ufw (Uncomplicated Firewall) with a default policy of deny (incoming). When sing-box runs 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 on tun0 and drops it.
  • Diagnostics: Run sudo dmesg | grep -i ufw on 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 tun0 interface:
    ssh opi5p_root "sudo ufw allow in on tun0"
    (Note: This is only needed on the temporary Ubuntu environment. Once booted into NixOS, the firewall module automatically trusts tun0.)

2. Nix Settings on Running Ubuntu SD Card

  • Symptom: Nix commands on the Ubuntu host complain that nix-command or flakes are disabled, or hit GitHub rate limits.
  • Fix: Update the Orange Pi’s /etc/nix/nix.conf to align with the workstation settings (enabling flakes, caches, trusted users, and including the GitHub access token):
    1. 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
    2. 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"

3. LVM2 Setup on Target (E: Repository no longer has a Release file)

  • Symptom: During disko partition execution, lvcreate fails 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 lvm2 tools/daemon installed. When LVM commands are executed, the kernel registers the logical volumes, but udev and the LVM daemon are not active to create the device nodes under /dev/nixos/ automatically. As a result, lvcreate cannot open the newly created logical volume to wipe its signature and aborts.
  • Fix: Install lvm2 on 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 to old-releases.ubuntu.com/ubuntu first:
    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: disko fails because the volume group nixos already 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-anywhere fails with:
    sh: 27: nixos-install: not found
  • Root Cause: When skipping kexec (e.g. via --phases disko,install), nixos-anywhere expects the target host to already be running an environment with nixos-install available in its PATH. On a standard Ubuntu host, this utility is missing.
  • Fix: Install nixos-install-tools in the target’s root user environment:
    ssh opi5p_root "nix-env -f '<nixpkgs>' -iA nixos-install-tools"

Bootstrap FAQ

  1. Password is managed by agenix, not passwd. The full config references config.age.secrets for password hashes. If password.mode is 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 as modules/profiles/user/alienzj.nix) and change password.mode to "deploy" (which disables password logins over SSH, enforcing key-only access).

  2. Why does the full config need —build-host on the Orange Pi? hey ops deploy and plain nixos-rebuild switch --target-host build on the workstation by default. For aarch64 targets, this means QEMU binfmt cross-compilation. Rust packages (vscode-lldb-adapter, rust-analyzer, etc.) crash QEMU with SIGSEGV/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.

  3. 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-anywhere via hey. 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:
      hey ops bootstrap sbc-opi5p opi5p_root -- --phases install
      This will compile your updated NixOS configuration (e.g. with the correct SSH keys/password configurations) and re-run nixos-install over the existing /mnt layout without re-partitioning or erasing /mnt/persist.

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

VolumeSizeFormatMountPurpose
ESP2 GBFAT32/bootsystemd-boot, initrd, kernel
lv_nix30%VG (~300 GB)ext4/nixNix store (cross-compiled closures)
lv_swap8 GBswap[swap]Hibernate resume + discard
lv_persist100%FREE (~690 GB)ext4/persistPersisted state (impermanence)
tmpfstmpfs/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:

ComponentSourcePurpose
Kernel sourcegit.kernel.org (mainline)Base Linux kernel
DefconfigArmbian linux-rockchip64-edge.configHardware-tuned kernel config
PatchesArmbian patch/kernel/archive/rockchip64-<ver>/Rockchip64 hardware fixes
Extra configstructuredExtraConfig in vendor.nixNVMe, USB-C, DM_CRYPT, etc.
Board DTBSelected by board parameterDevice tree for specific board
Driver trimming= no overrides in structuredExtraConfigDisable 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.

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 cached aarch64-linux binaries (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-linux package (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:

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_root directly to nixos-rebuild/hey ops deploy. Doing so forces all tasks—including the x86_64-linux cross-compiled kernel—to run on the Orange Pi, which fails with a platform mismatch error.

Instead, configure the Orange Pi as a distributed builder on your workstation:

  1. Add opi5p_root to /etc/nix/machines on your workstation.
  2. Run deployment without the --build-host flag:
    hey ops deploy sbc-opi5p-hybrid opi5p_root --boot -- --use-substitutes
    Nix will automatically execute the aarch64 compile tasks on the Orange Pi, while keeping the x86_64 kernel 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-linux package (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

# 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

BranchUpdate FrequencyWhen to Update
Stable (7.0.x)Weekly patchesWhen security fixes land
Edge (7.1, 7.2…)Every 2-3 monthsWhen Armbian adds support
LTS (6.12, 6.18)Monthly patchesFor 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

DateVersionArmbian CommitNotes
2026-06-067.078b0feedUpdated Armbian patches (latest fixes)
2026-04-297.073a3e49Upgraded from 6.14 (unmaintained)
2026-04-146.1484447a0eInitial 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?

AspectU-Bootedk2 UEFI
Boot methodextlinux.confGRUB/systemd-boot
NixOS integrationgeneric-extlinux-compatibleStandard UEFI loaders
NVMe bootRequires SPI U-BootNative UEFI support
systemd-bootNot supportedSupported
Secure BootNot supportedPossible (future)
Community supportGoodPlatinum 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

  1. Verify edk2 is flashed to SPI: connect HDMI, check for UEFI boot screen
  2. Check NVMe detection: in edk2 shell, run map to list block devices
  3. Verify ESP has bootloader: mount NVMe ESP, check for EFI/BOOT/BOOTAA64.EFI
  4. 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)

SymptomRoot CauseFix
Red LED only, SD insertedWrong bootstrap image (TPL/SPL crashes)Try Joshua Riek’s Ubuntu (known-working)
Red LED only, SD removedSPI has corrupt/broken firmwareErase SPI (Step 4 troubleshooting)
Red LED only, tried multiple SD cardsSD card incompatible with RK3588 BootROMTry a different brand/size
Red → green cycling, never bootsSPI 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:

  1. Build on workstation (recommended)
  2. Add swap: sudo fallocate -l 8G /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile
  3. 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.


FilePurpose
hosts/sbc-opi5p/default.nixHost entry point
hosts/sbc-opi5p/modules/modules.nixSystem configuration
hosts/sbc-opi5p/modules/storage.nixDisko disk layout
packages/rockchip-kernel/vendor.nixCustom kernel build
packages/armbian-firmware/default.nixWiFi/BT firmware
modules/profiles/hardware/cpu/rock.nixRockchip hardware profile
modules/profiles/role/board.nixBoard role profile
docs/storage-disko.mdDisko documentation