Build DCENT_OS From Source
Home » DCENT_OS — Open-Source Antminer Firmware » Build DCENT_OS From Source
The Rust daemon, dashboard and Buildroot integration are public under GPL-3.0 and build from the repository. A full flashable Antminer image is a different boundary: it reuses boot-critical vendor components that D-Central cannot redistribute in the source repository. Those are two different jobs with two different answers, and most of the confusion here comes from treating them as one.
On this page
What is open and what is not redistributed
| Component | Repository status | Build/audit path |
|---|---|---|
dcentrald Rust mining daemon | GPL-3.0 source | Builds from a fresh clone for ARMv7 and AArch64 targets |
| React/TypeScript dashboard | GPL-3.0 source | Builds from the repository toolchain (Node and npm) |
| Host-side test suites | GPL-3.0 source | Run on your machine with no miner attached |
| Buildroot external tree and configuration | GPL-3.0 project source/configuration | Defines the minimal Linux userspace and integration |
| SoC kernel, FPGA bitstream, FSBL/U-Boot | Boot-critical vendor/upstream artifacts; not redistributed in the source repo | Must be supplied locally from firmware the operator is authorized to use and must match pinned hashes |
| Signed release package | Prebuilt guarded artifact | Contains SHA-256 manifests, Ed25519 public key and signed manifest |
Build the open daemon
The workspace pins its own Rust toolchain, so you do not pick a version. A
rust-toolchain.toml at the daemon workspace root names channel 1.90.0,
the rustfmt and clippy components, and both cross targets
— armv7-unknown-linux-musleabihf for Zynq control boards and
aarch64-unknown-linux-musl for Amlogic. Install rustup and it provisions
all of that on the first build. The pin exists because the primary daemon workspace previously did
not have one, so a fresh clone built with whatever toolchain the contributor happened to have.
The prerequisite that stops most first builds
Read this before you run anything, because the error message does not point at the fix. The
daemon's dependency tree includes ring, which compiles C and assembly. Rust's own
cross-linking needs no external GCC — rust-lld handles it, and the
repository's cargo config says so. C compilation is a separate matter. On a host with no
ARM C cross-compiler, the build stops here:
error occurred in cc-rs: failed to find tool "arm-linux-musleabihf-gcc": program not found
warning: build failed, waiting for other jobs to finish...
Exit code 101, on ring v0.17.14. If you already have an ARM C cross-toolchain on
your PATH you will never see it. If you do not, this is where you stop, and nothing in the message
tells you why. The fix is to point the cc crate at a C cross-compiler through its
per-target environment variables:
# Linux or CI - real musl-cross-make tools
export CC_armv7_unknown_linux_musleabihf=arm-linux-musleabihf-gcc
export AR_armv7_unknown_linux_musleabihf=arm-linux-musleabihf-ar
# Windows - the wrappers the repository already ships (needs Zig 0.13.0)
set CC_armv7_unknown_linux_musleabihf=%CD%\zig-cc-arm.bat
set AR_armv7_unknown_linux_musleabihf=%CD%\zig-ar-arm.bat
The AArch64 equivalents are CC_aarch64_unknown_linux_musl and
AR_aarch64_unknown_linux_musl, with zig-cc-aarch64.bat and
zig-ar-aarch64.bat. Those four wrapper scripts are in the public tree under
dcentrald/; they strip the --target flag cc-rs adds and hand
the compile to zig cc. The deploy helper exports the same variables for you when you
have not set your own, which is why a deploy sometimes builds cleanly on a machine where a bare
cargo build did not. The reason the repository does not simply put a default in a
cargo [env] block is documented in dcentrald/.cargo/config.toml: cargo
resolves the path to absolute form first, and cc-rs on Windows can mis-split an
absolute path containing spaces.
Then the build itself
git clone https://github.com/DCentralTech/DCENT_OS.git
cd DCENT_OS/DCENT_OS_Antminer/dcentrald
cargo build --release --target armv7-unknown-linux-musleabihf # Zynq
cargo build --release --target aarch64-unknown-linux-musl # Amlogic
With the C cross-compiler in place, that produces an ARM dcentrald binary at
target/<triple>/release/dcentrald. It does not by itself produce a complete
bootable image, and it is not a statement about any particular miner — what happens when that
binary reaches hardware is a separate question with a separate answer.
The dashboard and the host-side tests need no cross-compiler at all:
cd dashboard && npm install && npm run build
cd dcentrald
cargo test
cargo fmt --all --check
cargo clippy --all-targets
The repository also carries a Docker wrapper, scripts/build-dcentrald.sh, which
builds a pinned cross image that supplies the C toolchain. It is the lane our own build environment
uses; from a fresh public clone it currently stops on missing tracked inputs, so use the
host-toolchain route above until that is fixed.
The build environment, concretely
- Default workspace build. A bare
cargo buildcompiles the daemon stack through the workspace'sdefault-members. It deliberately excludes the optionalpic-recoverypackage, which is diagnostic-only and needs no vendor bitstream. Build it explicitly withcargo build -p pic-recoveryif you want it. - Host OS for the image lane: Ubuntu 22.04, in a container. The build image
installs
build-essential,device-tree-compiler,u-boot-tools,squashfs-tools,libncurses-dev,libssl-dev,cpio,bcandrsyncamong others. - Windows hosts: use WSL or Docker for anything beyond the daemon build. Several crates carry Linux-only hardware-abstraction code and are validated on the target rather than on a Windows host.
The Buildroot layer
The image lane wraps Buildroot with an external tree at br2_external_dcentos/.
Buildroot is not vendored — the setup target clones it and pins it to a specific commit for
repeatability. Buildroot's own manual is better than anything we would write and we are not going to
reproduce it; what follows is only the part that is specific to this repository.
make setup # clone Buildroot at the pinned commit, apply the merged defconfig
make # build
make menuconfig # adjust Buildroot config
make savedefconfig # write your changes back
Defconfigs are merged, not monolithic. The tree carries 15 defconfigs — S9, three AM2 Zynq boards, two BeagleBone variants, and nine Amlogic boards — plus two fragments. The merge step concatenates a workspace-wide common fragment, then an architecture-specific fragment where one applies, then the per-product defconfig last so its overrides win. The merged file is generated and git-ignored; edit the fragments or the per-product defconfig, never the merged output.
The default target is the S9. Any other board needs both variables on the command line:
make DEFCONFIG=dcentos_am3_s21_defconfig \
DEFCONFIG_FRAGMENTS="dcentos-common.fragment dcentos_am3_aml_common.fragment" \
setup
Pass the defconfig without its fragments and you get a config missing everything the common layer provides. This is the single most common way to waste an afternoon here.
That a defconfig exists for a board is not a statement that an image for it can be packaged. Fifteen defconfigs exist; one target is admitted by the release capsule. The gap between those two numbers is the vendor-artifact boundary described below, not a to-do list.
Verifying your build
make test # compile-gate every workspace test for armv7 musl, in Docker
make test RUN_TESTS=1 # compile and execute on the container host target
make test-host # the no-hardware crate tests, no container
make verify # the local gate that `make release` runs before building
make install-hooks # install the commit/push gates once per checkout
make release runs make verify itself, and the hook-only skip variable
does not bypass release verification. None of these need a miner.
Build a full image
The repository's production capsule currently admits the S9 target. It expects restricted boot inputs, release keys and a digest-pinned builder described in the release-candidate runbook. Direct development packaging fails closed when it cannot satisfy the release receipt.
make release RELEASE_TARGET=s9
Two variables gate that command: a manifest public-key pin and a release signing key. Neither is
a secret you have to be given — scripts/generate_release_keypair.sh is in the
public tree, it generates an Ed25519 keypair with openssl, and the Makefile's own error
message names it. What a public cloner cannot supply is the boot-critical vendor material: the SoC
kernel, the FPGA bitstream and the FSBL/U-Boot chain, which come from each miner's stock or
BraiinsOS firmware, are not ours to redistribute, and must hash-match a recorded manifest. Producing
your own S9 image means extracting those artifacts from firmware you are authorized to
use — in practice, from a unit you own. We can describe the boundary. We cannot hand
you the artifacts, and you should be suspicious of anyone who does. Calling the surrounding stack
open source does not make third-party redistribution rights appear.
Three lanes refuse before they do any work, so nobody burns an afternoon on them:
make devimage packaging is fail-closed and exits with an error. It cannot satisfy the invocation-bound build-receipt contract the release lane depends on.- Direct Buildroot packaging through the inner Docker driver is likewise disabled until a separate lab capsule exists; it refuses before doing any build work.
make releaseis S9 only and rejects any other release target.
So the buildable, useful, genuinely supported artifact from this repository is the daemon. That is what most contributors need, and it is enough to get a running process on real hardware.
Reproducibility status
We do not claim byte-for-byte reproducible firmware. The release lane pins a Buildroot commit, a digest-pinned builder image and a toolchain SHA-256, and it records a build receipt — but a third party cannot currently reproduce a signed image bit-for-bit from the public tree alone, because of the same non-redistributable boot inputs described above. A reproducibility claim needs a published environment, hashes from independent rebuilds, and a documented comparison of any differences. Stating otherwise would be a claim we cannot back.
Upstream we lean on
The build is Buildroot with a BR2_EXTERNAL tree, and Buildroot's own manual is the
right place to understand the underlying system rather than just drive ours. Same for the Rust
project's cross-compilation model and Xilinx's Zynq boot documentation — all three publish
better documentation for their own layers than we could write, so we link them instead of cloning
them. Braiins made the Antminer control board an open, scriptable Linux target years before we
shipped anything. We credit the 256 Foundation's Mujina, ESP-Miner and Skot's reverse-engineering
work as references studied during design; no code was forked from them.
You have a binary. Now what?
A compiled dcentrald is not a running miner, and for most boards it will never become
a flashable image — the release capsule admits one target. The route from binary to running
daemon is a warm deployment over the Linux already on the control board: a script that cross-compiles,
copies, takes over from the incumbent mining process and starts the daemon. On every board family
except the S9 it writes only to /tmp, so a power cycle undoes it completely — and
a daemon that starts is still not a daemon that mines.
That route, its per-board recovery paths and the guardrails it will stop you at are documented in Run DCENT_OS from your own build. Read it before you point anything at hardware. If you first want to know what your machine actually is, install routes by control board is the per-board lookup: one model badge maps to several control boards and most of them cannot mine.
Audit trail
- DEVELOPMENT.md — source and vendor-artifact boundary
- TESTING.md — no-hardware through persistent-install tiers
- PLATFORMS.md — per-model evidence and install readiness
- Third-party notices and licenses
Boundary reviewed 2026-08-29. Checked against the public GPL-3.0 tree at commit 6f61603. This page distinguishes buildable source from a complete redistributable boot image, and every command on it was executed before it was published.
Companion tool — DCENT_Toolbox: Install DCENT_Toolbox from source.
Related: Check your control-board target before you build.
