A board can be added when Armbian already supports it. Roxora adds no board support of its own (see Architecture); adding a board means checking what Armbian puts into its image and making sure only the hardware layer stays.
1. Check the board exists in Armbian at the pinned commit
Use the armbian/build commit in armbian.ref, not Armbian's
current main branch. ./build.sh fetches it into cache/armbian-build, or
check it out yourself:
git clone https://github.com/armbian/build armbian-build
git -C armbian-build checkout "$(cat armbian.ref)"In that checkout:
config/boards/<board>.conf(standard support) or.csc(community support) must exist..wip,.eosand.tvbboards are not candidates.KERNEL_TARGETin that file must list the branch you want (edgefirst).- Note
BOARDFAMILY, the boot method (BOOTSCRIPTandBOOTENV_FILE, orSRC_EXTLINUX) and everyenable_extensionline. Roxora's checks assume the U-Boot boot script method the current boards use; a board that boots differently needs a closer look before it is added. - Check which packages Armbian's repository publishes for the board and branch
(
linux-u-boot-<board>-<branch>, the kernel and dtb of its family). Roxora takes updates of these from Armbian. If a package is not published, for example the U-Boot of a community board, the image still works but that package never gets updates.
./compile.sh config-dump-json BOARD=<board> BRANCH=<branch> RELEASE=noble BUILD_MINIMAL=yes BUILD_DESKTOP=no prints the resolved configuration and
runs without root.
2. Add the board to boards.conf
Add one line to boards.conf:
# BOARD BRANCH RELEASE FLAVOR STATUS SOC VENDOR NAME
radxa-rock-4d edge noble cli ci-only rk3576 Radxa Radxa ROCK 4DBOARDis Armbian's board name (the file name without extension).BRANCHis the Armbian kernel branch,RELEASEthe Ubuntu codename.FLAVORisclifor the command line image. Start with that one. A desktop image is one more line each, withgnome-minimalorgnome, once the board's display output works with the kernel branch.STATUSisci-onlyfor a new board. It becomeshardware-testedonly after Hardware test has passed on the board.SOCis lower case (rk3576).VENDORis the board maker as people write it, one word (Radxa); the imager and the website group boards by it.NAMEis the name people know the board by, with the vendor (Radxa ROCK 4D); it is the rest of the line.
build.sh, the extension, the CI matrix and the website all read this file.
Add the board's BSP package to
verify/reference/allowlist, the same way as
the existing ones:
armbian-bsp-cli-<board>-<branch> board support package, filtered to its hardware parts (docs/bsp-classification.md); built with the image3. Check the board support package
What Roxora keeps from Armbian lists every file of the BSP package of the current boards and says which layer it belongs to. A new board can bring more. Look in the pinned armbian/build checkout for:
- Files copied into the BSP package.
packages/bsp/commongoes to every board and is already classified. Board and family files come fromconfig/optional/boards/<board>/_packages/bsp-cli/,config/optional/families/<family>/_packages/bsp-cli/and fromfamily_tweaks_bspin the family file (config/sources/families/<family>.confand the files it includes), which often copies frompackages/bsp/<dir>/. - Board or family hooks that write into the root filesystem outside any
package: functions in the board file such as
post_family_tweaks__*, andfamily_tweaksin the family file. - Extensions the board enables, for example
radxa-aic8800on the ROCK 4D, which builds the Wi-Fi driver with DKMS. Read each one: what it installs, from where, and whether it needs kernel headers.
Classify each new file or change the same way as bsp-classification.md:
- Hardware layer (needed to boot or to drive the board's hardware): keep it, and add a row to the "Kept" table.
- Distro layer (changes how Ubuntu looks or behaves): remove it. Paths in
the BSP package go to
bsp-remove.list; files written into the root filesystem go torootfs-remove.list. Add a row to the "Removed" table with the reason. - An Ubuntu package file the board changes on purpose (rare): add it to
keep-modified.listwith a comment, and explain it in bsp-classification.md. Otherwise the extension restores it and the build fails if it cannot.
If the board needs kernel headers for a DKMS module, check that its extension
sets INSTALL_HEADERS=yes; the roxora extension turns headers off by default.
Headers are a hardware-layer package and are updated from Armbian with the
kernel.
When a file is hard to classify, compare the Roxora image with an image Armbian builds from the same commit without the extension, and list the files that differ.
4. Build in CI
Open a pull request with the changes. The Build
workflow runs for changes to boards.conf, userpatches/ and verify/, and
builds and verifies every line of boards.conf. It can also be started by
hand from the Actions tab. Images, verify output and Armbian's build logs are
uploaded as workflow artifacts.
A local build needs root (Armbian's build uses sudo) or Docker:
./build.sh BOARD=<board> BRANCH=<branch> RELEASE=noble5. Verify the image
verify/verify-image.sh runs in CI after the
build. To run it yourself (root and an arm64 host):
sudo verify/verify-image.sh output/roxora-<board>-noble-<branch>-dev.img.xzEvery line must say PASS. What to look at when one fails:
packages: a package that is neither in Ubuntu's server image nor hardware layer. Find out what pulls it in. Allowlist it only with a reason, and only if it comes from the Ubuntu archive.apt: an Armbian package outside the hardware patterns is the candidate. The pin file is shared by all boards; do not widen it for one board without a discussion in an issue first.files: a removed path is back, or an Ubuntu file differs from its package. Usually a board hook from step 3 that is not handled yet.boot: the boot script,armbianEnv.txt, kernel,uInitrd, device tree or the bootloader at 32 KiB is missing or does not match the packages. On a UEFI image (boot: UEFI): the EFI system partition, GRUB orgrub.cfgis not as described in Architecture.
6. Test on the board
Run every step of Hardware test on the board: flash, serial console, first boot, network, warm boot, update from the archives, reboot into a new kernel and roll back. Also check the hardware the board's BSP files and extensions are for, for example the Wi-Fi interface after a kernel update when its driver is built with DKMS.
Write down the board's boot order (which media the BootROM tries, and in what order) in hardware-test.md if it differs from the boards already there.
Every new release starts with all its images marked ci-only. When the test
passes on a release's image, the maintainer runs the "Mark hardware-tested"
workflow for that release and board, which updates the release's catalog and
notes (see Release contract). Set the board's
STATUS in boards.conf to hardware-tested at the same time, so the Boards
page shows it.
A UEFI image for another SoC
A UEFI image is not for one board but for every board of a SoC that runs
UEFI firmware (see Architecture). It has
its own name, generic-<soc>-uefi, and its own board file in
userpatches/config/boards/, because Armbian
has no such board. Everything UEFI images share is in
userpatches/roxora/uefi/board.inc.
-
Copy
generic-rk3576-uefi.conftogeneric-<soc>-uefi.confand set:BOARD_NAME;BOARDFAMILY: the Armbian family whoseedgekernel the SoC's boards use (rk35xxfor RK3576,rockchip-rk3588for RK3588; at the pinned commit both givelinux-image-edge-rockchip64, seeconfig/sources/families/include/rockchip64_common.inc);BOOT_SOC: the SoC, lower case;ROXORA_UEFI_SERIAL: the kernel console on the SoC's debug UART, asconsole=takes it (ttyS0,1500000n8on RK3576,ttyS2,1500000n8on RK3588).
-
Add one line per Ubuntu release to
boards.conf, withVENDORGenericand aNAMEthat says which boards it is for:generic-rk3588-uefi edge noble cli ci-only rk3588 Generic RK3588 boards with UEFI firmware -
Add
armbian-bsp-cli-generic-<soc>-uefi-edge-grubtoverify/reference/allowlist(Armbian adds-grubto the BSP package name of GRUB images). -
Check the family file for anything that assumes U-Boot beyond the boot script and its environment, which
board.incalready turns off.
CI builds the image, runs verify-image.sh on it (the UEFI checks are
chosen because the image has an EFI system partition) and boots it in QEMU.
Then test it on at least one board with the firmware, following
Hardware test.