4.1. 搭建开发环境及编译说明
4.1.1. 概述
本章旨在指导用户快速搭建适用于 X5 BSP( Board Support Package)开发的环境,了解源码的组织方式,以及掌握如何正确编译系统镜像。通过本章的学习,用户将能够完成以下目标:
搭建开发环境:
了解开发所需的软件和硬件环境要求,包括操作系统版本、必要的工具链、编译器和相关依赖库的安装。
配置交叉编译环境。
源码目录结构:
详细解析 X5 BSP 的源码目录,包括每个模块的功能和文件组织方式。
明确各个模块在系统开发中的作用,以及如何定位和修改相关代码。
系统镜像的编译:
从源码到生成完整系统镜像的编译流程解析。
包括配置文件的准备、编译脚本的使用方法、镜像生成的常见问题及其解决方案。
详细说明 X5 BSP 编译生成的主要文件的作用和功能。
通过阅读本章内容,用户将具备搭建开发环境并顺利完成 X5 系统镜像编译的能力,为后续的系统、应用功能开发和优化奠定基础。
4.1.2. 搭建开发环境
X5 BSP 采用 交叉编译 的开发方式,即在 x86 架构的主机上完成针对 ARM 嵌入式架构设备的程序开发和编译。交叉编译环境通过特定的工具链,将源码编译生成适合目标硬件运行的二进制程序。编译生成的目标程序需要通过串口、网络、 USB 等方式传输到开发板上运行和调试。

