The scripts in this repository produce disk images for Rockchip RK3576 based boards, ready to be flashed to an SD card or uploaded to internal storage via a USB connection and Maskrom mode.
You don't necessarily have to build images yourself. Most commits include a small green checkmark in the GitHub interface next to the commit message (or a red cross if we are less lucky), which links to a page in our Buildbot web interface with full build logs and links to pre-built images for all relevant boards, which our automated build system produces whenever something updates either in this repository or in one of its dependencies. Building from source is only necessary if you want to modify the system.
This repo contains build scripts only. The full system is assembled from several components:
| Repository | Description |
|---|---|
| flipperone-linux-build-scripts | Build scripts that assemble complete disk images for RK3576-based boards (this repo) |
| flipper-linux-kernel | Linux kernel patches and configuration for Flipper One RK3576-based boards |
| flipperone-mcu-firmware | Firmware for the low-power RP2350 MCU |
The build scripts pull the kernel and other components automatically — you don't need to clone other repos manually unless you want to modify them.
Build scripts (run them in order):
| Script | What it does |
|---|---|
build-uboot.sh |
Clones U-Boot and TF-A (or uses Rockchip's binary BL31), builds the bootloader and SPL loader for each target board |
build-kernel-mainline.sh |
Clones flipper-linux-kernel, merges config fragments from configs/linux/, builds arm64 kernel .deb packages and DTBs |
build-kernel-bsp.sh |
Clones Rockchip's BSP kernel (develop-6.1), fetches vendor DTS files, applies patches from patches/bsp/, builds arm64 kernel packages |
build-images.sh |
Assembles complete GPT disk images for all boards you've built bootloaders for; calls build-rootfs-img.sh to build the root filesystem if it doesn't exist yet |
build-rootfs-img.sh |
Runs debos on debian-rk3576-img.yaml to install the kernel into a partitioned image, then zeekstd-compresses it |
build-ospack.sh |
Runs mmdebstrap via debos (debian-rk3576-ospack.yaml) to build the Debian root filesystem tarball |
Other directories:
configs/— kernel config fragments merged on top of the base config (minconfig-mainlinefor mainline,linux-bsp/for the BSP kernel)overlays/— files copied into the root filesystem: systemd units, NetworkManager config, Broadcom Wi-Fi/BT firmware, KDE Plasma settings, SDDM autologin, U-Boot menu configvendor-dts/— Luckfox Omni3576 DTS/DTSI files and BSP device tree overlay sources (.dtso) for the EVB evaluation board and shared peripheralspatches/bsp/— kernel patches applied to the BSP tree (TypeC, panfrost DTS, audio card)rk_unpacker/— standalone Python tool to extract partition images from Rockchipupdate.imgfilesprebuilt/,src/,out/— build outputs and source clones; all gitignored
Every push to this repository (and to the tracked branches of its dependencies) triggers a full build on Buildbot. The resulting images land at dl-linux-images.flipp.dev/full-img/ and are updated automatically.
| Board | Target name | Notes |
|---|---|---|
flipper-one |
Our current Flipper One prototype | |
sige5 |
Same hardware sold under two names. Has DisplayPort on USB-C. Recommended for development. | |
rock-4d |
No DisplayPort on USB-C. Entering Maskrom requires a USB-A to USB-A cable. | |
nanopi-m5 |
||
omni3576 |
||
roc-pc |
The only RK3576 board supported by unmodified upstream U-Boot (as of mid-2025). | |
| Rockchip RK3576 EVB1 | evb |
Official Rockchip evaluation board. Not available for sale. |
The scripts are designed to run on Debian 13 (trixie). Other distributions may work but you'll need to find the equivalent packages yourself.
Use the included Dockerfile to avoid installing anything on the host:
# Clone the repo
git clone https://github.com/flipperdevices/flipperone-linux-build-scripts
cd flipperone-linux-build-scripts
# Build the container image (one-time; typically 20–30 min depending on network and CPU)
docker build -t flipperone-linux-build-scripts .
# Run a full build — images appear in out/images/
mkdir -p out
docker run --privileged --rm -v "$(pwd)/out:/artifacts" \
flipperone-linux-build-scriptsReplace docker with podman if that's what you have. --privileged is required because debos and mmdebstrap use loop devices and mount namespaces.
- Install VS Code and the Dev Containers extension
- Clone this repository and open it in VS Code
- Press
F1and select "Dev Containers: Reopen in Container" - Wait for the container to build (first time only)
- Run build scripts from the integrated terminal
For the bootloader:
sudo dpkg --add-architecture arm64
sudo apt update
sudo apt install git build-essential crossbuild-essential-arm64 bison flex \
python3-dev python3-libfdt python3-setuptools swig libssl-dev gnutls-dev \
python3-pyelftools device-tree-compilerFor the kernel:
sudo dpkg --add-architecture arm64
sudo apt update
sudo apt install git build-essential crossbuild-essential-arm64 bc bison flex \
imagemagick libssl-dev libdw-dev libelf-dev debhelper libssl-dev:arm64 rsyncFor assembling disk images — debos, bmaptool, and zeekstd all need to be installed from source:
sudo apt install golang pipx pigz cargo parted fdisk mmdebstrap \
systemd-resolved systemd-container qemu-user-binfmt \
libglib2.0-dev libostree-dev fakemachine
# debos
go install -v github.com/go-debos/debos/cmd/debos@latest
sudo install -m 755 ~/go/bin/debos /usr/local/bin
# zeekstd (requires Rust; v0.4.5+ needs Rust 1.91 — stick to v0.4.4-cli for now)
cargo install --git https://github.com/rorosen/zeekstd.git --tag v0.4.4-cli zeekstd_cli
sudo install -m 755 ~/.cargo/bin/zeekstd /usr/local/bin/
# bmaptool (Flipper fork)
sudo pipx install --global git+https://github.com/flipperdevices/bmaptool.git@flipper-develFor flashing images to boards over USB:
sudo apt install rockusbTo fetch and build U-Boot with open-source TF-A:
./build-uboot.shThe default source is the Flipper fork of U-Boot (flipperdevices/u-boot, branch rk3576), which has defconfigs for all supported boards. Note that as of mid-2025, only the Firefly ROC-RK3576-PC (roc-pc) is supported by vanilla upstream U-Boot; all other boards require either the Flipper fork or a board-specific tree.
To build for a specific board instead of all boards:
BOARD=sige5 ./build-uboot.shIf you need a different U-Boot source tree (e.g., a newer upstream tree for a specific board):
BOARD=sige5 UBOOT_GIT="https://source.denx.de/u-boot/contributors/kwiboo/u-boot.git" UBOOT_BRANCH="rk3576" ./build-uboot.sh
BOARD=omni3576 KEEP_SRC=yes ./build-uboot.sh
BOARD=nanopi-m5 KEEP_SRC=yes ./build-uboot.sh
BOARD=rock-4d KEEP_SRC=yes ./build-uboot.shKEEP_SRC=yes reuses the already-cloned source tree; KEEP_SRC=update pulls the latest commits without a full re-clone.
To use Rockchip's binary BL31 instead of open-source TF-A:
USE_BL31=vendor BOARD=sige5 UBOOT_GIT="https://source.denx.de/u-boot/contributors/kwiboo/u-boot.git" UBOOT_BRANCH="rk3576" ./build-uboot.sh
USE_BL31=vendor BOARD=omni3576 KEEP_SRC=yes ./build-uboot.sh
USE_BL31=vendor BOARD=nanopi-m5 KEEP_SRC=yes ./build-uboot.sh
USE_BL31=vendor BOARD=rock-4d KEEP_SRC=yes ./build-uboot.shOutputs go to prebuilt/u-boot/<board>/ — u-boot-rockchip.bin, rk3576_loader_v*.bin, and rk3576_loader_fspi1_v*.bin per board, plus USB loader variants.
./build-kernel-mainline.shTo rebuild without re-downloading:
KEEP_SRC=yes ./build-kernel-mainline.shTo incrementally pull new commits without a full fresh clone:
KEEP_SRC=update ./build-kernel-mainline.shTo build from a different tree:
LINUX_GIT=https://gitlab.collabora.com/hardware-enablement/rockchip-3588/linux.git \
LINUX_BRANCH=rockchip-devel ./build-kernel-mainline.sh./build-kernel-bsp.shThe same KEEP_SRC variants work here too.
Once you have bootloader outputs in prebuilt/u-boot/ and kernel outputs in prebuilt/linux/, run:
./build-images.shThis produces compressed images for each board whose bootloader is present. The kernel and root filesystem are shared; only the bootloader partition differs per board. Output files: out/debian-<sector-size>-<board>-<timestamp>.img.gz with a matching .bmap file, for both 512-byte and 4096-byte sector variants. When run inside the container, images go to out/images/ instead (the container sets IMG_OUT=/artifacts/images).
Don't run the mainline and BSP kernel scripts in parallel against the same output directory — both write to the same prebuilt/linux/ path and the final packaging step will fail. Run one, then the other (or set separate LINUX_OUT paths).
Note that as of mid-2025, upstream U-Boot doesn't have a driver for the Rockchip UFS controller, so boards with UFS cannot boot from it.
To produce a bootable SD card with your newly built Debian image, connect it to your host computer (e.g. through a card reader).
If you have a built-in SD card slot, you may use that, and the card will likely show up as /dev/mmcblkX (where X is the number identifying the respective SD/MMC controller, likely 0 if you only have one).
If you are using a USB card reader, the card will likely show up as /dev/sdX (where X is a lowercase letter). In this latter case you need to be triple careful, because any SATA or SCSI storage devices will also share the same naming scheme, and if you have important data on any other /dev/sdX device (such as your main system disk being called something like /dev/sda) you might end up inadvertently overwriting it if you pick the wrong one in the below commands, losing all your data. Please be careful.
sudo bmaptool copy out/debian-512-<your_board>-*.img.gz /dev/sdXRockchip devices include a special built-in mode called Maskrom, which allows flashing the board over a USB connection even if the board contains no bootloader or it is corrupted.
This mode is activated by holding down a MASKROM button when the power supply gets connected.
- Instructions for Radxa Rock 4D: Connect a USB A to A cable (or Type C to USB A, depending on your host computer's available USB ports) to the top USB 3.0 blue port, hold the MASKROM button and apply power to the board as usual via its Type C DC IN. Note that eMMC modules cannot be used together with the onboard SPI flash, as they share pins internally
- Instructions for ArmSoM Sige5: Connect a USB A to Type C cable (or Type C to Type C, depending on your host computer's available USB ports) to the Type C OTG port (marked TYPEC on the board), hold the MASKROM button and apply power to the board as usual via its Type C DC IN
You should then see something like this in lsusb command output:
Bus 002 Device 011: ID 2207:350e Fuzhou Rockchip Electronics Company
Your device is now ready for programming over the Rockusb protocol.
# Boot the board in USB upload mode
sudo rockusb download-boot prebuilt/u-boot/<your_board>/rk3576_loader_v*.bin
sudo rockusb write-bmap out/debian-512-<your_board>-*.img.gzContainer builds place bootloaders in out/u-boot/<board>/ and disk images in out/images/ instead.
Switch Radxa 4D into Maskrom mode, then:
rockusb list
rockusb download-boot prebuilt/u-boot/rock-4d/rk3576_loader_v*.bin
rockusb write-bmap out/debian-512-rock-4d-*.img.gz
rockusb reset-deviceThe default branch is dev. Branch off it, then open a PR back to dev:
git checkout dev && git pull
git checkout -b your-feature-name
# make changes, then:
git push origin your-feature-nameDon't push directly to dev.
Every PR and every push to dev triggers a full build on Buildbot — all boards, both kernels. The green checkmark on a commit means they all passed. If your PR makes the build go red, it won't merge.
To test locally before pushing:
docker build -t flipperone-linux-build-scripts .
mkdir -p out
docker run --privileged --rm -v "$(pwd)/out:/artifacts" flipperone-linux-build-scriptsDrop a config fragment file in configs/linux/ (mainline) or configs/linux-bsp/ (BSP). Every file in those directories gets merged in. One file per logical feature.
Files go in overlays/, mirroring the target filesystem: overlays/configs/ → /etc/, overlays/usr/ → /usr/, etc. Firmware blobs go in overlays/firmware/. For system packages, edit debian-rk3576-ospack.yaml.
- U-Boot: If the board needs a custom U-Boot tree, note the
UBOOT_GIT/UBOOT_BRANCH/BOARDvalues in the PR description. If it uses the Rockchip binary BL31, noteUSE_BL31=vendor. - Device tree (mainline kernel): If a DTS is already upstream, nothing extra is needed. If not, add the source to the appropriate location and document it.
- Device tree (BSP kernel): Vendor DTS files go in
vendor-dts/(seevendor-dts/omni3576/for the layout). Device tree overlays go invendor-dts/bsp/as.dtsofiles. - Kernel config: Board-specific options go as a fragment in
configs/linux/orconfigs/linux-bsp/. - Open a PR with a description of the board and how you tested that the image boots.





