XTOS / OPEN SOURCE REAL-TIME SYSTEMOPEN SOURCE · VERSION 0.9.0 · BUILD FROM SOURCE
DocsBuild

Build

Dependencies, parameters, configuration, and artifacts for x86_64, ARM64, and RISC-V64.

On this page

Dependencies

The apt commands below target Debian/Ubuntu Linux hosts.

Native x86_64 needs GCC and glibc development files; kernel building additionally needs make, flex, bison, bc, OpenSSL/ELF development files, and Perl.

Builders do not install dependencies automatically, and cross builders do not initially check every link input, so finding gcc is not a complete environment check.

bash
sudo apt-get update
sudo apt-get install -y \
  bash git build-essential libc6-dev flex bison bc libssl-dev libelf-dev \
  cpio gzip rsync python3 kmod binutils file patch perl pkg-config \
  coreutils findutils grep sed diffutils qemu-system-x86
bash
sudo apt-get install -y \
  crossbuild-essential-arm64 libc6-dev-arm64-cross qemu-system-arm \
  gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu \
  libc6-dev-riscv64-cross qemu-system-misc opensbi
PurposeTools or packages
ARM64 compilationaarch64-linux-gnu-gcc/ar/objdump; crossbuild-essential-arm64 and libc6-dev-arm64-cross.
RISC-V64 compilationriscv64-linux-gnu-gcc/ar/objdump; gcc-riscv64-linux-gnu, binutils-riscv64-linux-gnu, and libc6-dev-riscv64-cross.
RISC-V64 bootqemu-system-misc and opensbi; scripts use /usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin.
Packing and module indexesGNU cpio with --reproducible, gzip with -n, kmod for depmod, and rsync for DTB copying.
Non-destructive preflight; successful static links establish that the corresponding libc development files are usable.
aarch64-linux-gnu-gcc -print-file-name=libc.a
riscv64-linux-gnu-gcc -print-file-name=libc.a
printf 'int main(void) { return 0; }\n' | aarch64-linux-gnu-gcc -static -x c - -o /dev/null
printf 'int main(void) { return 0; }\n' | riscv64-linux-gnu-gcc -static -x c - -o /dev/null
test -r /usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin

gcc-riscv64-linux-gnu commonly recommends rather than requires libc6-dev-riscv64-cross.

Environments installing only the compiler or using --no-install-recommends should check libc.a explicitly; if missing, -print-file-name returns libc.a unchanged rather than a full path.

Static BusyBox and guest C tests both need these development files.

Parameters

Parameterx86_64 build_system.shARM64 / RISC-V64
JOBSDefaults to 2; passed to parallel kernel and BusyBox make.Defaults to $(nproc); used for kernel, BusyBox, and SDK builds.
BUILD_ROOTDefaults to <repo>/.build; created and converted to an absolute path.Defaults to <repo>/.build; use an absolute custom path.
CCScript default gcc, used for BusyBox and the BCI example; the kernel invocation does not explicitly forward it, so it is not a whole-system toolchain selector.Scripts fix aarch64-linux-gnu-gcc or riscv64-linux-gnu-gcc and the matching AR/CROSS_COMPILE; external CC does not switch the target.
bash
export BUILD_ROOT="$PWD/.build-work"
JOBS=2 CC=gcc ./scripts/build_system.sh
BUILD_ROOT="$BUILD_ROOT" QEMU_TIMEOUT=180 ./scripts/verify_system.sh

User-space Makefiles can inherit CC when it is supplied in the environment; build_system.sh’s default local CC and GNU make’s built-in CC are not the same propagation mechanism.

For a first build, use the scripts’ default GNU toolchains rather than treating CC=clang, ARCH, and CROSS_COMPILE as freely composable parameters across all system builders.

Toolchain replacement requires checking each script and Makefile and revalidating every artifact.

x86_64 stages

bash
JOBS=$(nproc) ./scripts/build_system.sh
QEMU_TIMEOUT=180 ./scripts/verify_system.sh
  1. build_kernel.sh invokes prepare_linux.sh, generates x86 defconfig, merges kernel/xtos_defconfig, checks PREEMPT_RT, XTOS_SCHED, BCI, and serdev after olddefconfig, then builds bzImage and modules.
  2. BusyBox uses system/busybox_defconfig and requires STATIC, BUSYBOX, ASH, and MODPROBE. The script runs BusyBox and uses readelf to check that no INTERP dynamic interpreter exists.
  3. Copy sdk, tools, and examples to userspace-source; compile three libraries, the static EEG pipeline/benchmark, rt/spsc/signal C tests, and bci_test. The system installs .a archives and does not depend on loading SDK .so files in the guest.
  4. Copy the rootfs skeleton, install applets, headers, the fixture, and modules, run depmod, pack with fixed mtimes, sorted entries, stable ownership and gzip headers, then copy the kernel image and final configuration into images.

system_build=pass marks build completion. System verification is the subsequent verify_system.sh, which runs /usr/bin/xtos-selftest and checks XTOS_SYSTEM_TEST=PASS. Build-time deletion and rebuilding affect generated directories such as userspace-source/rootfs, not repository source directories. Do not store data that must survive there.

Cross-architecture stages

bash
JOBS=$(nproc) ./scripts/build_system_arm64.sh
QEMU_TIMEOUT=180 ./scripts/verify_system_arm64.sh
QEMU_TIMEOUT=300 ./scripts/verify_guest_arm64.sh

JOBS=$(nproc) ./scripts/build_system_riscv64.sh
QEMU_TIMEOUT=300 ./scripts/verify_system_riscv64.sh
QEMU_TIMEOUT=360 ./scripts/verify_guest_riscv64.sh