4.1.2.1. 开发主机规格要求
为了能够高效、顺利的完成系统镜像的编译,建议选择的主机满足以下要求:
| 硬件 / 操作系统 | 要求 |
|---|---|
| CPU | 8 核以上的 I3 以上或者同级别 E3/E5 的处理器 , 核心数越多编译内核时越快,可以缩短编译时间 |
| 内存 | 16GB 或以上级别 |
| 操作系统 | 推荐使用 Ubuntu 20.04 操作系统,若使用其它系统版本,可能需要对软件包和环境配置做相应调整。 |
4.1.2.2. 配置开发主机编译环境
为确保 X5 BSP 的开发环境搭建顺利,以下是详细的主机环境配置步骤,包括必要的软件包和 Python 依赖的安装方法。
安装 Ubuntu 软件包(推荐方式)
通过以下脚本可以自动检查开发主机的操作系统版本,并根据不同的版本安装编译所需的软件包。目前支持的操作系统版本包括 Ubuntu 18.04、20.04 和 22.04。
执行以下命令:
sudo build/install_host_deps.sh
该脚本将自动安装开发环境所需的依赖包,无需用户手动配置。
安装 Python 软件包(必须)
根据 Ubuntu 版本的不同,需要安装以下 Python 包来支持 BSP 开发:
Ubuntu 18.04
pip3 install cryptography -i https://pypi.tuna.tsinghua.edu.cn/simple
Ubuntu 20.04 和 Ubuntu 22.04
pip3 install cryptography==40.0.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
手动安装 Ubuntu 软件包(可选方式)
如果用户不使用自动脚本,可以根据需求手动安装所需的软件包。以下是常见的开发工具和依赖:
根据 Ubuntu 版本的不同,请执行以下命令安装依赖工具:
Ubuntu 18.04
sudo apt update
sudo apt-get install -y \
tzdata tree bc hashdeep kmod file wget curl cpio unzip rsync liblz4-tool jq \
build-essential make cmake bison flex ccache zlib1g-dev libssl-dev \
libncurses-dev u-boot-tools device-tree-compiler cryptsetup-bin \
android-sdk-libsparse-utils e2fsprogs dosfstools mtools mtd-utils
sudo apt-get install -y python3 python3-pip
pip3 install cryptography -i https://pypi.tuna.tsinghua.edu.cn/simple
Ubuntu 20.04
sudo apt update
sudo apt-get install -y \
tzdata tree bc hashdeep kmod file wget curl cpio unzip rsync liblz4-tool jq \
build-essential make cmake bison flex ccache zlib1g-dev libssl-dev \
libncurses-dev u-boot-tools device-tree-compiler cryptsetup-bin \
android-sdk-libsparse-utils e2fsprogs dosfstools mtools mtd-utils
sudo apt-get install -y python3 python3-pip
pip3 install cryptography==40.0.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
Ubuntu 22.04
sudo apt update
sudo apt-get install -y \
tzdata tree bc hashdeep kmod file wget curl cpio unzip rsync liblz4-tool jq \
build-essential make cmake bison flex ccache zlib1g-dev libssl-dev \
libncurses-dev u-boot-tools device-tree-compiler cryptsetup-bin \
android-sdk-libsparse-utils dosfstools mtools mtd-utils
sudo apt-get install -y python3-pip
pip3 install cryptography==42.0.2 -i https://pypi.tuna.tsinghua.edu.cn/simple
注意事项
若下载 Python 包时网络较慢,可更换国内镜像源,例如以上命令中指定的清华源(https://pypi.tuna.tsinghua.edu.cn/simple)。
4.1.2.3. 安装交叉编译工具链( GCC)
X5 BSP 使用 arm-gnu-toolchain-11.3.rel1 版本的交叉编译工具链。该工具链以压缩包形式存放在 BSP 的 toolchain 目录中,文件名为:
arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
在开始编译 BSP 之前,需要解压工具链并将其放置到板级配置文件中指定的目录。板级配置文件通常位于 device/horizon/x5 目录下,提供多种配置供选择。以下以 board_x5_soc_debug_config.mk 配置为例说明具体操作。
默认工具链路径
以 device/horizon/x5/board_x5_soc_debug_config.mk 板级配置为例,通常将工具链路径设置为 /opt/ 目录,例如:
export TOOLCHAIN_PATH=/opt/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu
工具链解压与安装
根据用户权限,可以选择以下两种方式将工具链解压到指定目录:
有
sudo权限的用户 如果您可以访问/opt/目录,执行以下命令解压工具链:sudo tar -xvf toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
无
sudo权限的用户 如果您无法访问/opt/目录,可将工具链解压到用户目录下,例如/home/hobot/:tar -xvf toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /home/hobot/
然后在板级配置文件中更新
TOOLCHAIN_PATH变量:export TOOLCHAIN_PATH=/home/hobot/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu
注意事项
目录权限 如果解压路径需要
sudo权限,请确保具备相应的操作权限。否则,选择用户拥有写权限的目录进行安装。更新配置文件 每次更改工具链安装路径后,请及时修改板级配置文件中的
TOOLCHAIN_PATH变量,确保编译过程中工具链路径正确。
4.1.3. BSP 源码目录结构
4.1.3.1. 顶层目录结构
以下是 X5 BSP 的源码的顶层目录结构:
.
├── bd.sh -> build/xbuild.sh # 链接到编译主程序,用户可直接执行此文件启动编译
├── device # 板级配置目录,包含硬件配置文件,可设置编译选项和分区表
├── build # 编译系统代码目录,包含编译脚本及工具
├── miniboot # 最小启动固件原始资料目录,包含 BL2 、 DDR、 BL3x 等文件
├── uboot # U-Boot 源码
├── kernel # Linux Kernel 源码
├── system # 根文件系统,包括 initramfs 、 buildroot 和 Ubuntu 根文件系统
├── hbre # 多媒体库、板端运行工具等用户态程序的源码
├── app # 应用程序及测试程序源码
├── toolchain # 交叉编译工具链
├── prebuilts # 预编译模块,如闭源的 libbpu 和 bpu-hw_io 驱动等
├── README.md -> build/README.md # 源码中自带的英文版 xbuild 使用说明,提供基础的环境搭建和命令使用说明
└── out # 系统编译的目标输出目录
system 目录下的各种根文件系统制作、修改方法请查阅 根文件系统适配指南 。
4.1.3.2. bd.sh 文件
bd.sh 是 BSP 项目的主编译脚本入口,其功能是通过链接到 build/xbuild.sh,简化用户的编译操作。用户只需执行 bd.sh 即可启动 BSP 的整体编译。它的功能和作用与 build/xbuild.sh 完全一致。
4.1.3.3. device 目录
device 目录包含板级硬件配置、系统分区表、 BL2 阶段的可配选项:
device/
└── horizon
└── x5
├── board_cfg # 本目录下包含硬件的基础配置
│ └── soc
│ ├── bl2_cfg
│ │ ├── bl2_cfg.json # BL2 阶段配置文件,例如: DDR 参数、设置启动阶段是否开启看门狗等
│ │ ├── bl2_rot_prikey.pem # BL2 阶段使用的私钥
│ │ └── user_root.key # 用户根密钥
│ ├── boot_its
│ │ ├── x5-common.its # 系统镜像的ITS配置文件
│ │ ├── x5-enc-common.its # 加密模式的ITS配置文件
│ │ ├── x5-enc-recovery.its # 恢复模式下的ITS配置文件
│ │ └── x5-recovery.its # 恢复模式的ITS配置文件
│ ├── initramfs_configs
│ │ └── recovery_ramfs_recipe_extern # 初始化文件系统配置
│ ├── key_files # 镜像加密等功能需要使用到的秘钥文件
│ │ ├── fde-origin-128.key
│ │ ├── fit_enc_iv.bin
│ │ └── fit_enc_key.bin
│ ├── sub_config # 分区表子集,可以把多个分区表合并在一个 json 中,然后在主分区表中引用
│ │ ├── miniboot.json
│ │ └── miniboot_nand.json
│ ├── x5-soc-debug-ab-gpt.json # Debug 模式下使用的 AB 分区表
│ ├── x5-soc-debug-gpt.json # Debug 模式的 GPT 分区表
│ ├── x5-soc-debug-nand-ab-ota-gpt.json # NAND 分区表和 OTA 配置
│ ├── x5-soc-debug-nand-gpt.json # NAND 分区表配置
│ ├── x5-soc-recovery-ota.json # 恢复模式的 OTA 分区表
│ ├── x5-soc-release-gpt.json # Release 模式下使用的分区表,使用单分区模式减小系统镜像大小
│ ├── x5-soc-ubuntu-debug-gpt.json # Ubuntu Debug 模式的 GPT 分区表
│ └── x5-soc-ubuntu-release-gpt.json # Ubuntu 发布模式的 GPT 分区表
├── board_x5_evb_debug_config.mk # X5 EVB 的板级配置文件, Linux Kernel 配置会使能 Debug 选项等
├── board_x5_evb_jammy_debug_config.mk # X5 EVB 使用 Jammy 作为主存储器的板级配置文件,Linux Kernel 配置使能 Debug 选项等
├── board_x5_evb_jammy_release_config.mk # X5 EVB 使用 Jammy 作为主存储器的板级配置文件,Linux Kernel 配置关闭 Debug 选项等
├── board_x5_evb_nand_debug_config.mk # X5 EVB 使用 Nand Flash 作为主存储器的板级配置文件,Linux Kernel 配置使能 Debug 选项等
├── board_x5_evb_nand_release_config.mk # X5 EVB 使用 NAND Flash 作为主存储器的板级配置文件,Linux Kernel 配置关闭 Debug 选项等
├── board_x5_evb_release_config.mk # X5 EVB Release 模式的板级配置文件,Linux Kernel 配置关闭 Debug 选项等
├── board_x5_soc_debug_config.mk # X5 SoC Debug 模式的板级配置,Linux Kernel 配置使能 Debug 选项等
├── board_x5_soc_release_config.mk # X5 SoC 发布模式的板级配置,Linux Kernel 配置关闭 Debug 选项等
└── dr_release_version.mk # 系统镜像版本信息定义
4.1.3.4. build 目录
build 目录用于编译和打包 BSP 各个功能模块:
build/
├── common # 通用 Makefile 和配置项, mk_hbre.sh 在编译 hbre 目录下的源码时会用到当面目录下的源码
├── Dockerfile # 用于生成 BSP 编译的 Docker 容器,配合 start_docker.sh 使用
├── hbre_config # hbre 编译配置项,该配置文件中定义了是否编译对应的 hbre 模块
├── install_host_deps.sh # 安装主机依赖的软件包
├── mk_app.sh # 编译 app 目录并生成 app.img
├── mk_hbre.sh # 编译 hbre 和 prebuilts/hbre ,生成 hbre.img
├── mk_boot.sh # 编译 kernel 和 prebuilts/kernel,生成 boot.img
├── mk_miniboot.sh # 打包 miniboot,生成 miniboot.img
├── mk_system.sh # 打包 system 根文件系统,生成 system.img
├── mk_uboot.sh # 编译 U-Boot,生成 uboot.img
├── mk_fde.sh # 编译加密分区的示例脚本
├── pack_uart_usb.sh # 打包用于 UART/USB 刷机的镜像
├── quickcmd.sh # 提供常用快捷命令
├── README.md # 源码中自带的英文版 xbuild 使用说明,提供基础的环境搭建和命令使用说明
├── start_docker.sh # 如果需要在 docker 容器中编译 BSP,使用此脚本生成和启动容器
├── tools # 编译、打包、签名工具软件
├── utils_funcs.sh # 通用函数封装
└── xbuild.sh # 主编译入口
4.1.3.5. out 目录
out 目录保存编译生成的所有文件,包括编译的中间产物、编译日志、所有的系统镜像、分区镜像和配置文件:
out/
├── build # U-Boot、 Kernel、 hbre、 app 等源码外编译的输出目录
│ ├── app
│ ├── hbre
│ ├── hbre_deps
│ ├── kernel # Kernel 的目标文件生成目录,通过板级配置中的 HR_KERNEL_OUTPUT_DIR 指定
│ └── uboot # U-Boot 的目标文件生成目录,通过板级配置中的 HR_UBOOT_OUTPUT_DIR 指定
├── build_log
│ └── build_20250110_101641.log # 编译日志,通过 bd.sh 或者 xbuild.sh 启动的编译,所有输出日志会同步保存在此
├── deploy # 各分区镜像的内容,编译系统会把此目录下的数据打包成 product 目录下的 *.img 镜像
│ ├── app
│ ├── boot
│ ├── hbre
│ ├── miniboot
│ ├── ota_packages
│ ├── system
│ ├── uboot
│ └── vbmeta
└── product # 编译后的最终产物,完整系统镜像和各分区镜像文件,刷机工具使用此目录下文件进行刷机
├── app.img # app 分区镜像
├── board_config.mk # 方便查看板级配置信息,对升级过程无用
├── boot.img # Linux Kernel 分区镜像
├── emmc_disk.img # 完整系统镜像,包括 miniboot_all.img、 uboot.img、 ubootenv.img、 boot.img 和所有文件系统分区镜像
# emmc_disk.img 可用于 fastboot、 DFU 或 TFTP 升级
├── emmc_disk.simg # sparse 格式的完整镜像 , 比 emmc_disk.img 占用空间更小。 dfu 升级目前不支持解析该镜像
├── gpt_back.img # 没有被打包进 disk.img,暂时没有什么作用,编译的临时文件
├── gpt.img # 存放在 eMMC 0 地址处的分区表信息
├── hbre.img # hbre 分区镜像
├── mbr.img # ROMCODE 能解析的分区信息,记录 BL2 、 DDR 参数、 BL3x 等固件在镜像中的存放位置
├── miniboot.img # miniboot.img 包含 BL2 、 BL31 、 optee、 DDR 参数
├── miniboot_all.img # miniboot_all.img = gpt.img + mbr.img + miniboot.img + misc.img
# miniboot_all.img 可以直接写到 eMMC 或者 Nand Flash 的 0 地址
├── misc.img # 无数据,在运行时该分区记录升级信息,并在 AB 分区模式下保存当前使用的分区编号
├── ota_packages # OTA 升级需要使用到的镜像,通过 bd.sh otapackage 命令生成
├── system.img # 根文件系统镜像
├── uart_usb # 此目录下固件,在刷机工具对空片升级时需要使用
├── ubootenv.img # 默认无数据,在 U-Boot 下执行 saveenv 后会保存 U-Boot 环境变量到该分区
├── uboot.img # U-Boot 分区镜像
├── vbmeta.img # 开启安全启动时,本镜像存放 Boot 和 system 分区镜像的校验信息
└── x5-soc-release-gpt.json # 分区表信息,在使用刷机工具刷机时,会读取该文件来获取分区表列表
product 目录镜像的使用请查阅 快速入门 - 系统镜像烧写 。
4.1.4. 编译过程及命令
4.1.4.1. 编译过程
BSP 项目的所有编译脚本都存放在 build 目录下,xbuild.sh 是主编译入口程序。为了方便用户操作, BSP 根目录下提供了软链接 bd.sh,指向 xbuild.sh,用户可在根目录下直接执行 bd.sh 开始编译。以下为完整的编译与固件打包流程示意图:

生成的各镜像功能说明:
miniboot.img:底层启动引导程序,负责 DDR 初始化、加载和引导 U-Boot。uboot.img:引导加载程序,用于在启动 Linux Kernel 之前完成必要的初始化。boot.img:包含 Linux Kernel 镜像、设备树和一个基于 initramfs 格式的最小根文件系统。system.img:根文件系统镜像,包含 glibc 运行库、 Shell、工具软件及脚本。hbre.img:多媒体库镜像,包含多媒体相关的库文件。app.img:应用程序镜像,默认存放测试程序,用户可根据需求替换为实际功能程序。emmc_disk.img:完整系统固件,包含上述所有镜像,适用于 fastboot、 DFU、 TFTP 升级。uart_usb:刷机工具专用固件。
4.1.4.2. lunch 命令选择板级配置
执行 ./bd.sh lunch 命令时,系统会根据 device 目录下以 board_***_config.mk 命名的文件选择板级配置,并用于编译 BSP(具体示例显示内容根据 BSP 版本可能有所不同)。有关板级配置文件的详细说明,请参阅 新增板级配置 。
配置流程
执行 ./bd.sh lunch 命令后,系统会在 device 目录下生成一个指向所选板级配置文件的软链接 board_config.mk (可以通过 ls -lha device/ 命令查看当前选择的配置)。在未执行 distclean 清理之前,该软链接文件会一直存在,因此通常只需配置一次即可。
使用方法
首次配置 如果用户直接运行
./bd.sh,而未选择过板级配置文件,系统会提示选择配置文件。切换板级配置 若需更换板级配置文件,用户可主动执行以下命令重新选择:
./bd.sh lunch
直接指定配置文件 为方便脚本调用,
lunch命令支持通过数字或配置文件名直接选择:./bd.sh lunch 5 ./bd.sh lunch board_x5_evb_release_config.mk
示例
首次运行
./bd.sh lunch时,系统会显示配置选项$ ./bd.sh lunch You're building on #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 Lunch menu... pick a combo: 0. horizon/x5/board_x5_evb_debug_config.mk 1. horizon/x5/board_x5_evb_jammy_debug_config.mk 2. horizon/x5/board_x5_evb_jammy_release_config.mk 3. horizon/x5/board_x5_evb_nand_debug_config.mk 4. horizon/x5/board_x5_evb_nand_release_config.mk 5. horizon/x5/board_x5_evb_release_config.mk 6. horizon/x5/board_x5_soc_debug_config.mk 7. horizon/x5/board_x5_soc_release_config.mk Which would you like? [0] : 5 You are selected board config: horizon/x5/board_x5_evb_release_config.mk输入对应的数字即可完成配置,例如以上示例中输入 5 后选择使用
horizon/x5/board_x5_evb_release_config.mk。成功选择后,系统会在
device目录下创建软链接board_config.mk,指向所选配置文件,无需重复选择配置文件,除非主动切换或清理编译环境。通过指定数字和板级配置文件名直接完成配置
$ ./bd.sh lunch 5 You're building on #140~20.04.1-Ubuntu SMP Wed Dec 18 21:35:34 UTC 2024 You are selected board config: horizon/x5/board_x5_evb_release_config.mk $ ./bd.sh lunch board_x5_evb_release_config.mk You're building on #140~20.04.1-Ubuntu SMP Wed Dec 18 21:35:34 UTC 2024 You are selected board config: horizon/x5/board_x5_evb_release_config.mk
4.1.4.3. 编译命令
本构建系统支持两种编译模式:完整命令模式 和 快捷命令模式。
完整命令模式
支持所有编译命令和选项。
无需配置环境变量,在任何终端下均可运行。
在 BSP 根目录下执行:
./bd.sh [all | function] [module] [clean | distclean]
命令帮助信息如下:
==================================================================================
\ // Welcome to the D-Robotics xbuild system!
\// Working directory: /home/hobot/1-work/6-x5/02-dev-x5
//\
// \
==================================================================================
Available commands for bd.sh:
./bd.sh [all | function] [module] [clean | distclean]
Support functions :
help all lunch miniboot uboot factory boot hbre system app pack otapackage
Usage example:
./bd.sh all
./bd.sh miniboot [clean | distclean]
./bd.sh uboot [clean | distclean]
./bd.sh boot [clean | distclean]
./bd.sh boot module [clean] -- eg: ./bd.sh boot spi
./bd.sh system [clean | distclean]
./bd.sh hbre [help | all ] [modules] [pack | clean | distclean]
./bd.sh hbre module [pack | clean | distclean] -- eg: ./bd.sh hbre liblog
./bd.sh app [help | all ] [modules] [pack | clean | distclean]
./bd.sh app module [pack | clean | distclean]
./bd.sh clean
./bd.sh distclean
./bd.sh uboot menuconfig
./bd.sh boot menuconfig
./bd.sh help
==================================================================================
快捷命令模式
提示: 如果长时间在同一个目录下开发,可以把 source <BSP workspace>/build/quickcmd.sh 命令添加到 ~/.bashrc 或者 ~/.profile 中,则终端登录时即可直接使用快捷命令。
通过执行 source build/quickcmd.sh,可以将常用命令关联为简短的快捷命令,方便快速操作。
快捷命令特点:
简化命令,支持
Tab键补全。支持快捷跳转目录(如
cr跳转到 BSP 根目录)。所有快捷命令支持在任意目录下执行,例如可以在 $HOME 目录下执行 b 完成对
BSP目录下源码的编译。登录的一个终端只支持编译 source 过的那份源码。
仅支持以下罗列的命令集。
快捷命令帮助信息如下:
==================================================================================
\ // Welcome to the D-Robotics xbuild system!
\// Working directory: /home/hobot/1-work/6-x5/02-dev-x5
//\
// \
==================================================================================
Available commands for bd.sh:
help all clean distclean lunch miniboot uboot factory boot system hbre app pack
Shortcut commands for build:
b : bd.sh - default build all
ball : bd.sh all - build all
bm : bd.sh miniboot - only build miniboot
bu : bd.sh uboot - only build uboot
bf : bd.sh factory - build uart_usb image
bb : bd.sh boot - only build kernel
bs : bd.sh system - only build rootfs
bh : bd.sh hbre - build hbre
bhm : bd.sh hbre module - build hbre module, user interactive mode
ba : bd.sh app - build app
bam : bd.sh app module - build app module, user interactive mode
bp : bd.sh pack - pack all image into emmc_disk.img
Shortcut commands for changing directory:
croot - go to root directory
cr - go to root directory
cout - go to out directory
co - go to out directory
cuboot - go to uboot directory
cub - go to uboot directory
cboot - go to kernel directory
cb - go to kernel directory
cdev - go to device directory
cbuild - go to device directory
capp - go to app directory
chbre - go to hbre directory
go <regex> -- go to directory matching the specified <regex>
Shortcut commands for configuring U-Boot and the kernel defconfig
bumc : bd.sh uboot menuconfig - Edit and save uboot menuconfig
bbmc : bd.sh boot menuconfig - Edit and save kernel menuconfig
Usage example for build kernel and hbre module
bb spi : bd.sh boot spi - Compile driver under kernel
bh liblog : bd.sh hbre liblog - Compile modules under hbre
==================================================================================
注意:进入快捷命令模式后,终端会显示类似如下:
<xbuild>(base) sxq@DESKTOP-6VORLA0:~/projects/sdk_x5_1$
quickcmd.sh 脚本会修改 PS1 提示符,新增 <xbuild> 字符串,以表明当前已经进入了快捷命令模式。如果不再需要快捷命令模式,另外起一个终端即可。
4.1.4.4. 整体编译
不带任何参数的执行 ./bd.sh 命令编译所有模块:
./bd.sh
编译成功后,默认会在编译镜像输出目录( out) 目录下生成所有的镜像文件。
4.1.4.5. 模块化编译
通过 bd.sh 脚本编译单独模块,生成的镜像文件会输出到编译镜像输出目录( out)下。
./bd.sh [all | function] [module] [clean | distclean]
Support functions :
help lunch miniboot uboot factory boot hbre system app pack
miniboot uboot boot hbre system app 这些功能选项是编程生成对应的固件镜像,编译过程中输出所有编译日志,方便单模块编译时直观的查阅编译日志。一般有实际内容的分区都会有对应的功能选项来完成镜像的编译生成。用户在调试时可以单独调试一个模块的功能,编译后单独更新到板端。所有的模块化编译功能都支持 clean 和 distclean 命令,例如:
# 单独编译 uboot
./bd.sh uboot
# 单独 clean uboot
./bd.sh uboot clean
# 单独 distclean uboot
./bd.sh uboot distclean
全部模块编译后,或者仅更新了某个或者某几个模块镜像,又想要生成完整镜像时,可以执行 pack 命令重新打包 emmc_disk.img:
./bd.sh pack
hbre 和 app 编译还支持更细粒度的编译,可以方便单独调试一个更小模块的功能,例如要单独编译 hbre 目录下的 liblog:
# 单独编译 liblog
./bd.sh hbre liblog
# 编译 liblog,并且重新打包 hbre.img
./bd.sh hbre liblog pack
# 如果不记得模块名,可以执行以下命令进入用户交互模式,通过输入数字选择模块
./bd.sh hbre module
factory 命令用来生成刷机工具需要用到的固件,在 out/uart_usb 中存放,它的执行需要先完成 miniboot 和 uboot 的模块编译。刷机工具通过串口下载固件到板端内存中运行进入到 U-Boot 中,然后可以通过 usb 下载完整的镜像烧写到板端的 eMMC 或者 NAND Flash 中。
./bd.sh factory
注:用户还可以直接进入到 build 目录下,单独执行 ./mk_*.sh 相对应模块的编译脚本直接编译,例如:
cd build
./mk_boot.sh
./mk_boot.sh clean
./mk_uboot.sh
./mk_uboot.sh clean
./mk_uboot.sh distclean
./mk_hbre.sh
./mk_hbre.sh liblog
./mk_hbre.sh camsys/libvpf
4.1.4.6. Non-secure 固件
概述
根据是否烧录 Hash key,可将 X5 芯片分为 Secure 芯片 和 Non-secure 芯片,有关 Hash key 的介绍可参考X5 eFuse 介绍
Secure 芯片: 已烧录地瓜 Hash key,不支持客户自定义 Key
Non-secure 芯片:不包含任何 Hash key,客户可烧录自定义 Key,可以参考客户自定义Hash key
Secure 芯片需烧录 Secure 固件,相反的 Non-secure 芯片需烧录 Non-secure 固件,X5 SDK 默认编译均是 Secure 固件。以下介绍如何编译 Non-secure 固件。
编译
Non-secure 固件在执行编译操作之前,需修改当前使用的板级配置文件,开启选项 HR_ENABLE_CUSTOMER_KEY,如下所示
export HR_ENABLE_CUSTOMER_KEY="yes"
启动 log 信息
Non-secure 固件在启动过程不验证固件,其 log 如下:
NOTICE: Welcome to Horizon X5 ASIC BOOTROM - V4.1
NOTICE: OTP config:
NOTICE: otp exist: true
NOTICE: test region size: 304
NOTICE: secure region size: 120
NOTICE: none secure region size: 56
NOTICE: Enable MMU
NOTICE: Booting Trusted Firmware
NOTICE: BL1: v2.8(release):
NOTICE: BL1: Built : 17:42:12, Oct 19 2023
NOTICE: Enter eMMC Mode......
NOTICE: USER AREA.
NOTICE: eMMC clk_rate = CLK_12M
NOTICE: eMMC emmc_data_width == WIDTH_DATA_1
NOTICE: eMMC emmc_cfg.emmc_clk_latch == CLK_RISING
NOTICE: Enter media_source_select process(1).
NOTICE: BL1: BL2 memory layout address = 0x1fe9f000
NOTICE: BL1: Booting BL2
NOTICE: OTP config:
NOTICE: otp exist: true
NOTICE: test region size: 304
NOTICE: secure region size: 120
NOTICE: none secure region size: 56
NOTICE: BL2: v2.8(release):v1.0.8-77-g72e4fe066
NOTICE: BL2: Built : 20:14:26, Jun 11 2025
NOTICE: Enter eMMC Mode......
NOTICE: eMMC partition: User
NOTICE: Enter media_source_select process(1).
NOTICE: BL2 config file
NOTICE: ab slot is : 0
NOTICE: fip index:0
NOTICE: start to load bl2 cfg image
NOTICE: BL2 CFG ADDR:0x1ff00000, MAGIC:0x474643324c424248
NOTICE: bypass update efuse
NOTICE: calibration_offset 12
NOTICE: trimming_value 9
NOTICE: ADC read channel[2]: 295mv
NOTICE: ddr info:[LPDDR4]-[DUAL_RANK]-[DIE: 1 GB]-[ECC OFF]-[DVFS ON]-[4266M]
NOTICE: JTAG ENABLE
NOTICE: disable wdt
NOTICE: start to load ddr image
NOTICE: run ddr Fw
NOTICE: matching profile: profile_2 from aon config
NOTICE: type: LP4, freq: 4266, ecc: 0(0x7f), rank: 2, dvfs: 1, die_dencity: 1 GB, version: 10.04
NOTICE: ddr cost: 147151 us, ddr size: 4 GB, manuid: 0x13
NOTICE: ddr ready
NOTICE: start to load bl31 image
NOTICE: start to load optee image
NOTICE: start to load uboot image
NOTICE: BL1: Booting BL31
NOTICE: multicore_init: sec_entrypoint = 0x2000010c
NOTICE: BL31: v2.8(release):v1.0.8-77-g72e4fe066
NOTICE: BL31: Built : 20:12:37, Jun 11 2025
NOTICE: plat_setup_psci_ops: sec_entrypoint = 0x2000010c
4.1.4.7. 清理功能
clean
删除生成镜像和中间文件,不会清除 BSP 工程配置文件,比如板级配置文件链接、 U-Boot、 Linux Kernel 的 .config 文件 不会被清除,支持完整工程的 clean 和单独模块的 clean。
# 完整工程 clean
./bd.sh clean
# 单独模块 clean
./bd.sh uboot clean
./bd.sh boot clean
distclean
删除生成镜像和中间文件,清除所有配置文件,包括板级配置文件链接、 U-Boot、 Linux Kernel 的 .config 文件等,支持完整工程的 distclean 和单独模块的 distclean。
# 完整工程 distclean,力求把 BSP 还原到未编译前的状态
./bd.sh distclean
# 单独模块 distclean
./bd.sh uboot distclean
./bd.sh boot distclean
帮助信息
$ ./bd.sh help
Available commands for bd.sh:
./bd.sh [all | function] [module] [clean | distclean]
Support functions :
help lunch miniboot uboot factory boot hbre system app pack
... ( 和之前的章节内容重复,省略 ) ...
4.1.5. 使用 Docker 编译 BSP
为了提高编译系统的兼容性和灵活性, BSP 支持在 Docker 内进行构建。 Docker 提供了一个独立的容器化环境,无需直接在宿主机上安装复杂的依赖项,能够快速实现跨平台的一致性编译。
4.1.5.1. 安装 Docker
步骤 1: 安装 Docker
运行以下命令来安装 Docker:
sudo apt update
sudo apt install -y docker.io
启动 Docker 服务:
sudo systemctl start docker
将 Docker 服务设置为在系统启动时自动启动:
sudo systemctl enable docker
步骤 2: 将用户添加到 Docker 用户组
确认你的用户帐户属于 docker 组。运行以下命令:
sudo usermod -aG docker $USER
注意:这里的 $USER 是你当前登录的用户名。确保用正确的用户名替换它。
步骤 3 :配置 Docker 的代理设置
Docker Hub 在某些地区可能会受到限制,导致无法直接访问。需要使用国内的 Docker 镜像加速器。
编辑 daemon.json 文件(通常位于 /etc/docker/ 或 ~/.docker/ 目录下,如果文件不存在,可以手动创建一个)。以下是一个包含多个镜像源的 daemon.json 配置文件示例:
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://hub-mirror.c.163.com",
"https://registry.docker-cn.com",
"https://docker.ustc.edu.cn",
"https://nrbewqda.mirror.aliyuncs.com",
"https://dmmxhzvq.mirror.aliyuncs.com",
"https://docker.1panel.live",
"https://docker.1ms.run",
"https://docker.chenby.cn",
"https://docker.m.daocloud.io"
]
}
Docker 会按照上述 registry-mirrors 列表中的顺序依次尝试拉取镜像。如果第一个镜像源失败,会自动尝试下一个。根据实际情况,建议将最稳定的镜像源放在前面。
保存 daemon.json 文件后,运行以下命令重启 Docker 服务以使配置生效:
sudo systemctl daemon-reload
sudo systemctl restart docker
步骤 4: 验证 Docker 安装
运行以下命令检查 Docker 是否正确安装:
docker --version
使用以下命令运行一个简单的容器以验证 Docker 是否正常工作:
docker run hello-world
4.1.5.2. 构建容器镜像
cd build
docker build -t dr_xbuild/ubuntu20.04:1.0 .
docker build: 用于构建 Docker 镜像的命令。-t dr_xbuild/ubuntu20.04:1.0:-t表示标签,后面的参数是镜像的名称和版本号。在这个例子中,镜像名称为dr_xbuild/ubuntu20.04,版本号为1.0。.: 这是构建上下文的路径。 Docker 镜像构建时需要一个上下文,这个上下文包含了构建所需的所有文件和信息。在这个命令中,.表示当前目录,即当前 Dockerfile 所在的目录。 Docker 会在这个路径下查找 Dockerfile 文件,并使用它来构建镜像。
4.1.5.3. 启动容器
进入到 BSP 的根目录执行以下命令,会启动 Docker 容器,并且进入到 Docker 中。
hobot@ubuntu:~/1-work/6-x5/01-x5-gerrit$ ./build/start_docker.sh
c6a097021fd6d1adb2b8036204ecc510e37043ee5aff468dc90ebefb6e3da1c6
Starting Docker container dr_xbuild ...
Setting user and password ...
Installing cross-compilation toolchain ...
hobot@c6a097021fd6:~/1-work/6-x5/01-x5-gerrit$
4.1.5.4. 删除容器
# 停止容器
docker stop dr_xbuild
# 强制删除一个正在运行的 Docker 容器,即使容器正在运行
docker rm -f dr_xbuild
注意: dr_xbuild 是默认容器名称,如果使用了 ./build/start_docker.sh -n 修改过容器名称,需要将上述命令中的 dr_xbuild 替换为实际的容器名称。
4.1.5.5. start_docker.sh 使用说明
本脚本帮助您以指定的配置启动 Docker 容器。如果容器尚未运行,它将启动一个新容器;否则,它将进入现有容器。
使用方法
./build/start_docker.sh [-u 用户 ] [-p 密码 ] [-i 镜像 ] [-w 工作目录 ] [-n 容器名称 ] [-h]
选项
-u 用户:指定新的用户名。默认为当前主机用户名。-p 密码:指定新用户的密码。默认为预定义密码( 123456 )。-i 镜像:指定 Docker 镜像版本。默认为预定义 Docker 镜像( dr_xbuild/ubuntu20.04:1.0 )。-w 工作目录:指定容器的工作目录。默认为当前目录。-n 容器名称:指定容器名称,默认为dr_xbuild。-h:显示帮助消息。
示例
如果不带任何参数运行脚本,它将使用默认配置启动 Docker 容器,包括使用当前主机用户名、预定义密码( 123456 )和脚本运行的当前目录作为工作目录。
./build/start_docker.sh
4.1.6. 使用 Podman 编译 BSP
4.1.6.1. Podman 简介
Podman 是一个开源的容器管理工具,可作为 Docker 的替代品,它可以用来创建和维护容器,具有无守护进程和无根权限运行的特点。 Podman 提供了灵活的容器管理功能,支持以 root 用户或非特权用户身份运行容器。通过 libpod 库,Podman 能够高效地管理整个容器生态系统,涵盖 Pod、容器、容器镜像以及容器卷等关键组件。Podman 专注于提供全面的 OCI 容器镜像管理功能,包括拉取、标记等操作,可以方便地维护和修改容器镜像。
4.1.6.2. Podman 安装
在 Ubuntu 上安装 Podman 的过程如下:
更新系统:
sudo apt update && sudo apt upgrade -y
添加 Podman 仓库:
. /etc/os-release echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list curl -L "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" | sudo apt-key add -
安装 Podman:
sudo apt install podman -y
验证安装:
podman --version
最终可以看到:
hobot@hobot-ThinkPad-T14-Gen-1:~/project/sdk_x5_cs1.0/build$ podman --version
podman version 3.4.4
此时可以简单测试下 Podman 以验证 Podman 是否正常工作:
hobot@hobot-ThinkPad-T14-Gen-1:~/project/sdk_x5_cs1.0/build$ podman run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
可以看到 hello-world 已经成功运行。
4.1.6.3. 配置 Podman 基础环境
需要配置 Podman 的关键文件如下,如果没有这些文件可以使用 sudo vi 依次创建:
hobot@hobot-ThinkPad-T14-Gen-1:/etc/containers$ tree
.
├── policy.json
├── registries.conf
└── registries.conf.d
└── 999-mirror.conf
1 directory, 3 files
policy.json
policy.json 是 Podman 的签名策略文件,用于定义如何验证镜像的签名。Podman 使用这个文件来决定是否信任从远程仓库拉取的镜像,示例如下:
{
"default": [
{
"type": "insecureAcceptAnything"
}
],
"transports":
{
"docker-daemon":
{
"": [{"type":"insecureAcceptAnything"}]
}
}
}
简要说明如下:
default:
配置了默认的签名策略为 insecureAcceptAnything,这意味着 Podman 会接受任何镜像,不进行签名验证。这在开发环境中很常见,但在生产环境中不推荐,因为它降低了安全性。
transports:
配置了 docker-daemon 传输方式的签名策略,同样设置为 insecureAcceptAnything。这通常用于本地 Docker 守护进程拉取的镜像。
registries.conf
registries.conf 是 Podman 的镜像仓库配置文件,用于定义 Podman 如何解析镜像名称和从哪些仓库拉取镜像,示例如下:
unqualified-search-registries = ["docker.io", "quay.io"]
简要说明:
unqualified-search-registries:
定义了 Podman 在解析未完全限定的镜像名称时,会搜索的仓库列表。这里配置了两个仓库:docker.io 和 quay.io。这意味着当运行 podman pull ubuntu:20.04 时,Podman 会首先尝试从 docker.io 拉取镜像,如果失败,再尝试从 quay.io 拉取。
registries.conf.d/999-mirror.conf
registries.conf.d 是一个目录,用于存放额外的镜像仓库配置文件。这些文件会被合并到主 registries.conf 文件中。
999-mirror.conf 是一个具体的配置文件,通常用于配置镜像加速器,示例如下:
[[registry]]
prefix = "docker.io"
location = "docker.m.daocloud.io"
简要说明:
[[registry]]:
定义了一个具体的镜像仓库配置。
prefix:
指定了镜像名称的前缀为
docker.io。
location:
指定了实际的镜像仓库地址为
docker.m.daocloud.io,这是 DaoCloud 的公开镜像加速器地址(也可以使用其他的公开镜像加速器地址或者私有加速器地址)。
4.1.6.4. 使用 Podman 构建容器镜像
进入到 X5 BSP 源码包中的 build/ 目录下,可以看到已有的 Dockerfile 文件,在 BSP 源码目录下执行下面命令构建容器镜像:
cd build
sudo podman build -t dr_xbuild/ubuntu20.04:1.0 .
podman build: 用于构建 Podman 镜像的命令。-t dr_xbuild/ubuntu20.04:1.0:-t表示标签,后面的参数是镜像的名称和版本号。在这个例子中,镜像名称为dr_xbuild/ubuntu20.04,版本号为 1.0。.: 这是构建上下文的路径。 Podman 镜像构建时需要一个上下文,这个上下文包含了构建所需的所有文件和信息。在这个命令中,.表示当前目录,即当前 Dockerfile 所在的目录。 Podman 会在这个路径下查找 Dockerfile 文件,并使用它来构建镜像。
注意: 为避免一些权限报错,构建全程都使用 sudo 来执行命令。
构建完成后可以使用下面命令查看生成的镜像:
hobot@hobot-ThinkPad-T14-Gen-1:~/project/sdk_x5_cs1.0/build$ sudo podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/dr_xbuild/ubuntu20.04 1.0 e61c819842c6 18 minutes ago 603 MB
4.1.6.5. 启动 Podman 容器
执行 start_podman.sh 脚本启动 Podman 容器,并且进入到 Podman 中。
hobot@hobot-ThinkPad-T14-Gen-1:~/project/sdk_x5_cs1.0$ sudo ./build/start_podman.sh
Using container image: dr_xbuild/ubuntu20.04:1.0
Using container name: dr_xbuild
Using project directory: /home/hobot/project/sdk_x5_cs1.0
Using container workdir: /project
Starting a new container dr_xbuild...
f023213d8cce778fef4df273a1497ee60a788d0f24b99e3221d797bc2148277c
Starting podman container dr_xbuild ...
Setting user and password ...
Installing cross-compilation toolchain ...
root@f023213d8cce:/project# ls
README.md adsp app bd.sh build device hbre kernel miniboot out prebuilts system toolchain uboot
执行完毕后即可自动进入到容器中的目录 ,此时即可执行 ./bd.sh 进行 X5 镜像的编译。
4.1.6.6. 删除 Podman 容器
# 停止容器
sudo podman stop dr_xbuild
# 强制删除一个正在运行的 Podman 容器,即使容器正在运行
sudo podman rm -f dr_xbuild
注意: dr_xbuild 是默认容器名称,如果使用了 ./build/start_podman.sh -n 修改过容器名称,需要将上述命令中的 dr_xbuild 替换为实际的容器名称。
4.1.6.7. start_podman.sh 使用说明
本脚本帮助您以指定的配置启动 Podman 容器。如果容器尚未运行,它将启动一个新容器;否则,它将进入现有容器。 使用方法:
./build/start_podman.sh [-u 用户 ] [-p 密码 ] [-i 镜像 ] [-w 工作目录 ] [-n 容器名称 ] [-h]
选项:
-u 用户:指定新的用户名。默认为当前主机用户名。
-p 密码:指定新用户的密码。默认为预定义密码( 123456 )。
-i 镜像:指定 Podman 镜像版本。默认为预定义 Podman 镜像( dr_xbuild/ubuntu20.04:1.0 )。
-w 工作目录:指定容器的工作目录。默认为当前目录。
-n 容器名称:指定容器名称,默认为 dr_xbuild。
-h:显示帮助消息。
示例:
如果不带任何参数运行脚本,它将使用默认配置启动 Podman 容器,包括使用当前主机用户名、预定义密码( 123456 )和脚本运行的当前目录作为工作目录。
./build/start_podman.sh
4.1.6.8. Podman 常见问题
构建容器报 alias 相关错误
报错日志如下:
sudo podman build -t dr_xbuild/ubuntu20.04:1.0 .
STEP 1/6: FROM ubuntu:20.04
Error: error creating build container: short-name "ubuntu:20.04" did not resolve to an alias and no containers-registries.conf(5) was found
需要添加容器配置文件,参考本文中 配置 podman 基础环境 章节。
缺少 cache 文件
报错日志如下:
hobot@hobot-ThinkPad-T14-Gen-1:~/project/sdk_x5_cs1.0$ sudo ./build/start_podman.sh
Using container image: dr_xbuild/ubuntu20.04:1.0
Using container name: dr_xbuild
Using project directory: /home/hobot/project/sdk_x5_cs1.0
Using container workdir: /project
Starting a new container dr_xbuild...
Error: statfs /root/.ccache: no such file or directory
手动创建 /root/.ccache 即可:
sudo mkdir /root/.ccache