本文档面向初次接触 OrangePi 镜像构建的开发者,系统梳理 orangepi-build 仓库的核心能力、交互流程与工程结构。阅读后你将理解:执行 ./build.sh 时背后发生了什么、四个构建选项的区别、以及如何根据目标板卡找到对应的配置入口。若你尚未配置交叉编译环境,建议先阅读 交叉编译环境深度配置。
构建系统能做什么
orangepi-build 是一套基于 Bash 的模块化构建框架,专门用于将 U-Boot、Linux 内核、根文件系统打包成可烧录的 OrangePi 系统镜像。与通用发行版构建工具不同,它内建了多 SoC 适配层:从板级配置(Board)到芯片家族(Family)再到架构默认(Arch),层层继承、逐级覆盖,让同一套脚本可以同时服务 Rockchip、Allwinner、Cix 等多种平台。
在本项目的实际使用中,构建系统主要面向以下三款定制板卡:
| 固件编号 | 板卡代号 | SoC | 典型配置 |
|---|---|---|---|
| 01 | robopi1 |
Rockchip RK3588 | 八核、2.5GbE、NVMe、eMMC |
| 02 | robopi2 |
Rockchip RK3588S | 八核、USB3、WiFi/BT |
| 03 | robopi3 |
Rockchip RK3588 | 八核、2.5GbE、NVMe、eMMC |
构建系统支持四种输出产物:U-Boot 包、内核包、根文件系统、完整系统镜像。对于机器人系统固件集成而言,通常直接选择 image 即可一次性获得可烧录到 SD 卡或 eMMC 的完整镜像。
Sources: README_CN.md, main.sh
环境要求与快速开始
在开始构建之前,请确保你的编译主机满足以下条件:运行 Ubuntu 22.04 (Jammy) 或兼容的 Debian 发行版、x86_64 架构、具备 root/sudo 权限、可用磁盘空间大于 100GB,并且能够访问 Ubuntu 官方仓库与 GitHub(中国大陆用户可通过配置自动切换清华镜像与 Gitee 源)。
最简单的启动方式只需要两条命令:
cd orangepi-build
./build.sh
脚本会自动检测运行环境、拉取更新、加载配置模板,并弹出交互式菜单。如果你希望跳过菜单直接指定配置,可以在 userpatches/ 目录下创建自定义配置文件,例如 config-robopi1.conf,然后通过 ./build.sh robopi1 直接调用。
Sources: README_CN.md, build.sh
交互式菜单全流程
当你运行 ./build.sh 后,scripts/main.sh 会按顺序通过 whiptail 弹窗收集构建参数。这个流程可以概括为五个决策点,如下图所示:
flowchart TD
A[执行 ./build.sh] --> B[选择 Board<br/>robopi1 / robopi2 / robopi3]
B --> C[选择 Build Option<br/>u-boot / kernel / rootfs / image]
C --> D[选择 Kernel Branch<br/>legacy / current / develop]
D --> E[选择 OS Release<br/>bullseye / bookworm / jammy ...]
E --> F{是否桌面环境?}
F -->|是| G[选择 Desktop Environment]
F -->|否| H[选择 Standard 或 Minimal]
G --> I[开始编译与打包]
H --> I
第一步:板卡选择。main.sh 中维护了一个板卡列表,每个板卡关联一个位于 external/config/boards/ 下的 .conf 文件。以 robopi1 为例,配置中指定了 BOARDFAMILY="rockchip-rk3588"、BOOTCONFIG="robopi1_defconfig" 以及支持的 KERNEL_TARGET="legacy,current,develop"。
第二步:构建选项。这是初学者最容易困惑的地方,建议按需求选择:
| 选项 | 含义 | 适用场景 |
|---|---|---|
u-boot |
仅编译引导加载器并生成 .deb 包 |
调试启动流程、更新 SPL |
kernel |
仅编译内核及模块并生成 .deb 包 |
驱动开发、内核配置调整 |
rootfs |
构建根文件系统与所有软件包 | 定制系统预装软件 |
image |
完整流程:U-Boot + 内核 + rootfs 并打包为 .img |
最终发布、烧录使用 |
第三步至第五步:根据板卡配置中 KERNEL_TARGET 的声明,菜单会动态显示可用的内核分支(如 legacy 对应 5.10 内核、current 对应 6.1 内核、develop 对应 6.6 内核);接着选择基于的发行版(Debian/Ubuntu 版本);最后决定输出 CLI 镜像还是 Desktop 镜像。如果中途需要自定义内核配置,还可以在对应步骤开启 KERNEL_CONFIGURE=yes,在编译前弹出 menuconfig。
Sources: main.sh, robopi1.conf
构建流程架构
当所有交互参数收集完毕后,真正的构建工作由 do_default 函数在 main.sh 中触发。整个流程可以抽象为三层:源码准备层、编译层、镜像组装层。
flowchart LR
subgraph 准备层
A1[prepare_host<br/>安装依赖工具链]
A2[fetch_from_repo<br/>拉取 U-Boot / 内核 / ATF 源码]
end
subgraph 编译层
B1[compilation.sh<br/>compile_uboot]
B2[compilation.sh<br/>compile_kernel]
B3[compilation.sh<br/>compile_atf]
end
subgraph 镜像层
C1[debootstrap.sh<br/>create_rootfs_cache]
C2[distributions.sh<br/>install_common]
C3[image-helpers.sh<br/>customize_image]
C4[debootstrap.sh<br/>create_image]
end
A1 --> A2 --> B1 & B2 & B3 --> C1 --> C2 --> C3 --> C4
准备层:general.sh 中的 prepare_host 会检查并安装交叉编译工具链(如 aarch64-linux-gnu-gcc)、debootstrap、qemu-user-static 等构建依赖。随后 fetch_from_repo 根据板卡家族配置中的 BOOTSOURCE、KERNELSOURCE、ATFSOURCE 等变量,从 GitHub 或镜像站拉取对应源码到 external/cache/sources/ 目录。
编译层:compilation.sh 负责实际的交叉编译。它会读取家族配置中的 BOOTBRANCH、KERNELBRANCH、KERNEL_USE_GCC 等变量,自动匹配合适的工具链版本,然后依次编译 ARM Trusted Firmware(部分平台)、U-Boot、内核及设备树,最终输出 .deb 格式的软件包到 output/debs/。
镜像层:debootstrap.sh 通过 debootstrap 或解压预置缓存创建基础根文件系统;distributions.sh 注入 OrangePi 特有的 fstab、modules、initramfs 及发行版定制脚本;image-helpers.sh 提供了 mount_chroot/umount_chroot 与 install_deb_chroot 等封装,确保在构建主机上安全地操作目标根文件系统;最后分区、写入启动扇区、打包为 .img 文件。
Sources: main.sh, compilation.sh, debootstrap.sh, general.sh
配置体系的层级覆盖
OrangePi 构建系统的一大设计亮点是分层配置。理解这一机制能帮助你在正确的位置进行修改,而不是直接改动脚本源码。
userpatches/config-xxx.conf # 用户自定义:最高优先级,覆盖所有默认值
↓
external/config/boards/xxx.conf # 板级定义:BOARD_NAME、BOARDFAMILY、BOOTCONFIG
↓
external/config/sources/families/xxx.conf # 家族定义:内核分支、源码地址、工具链约束
↓
external/config/sources/xxx.conf # 架构默认:ARCH、KERNEL_IMAGE_TYPE 等
↓
scripts/configuration.sh # 全局默认值:ROOTPWD、TZDATA、MIRROR 等
以 robopi1 为例,它的完整配置链条如下:
boards/robopi1.conf声明BOARDFAMILY="rockchip-rk3588"和KERNEL_TARGET="legacy,current,develop"configuration.sh检测到LINUXFAMILY后,加载sources/families/rockchip-rk3588.conf- 家族配置根据用户选择的
BRANCH(如current)切换具体的KERNELBRANCH='branch:orange-pi-6.1-rk35xx'和LINUXCONFIG="linux-rockchip-rk3588-current-robopi1" - 最终,
main.sh在执行编译前通过call_extension_method触发扩展钩子,允许userpatches或外部扩展在最后一刻修改变量
因此,如果你只是想修改默认 root 密码或切换下载镜像,编辑 userpatches/config-example.conf 即可;如果你需要为 robopi1 增加一个内核 patch,则应放在 userpatches/kernel/ 目录下,构建系统会自动应用。
Sources: configuration.sh, rockchip-rk3588.conf
目录结构与关键文件
以下是初学者需要关注的核心目录结构:
orangepi-build/
├── build.sh # 主入口:权限检查、配置加载、分发到 main.sh
├── scripts/
│ ├── main.sh # 交互菜单与主流程编排
│ ├── configuration.sh # 默认参数、镜像源、配置分层加载
│ ├── compilation.sh # ATF / U-Boot / 内核 编译逻辑
│ ├── debootstrap.sh # Rootfs 创建、分区、镜像打包
│ ├── distributions.sh # 发行版特定安装与通用系统调整
│ ├── image-helpers.sh # Chroot 挂载、deb 安装、镜像辅助
│ ├── general.sh # 工具函数:fetch、display_alert、prepare_host
│ └── extensions.sh # 扩展管理器:钩子注册与调用
├── external/
│ ├── config/
│ │ ├── boards/ # 板级定义(*.conf)
│ │ ├── sources/families/ # SoC 家族定义
│ │ ├── kernel/ # 内核配置文件(*.config)
│ │ ├── templates/ # 用户配置模板
│ │ └── cli/ / desktop/ # 软件包清单与桌面环境定义
│ ├── cache/ # 源码、工具链、rootfs 缓存
│ └── packages/ # BSP 包、补丁、自定义 deb
└── userpatches/ # 用户自定义配置与补丁(构建时自动生成)
缓存机制值得特别注意:external/cache/rootfs/ 会保存已构建的根文件系统缓存,下次构建相同 RELEASE 与桌面配置时可直接解压复用,大幅缩短时间;external/cache/sources/ 则保存 Git 仓库,避免重复克隆。若遇到奇怪的错误或需要彻底清理,可删除 output/ 与 external/cache/ 下的对应目录,或在配置中将 CLEAN_LEVEL 设为 "debs,oldcache"。
Sources: build.sh, configuration.sh, extensions.sh
输出产物位置
构建完成后,你可以在以下路径找到产物:
| 产物类型 | 典型路径 | 说明 |
|---|---|---|
| 系统镜像 | output/images/ |
.img 或已压缩的镜像文件,可直接烧录 |
| 软件包 | output/debs/ |
U-Boot、内核、BSP 等 .deb 包 |
| 编译日志 | output/debug/ |
compilation.log、install.log 等排错依据 |
| 根文件系统缓存 | external/cache/rootfs/ |
.lz4 格式的缓存,用于加速后续构建 |
若选择了 kernel 或 u-boot 单独构建,产物仅以 .deb 形式存在于 output/debs/ 中,不会生成 .img 镜像。
Sources: main.sh, debootstrap.sh
下一步
至此,你已经掌握了 OrangePi 镜像构建的基本概念、交互流程与配置层级。如果你希望深入理解脚本如何编排编译顺序、如何添加自定义扩展,请继续阅读 构建流程与脚本编排;如果你需要修改内核配置或添加设备树支持,请参阅 板卡配置与内核编译。对于机器人系统的固件集成策略,可参考 机器人系统固件集成策略。