XTOS / OPEN SOURCE REAL-TIME SYSTEMOPEN SOURCE · VERSION 0.9.0 · BUILD FROM SOURCE
文档构建

构建

x86_64、ARM64 和 RISC-V64 的依赖、参数、配置与产物。

本页目录

依赖

以下 apt 命令面向 Debian/Ubuntu Linux 主机。

本机 x86_64 路径需要 GCC 与 glibc 开发文件;内核还需要 make、flex、bison、bc、OpenSSL/ELF 开发文件和 Perl。

构建不自动安装依赖,交叉脚本开头也不会检查所有链接所需文件,所以“找到 gcc”不是完整的环境验证。

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
用途需要的工具或包
ARM64 编译aarch64-linux-gnu-gcc/ar/objdump;crossbuild-essential-arm64 与 libc6-dev-arm64-cross。
RISC-V64 编译riscv64-linux-gnu-gcc/ar/objdump;gcc-riscv64-linux-gnu、binutils-riscv64-linux-gnu 与 libc6-dev-riscv64-cross。
RISC-V64 启动qemu-system-misc 与 opensbi;脚本固定使用 /usr/share/qemu/opensbi-riscv64-generic-fw_dynamic.bin。
打包与模块索引GNU cpio 支持 --reproducible,gzip 支持 -n,kmod 提供 depmod,rsync 复制 DTB。
非破坏性预检;静态链接成功才说明对应 libc 开发文件可用。
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 对 libc6-dev-riscv64-cross 通常是推荐依赖,不是强依赖。

仅安装编译器或使用 --no-install-recommends 的环境应特别核对 libc.a;找不到时 -print-file-name 会原样返回 libc.a,而非完整路径。

静态 BusyBox 与 guest C 测试都需要这些开发文件。

参数

参数x86_64 build_system.shARM64 / RISC-V64
JOBS默认 2;向内核与 BusyBox 的并行 make 传入。默认 $(nproc);内核、BusyBox 与 SDK 构建使用该并发数。
BUILD_ROOT默认 <repo>/.build;创建后转成绝对路径。默认 <repo>/.build;自定义值宜直接给绝对路径。
CC脚本默认 gcc,用于 BusyBox 和 BCI 示例;内核构建不显式转发该变量,不能视为全系统工具链选择器。脚本固定 aarch64-linux-gnu-gcc 或 riscv64-linux-gnu-gcc,并设置对应 AR/CROSS_COMPILE;外部 CC 不会改换目标。
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

CC 作为环境变量传给 make 时,用户态 Makefile 可以继承;build_system.sh 的默认局部 CC 与 GNU make 的内建 CC 不是同一种传递方式。

首次构建建议使用脚本默认 GNU 工具链,不把 CC=clang、ARCH 或 CROSS_COMPILE 当成三种完整系统脚本共同支持的自由组合。

需要替换工具链时应逐段确认脚本和 Makefile,并重新验证全部产物。

x86_64 阶段

bash
JOBS=$(nproc) ./scripts/build_system.sh
QEMU_TIMEOUT=180 ./scripts/verify_system.sh
  1. build_kernel.sh 调用 prepare_linux.sh,生成 x86 defconfig,合并 kernel/xtos_defconfig,olddefconfig 后核对 PREEMPT_RT、XTOS_SCHED、BCI 与 serdev,再构建 bzImage 和 modules。
  2. BusyBox 使用 system/busybox_defconfig,要求 STATIC、BUSYBOX、ASH、MODPROBE;脚本试运行 BusyBox 并用 readelf 检查没有 INTERP 动态解释器。
  3. 复制 sdk、tools、examples 到 userspace-source,编译三个库、静态 EEG 管线/基准、rt/spsc/signal C 测试及 bci_test。系统内安装 .a 库,不依赖客体动态加载这些 SDK .so。
  4. 复制 rootfs 骨架,安装 applet、头文件、fixture 和模块,执行 depmod 后以固定 mtime、排序、稳定 owner 和 gzip 头打包,复制内核镜像及最终配置到 images。

system_build=pass 是构建结束标记。真正系统验证是后续 verify_system.sh:它会执行 /usr/bin/xtos-selftest 并检查 XTOS_SYSTEM_TEST=PASS。构建阶段删除并重建的是 userspace-source/rootfs 等生成目录,不是仓库源目录;不要把需要保存的数据放到这些暂存位置。