Cross builders fix ARCH=arm64 or ARCH=riscv, use the corresponding GNU prefix, initially generate defconfig, enable RT, merge XTOS configuration, and configure virtual-platform devices.

ARM64 uses PL011 and ttyAMA0; RISC-V uses an 8250 serial console and ttyS0.

Both build Image, dtbs, and modules, copy Image/DTBs, and create static BusyBox and /etc/inittab.

The three SDKs are cleaned in source directories and rebuilt with target CC/AR, then checked with target objdump for .a member architecture. Committed rt and signal C tests are statically linked and installed under /bin.

Some test compilation failure branches warn and continue, so Build Complete does not establish that all tests exist.

verify_guest_* reports missing executables as guest_test_*=missing and fails validation.

Artifact paths

Every path below is relative to BUILD_ROOT, which defaults to .build, not to the kernel source directory. QEMU normally reads the installed/copied image; raw kernel output paths help diagnose builds. Keep the two roles distinct.

Artifactx86_64ARM64RISC-V64
QEMU kernel imageimages/xtos-bzImagekernel-install-arm64/Imagekernel-install-riscv64/Image
Raw kernel imagekernel-build/arch/x86/boot/bzImagekernel-build-arm64/arch/arm64/boot/Imagekernel-build-riscv64/arch/riscv/boot/Image
Normal initramfsimages/xtos-rootfs.cpio.gzinitramfs-arm64.cpio.gzinitramfs-riscv64.cpio.gz
Unpacked rootfsrootfs/rootfs-arm64/rootfs-riscv64/
Final kernel configkernel-build/.config; copied to images/kernel.configkernel-build-arm64/.configkernel-build-riscv64/.config
DTB install directoryThis QEMU pc path does not use a DTB directory.kernel-install-arm64/dtbs/kernel-install-riscv64/dtbs/
Run only after the matching architectures are built with the default BUILD_ROOT.
file .build/images/xtos-bzImage .build/kernel-install-arm64/Image .build/kernel-install-riscv64/Image
aarch64-linux-gnu-objdump -f .build/rootfs-arm64/usr/lib/libxtos-rt.a
riscv64-linux-gnu-objdump -f .build/rootfs-riscv64/usr/lib/libxtos-rt.a

ARM64 archive members should report architecture: aarch64, and RISC-V64 members architecture: riscv:rv64. Cross-architecture executables cannot be run directly on an x86 host; test them in the corresponding QEMU guest. A DTB directory existing does not establish real-hardware validation for all represented boards.

Reproducible builds

Source scripts/reproducible_env.sh into the current shell with the dot command.

It defaults SOURCE_DATE_EPOCH to the HEAD commit timestamp, allowing a prior override, and provides defaults of KBUILD_BUILD_VERSION=1 and KBUILD_BUILD_USER/HOST=xbuild while respecting existing overrides, and sets KBUILD_BUILD_TIMESTAMP, LC_ALL=C, and TZ=UTC.

All three system builders normalize rootfs mtimes to the epoch, sort entries, fix ownership to 0:0, and use cpio --reproducible and gzip -n.

Both directories must initially be absent or empty; this example does not delete the current build directory.
. ./scripts/reproducible_env.sh
printf 'SOURCE_DATE_EPOCH=%s\n' "$SOURCE_DATE_EPOCH"
BUILD_ROOT="$PWD/.build-repro-a" JOBS=2 ./scripts/build_system.sh
BUILD_ROOT="$PWD/.build-repro-b" JOBS=2 ./scripts/build_system.sh
cmp .build-repro-a/images/xtos-bzImage .build-repro-b/images/xtos-bzImage
cmp .build-repro-a/images/xtos-rootfs.cpio.gz .build-repro-b/images/xtos-rootfs.cpio.gz
sha256sum .build-repro-a/images/xtos-bzImage .build-repro-b/images/xtos-bzImage
sha256sum .build-repro-a/images/xtos-rootfs.cpio.gz .build-repro-b/images/xtos-rootfs.cpio.gz
BUILD_ROOT="$PWD/.build-repro-a" QEMU_TIMEOUT=180 ./scripts/verify_system.sh

Reproducibility requires a fixed commit, configuration, toolchain, dependencies, and clean kernel/BusyBox/user-space outputs; sourcing the environment and running an incremental build is insufficient. Old BusyBox configuration and generated headers, kernel counters, and residual rootfs files can change results. Before cleanup, identify regenerable directories and preserve evidence. This page uses fresh build directories to avoid destroying existing files.

Build checks

  1. Confirm the intended architecture’s image, configuration, and initramfs were produced and that every command uses the same BUILD_ROOT. Check final CONFIG_PREEMPT_RT=y, XTOS_SCHED=y, and BCI=m.
  2. Run the matching boot and guest checks. ARM/RISC-V verify_system_* tolerates a small number of failures, so inspect logs and execute the stricter verify_guest_*.
  3. If static linking cannot find -lc, check cross libc development packages. For archive architecture errors, investigate concurrent builds or stale libraries. For test_*=missing, inspect compiler warnings rather than masking the issue with a build-completion marker.

Source references at commit dd313955ad57542bcd2af8827157d1bbd0cf5e83: scripts/build_kernel.sh, scripts/prepare_linux.sh, scripts/build_system.sh, scripts/build_system_arm64.sh, scripts/build_system_riscv64.sh, scripts/reproducible_env.sh, scripts/verify_guest_arm64.sh, scripts/verify_guest_riscv64.sh, kernel/xtos_defconfig, and system/busybox_defconfig. These scripts determine parameters, artifact paths, and cleanup behavior.