构建
x86_64、ARM64 和 RISC-V64 的依赖、参数、配置与产物。
本页目录
依赖
以下 apt 命令面向 Debian/Ubuntu Linux 主机。
本机 x86_64 路径需要 GCC 与 glibc 开发文件;内核还需要 make、flex、bison、bc、OpenSSL/ELF 开发文件和 Perl。
构建不自动安装依赖,交叉脚本开头也不会检查所有链接所需文件,所以“找到 gcc”不是完整的环境验证。
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-x86sudo 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。 |
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.bingcc-riscv64-linux-gnu 对 libc6-dev-riscv64-cross 通常是推荐依赖,不是强依赖。
仅安装编译器或使用 --no-install-recommends 的环境应特别核对 libc.a;找不到时 -print-file-name 会原样返回 libc.a,而非完整路径。
静态 BusyBox 与 guest C 测试都需要这些开发文件。
参数
| 参数 | x86_64 build_system.sh | ARM64 / 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 不会改换目标。 |
export BUILD_ROOT="$PWD/.build-work"
JOBS=2 CC=gcc ./scripts/build_system.sh
BUILD_ROOT="$BUILD_ROOT" QEMU_TIMEOUT=180 ./scripts/verify_system.shCC 作为环境变量传给 make 时,用户态 Makefile 可以继承;build_system.sh 的默认局部 CC 与 GNU make 的内建 CC 不是同一种传递方式。
首次构建建议使用脚本默认 GNU 工具链,不把 CC=clang、ARCH 或 CROSS_COMPILE 当成三种完整系统脚本共同支持的自由组合。
需要替换工具链时应逐段确认脚本和 Makefile,并重新验证全部产物。
x86_64 阶段
JOBS=$(nproc) ./scripts/build_system.sh
QEMU_TIMEOUT=180 ./scripts/verify_system.sh- build_kernel.sh 调用 prepare_linux.sh,生成 x86 defconfig,合并 kernel/xtos_defconfig,olddefconfig 后核对 PREEMPT_RT、XTOS_SCHED、BCI 与 serdev,再构建 bzImage 和 modules。
- BusyBox 使用 system/busybox_defconfig,要求 STATIC、BUSYBOX、ASH、MODPROBE;脚本试运行 BusyBox 并用 readelf 检查没有 INTERP 动态解释器。
- 复制 sdk、tools、examples 到 userspace-source,编译三个库、静态 EEG 管线/基准、rt/spsc/signal C 测试及 bci_test。系统内安装 .a 库,不依赖客体动态加载这些 SDK .so。
- 复制 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 等生成目录,不是仓库源目录;不要把需要保存的数据放到这些暂存位置。
交叉阶段
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_64 | ARM64 | RISC-V64 |
|---|---|---|---|
| QEMU 内核镜像 | images/xtos-bzImage | kernel-install-arm64/Image | kernel-install-riscv64/Image |
| 原始内核镜像 | kernel-build/arch/x86/boot/bzImage | kernel-build-arm64/arch/arm64/boot/Image | kernel-build-riscv64/arch/riscv/boot/Image |
| 正常 initramfs | images/xtos-rootfs.cpio.gz | initramfs-arm64.cpio.gz | initramfs-riscv64.cpio.gz |
| 未打包 rootfs | rootfs/ | rootfs-arm64/ | rootfs-riscv64/ |
| 最终内核配置 | kernel-build/.config;另存 images/kernel.config | kernel-build-arm64/.config | kernel-build-riscv64/.config |
| DTB 安装目录 | 此 QEMU pc 路径不使用 DTB 目录。 | kernel-install-arm64/dtbs/ | kernel-install-riscv64/dtbs/ |
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.aARM64 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 都可能改变结果。需要清理时先确认哪些目录完全可再生成并保存证据,本页用新的构建目录避免破坏现有文件。
构建检查
- 确认生成的是预期架构镜像、配置和 initramfs,所有命令使用相同 BUILD_ROOT。核对最终 CONFIG_PREEMPT_RT=y、XTOS_SCHED=y、BCI=m。
- 运行对应启动与客体验证。ARM/RISC-V 的 verify_system_* 接受少量失败,所以必须检查日志并执行更严格的 verify_guest_*。
- 静态链接找不到 -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。参数、产物路径和清理行为以这些脚本为准。