交叉阶段

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

交叉脚本固定 ARCH=arm64 或 ARCH=riscv,使用相应 GNU 前缀,首次生成 defconfig、启用 RT、合并 XTOS 配置并设置虚拟平台外设。

ARM64 配置 PL011 与 ttyAMA0;RISC-V 配置 8250 串口与 ttyS0。

两者构建 Image、dtbs、modules,复制 Image/DTB,生成静态 BusyBox 与 /etc/inittab。

三个 SDK 会在源目录清理后以目标 CC/AR 重建,再用目标 objdump 检查 .a 成员架构;rt 与 signal 的已提交 C 测试静态链接安装到 /bin。

部分测试编译失败分支只警告而继续,所以“Build Complete”不能证明这些测试都已存在。

verify_guest_* 将缺少程序记录为 guest_test_*=missing 并令验证失败。

产物路径

下面所有路径相对 BUILD_ROOT(默认 .build),不是相对内核源码目录。QEMU 通常读取安装/复制后的镜像;原始内核输出路径有助于诊断构建,二者不要混用。

产物x86_64ARM64RISC-V64
QEMU 内核镜像images/xtos-bzImagekernel-install-arm64/Imagekernel-install-riscv64/Image
原始内核镜像kernel-build/arch/x86/boot/bzImagekernel-build-arm64/arch/arm64/boot/Imagekernel-build-riscv64/arch/riscv/boot/Image
正常 initramfsimages/xtos-rootfs.cpio.gzinitramfs-arm64.cpio.gzinitramfs-riscv64.cpio.gz
未打包 rootfsrootfs/rootfs-arm64/rootfs-riscv64/
最终内核配置kernel-build/.config;另存 images/kernel.configkernel-build-arm64/.configkernel-build-riscv64/.config
DTB 安装目录此 QEMU pc 路径不使用 DTB 目录。kernel-install-arm64/dtbs/kernel-install-riscv64/dtbs/
仅在对应架构已构建、使用默认 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 的成员应显示 architecture: aarch64,RISC-V64 应显示 architecture: riscv:rv64。交叉架构文件不能直接在 x86 主机执行;在对应 QEMU 客体测试它们。DTB 目录存在不意味着其中所有板卡都已做真实硬件验证。

可复现构建

scripts/reproducible_env.sh 需要用点命令 source 到当前 shell。

它将 SOURCE_DATE_EPOCH 默认固定为 HEAD 提交时间,可提前覆盖;同时为 KBUILD_BUILD_VERSION 提供默认值 1、为 KBUILD_BUILD_USER/HOST 提供默认值 xbuild,并设置 KBUILD_BUILD_TIMESTAMP、LC_ALL=C 与 TZ=UTC;已有 KBUILD 覆盖值会保留。

三个系统构建脚本按 epoch 修改 rootfs mtime、排序条目、固定 owner 0:0 并使用 cpio --reproducible 与 gzip -n。

两个目录必须事先不存在或为空;本示例不删除当前构建目录。
. ./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

可复现性需要固定提交、配置、工具链和依赖,以及干净的内核/BusyBox/用户态输出;只有 source 环境脚本后做增量构建并不充分。BusyBox 的旧配置和头文件、内核计数及残留 rootfs 都可能改变结果。需要清理时先确认哪些目录完全可再生成并保存证据,本页用新的构建目录避免破坏现有文件。

构建检查

  1. 确认生成的是预期架构镜像、配置和 initramfs,所有命令使用相同 BUILD_ROOT。核对最终 CONFIG_PREEMPT_RT=y、XTOS_SCHED=y、BCI=m。
  2. 运行对应启动与客体验证。ARM/RISC-V 的 verify_system_* 接受少量失败,所以必须检查日志并执行更严格的 verify_guest_*。
  3. 静态链接找不到 -lc 时检查交叉 libc 开发包;archive 架构错误时确认没有并发或旧架构库;test_*=missing 时回看编译警告,不用构建成功标记掩盖它。

源码依据:提交 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 与 system/busybox_defconfig。参数、产物路径和清理行为以这些脚本为准。