4.1. 搭建开发环境编译说明

4.1.1. 概述

本章旨在指导用户快速搭建适用于 X5 BSP( Board Support Package)开发环境,了解源码组织方式,以及掌握如何正确编译系统镜像。通过本章学习,用户能够完成以下目标:

  1. 搭建开发环境

    • 了解开发软件硬件环境要求,包括操作系统版本、必要工具链、编译器相关依赖安装。

    • 配置交叉编译环境。

  2. 源码目录结构

    • 详细解析 X5 BSP 的源码目录,包括每个模块功能文件组织方式。

    • 明确各个模块系统开发作用,以及如何定位修改相关代码。

  3. 系统镜像编译

    • 源码生成完整系统镜像编译流程解析。

    • 包括配置文件准备、编译脚本使用方法、镜像生成常见问题及其解决方案。

    • 详细说明 X5 BSP 编译生成主要文件作用功能。

通过阅读本章内容,用户具备搭建开发环境顺利完成 X5 系统镜像编译能力,为后续系统、应用功能开发优化奠定基础。

4.1.2. 搭建开发环境

X5 BSP 采用 交叉编译开发方式,即在 x86 架构主机完成针对 ARM 嵌入式架构设备程序开发编译。交叉编译环境通过特定工具链,将源码编译生成适合目标硬件运行二进制程序。编译生成目标程序需要通过串口、网络、 USB 等方式传输开发板运行调试。

image-20240314211441326

4.1.2.1. 开发主机规格要求

为了能够高效、顺利完成系统镜像编译,建议选择主机满足以下要求:

硬件 / 操作系统 要求
CPU 8 核以上的 I3 以上或者级别 E3/E5 的处理器 , 核心数越编译内核时越快,可以缩短编译时间
内存 16GB 或以上级别
操作系统 推荐使用 Ubuntu 20.04 操作系统,若使用其它系统版本,可能需要软件包环境配置相应调整。

4.1.2.2. 配置开发主机编译环境

确保 X5 BSP 的开发环境搭建顺利,以下详细主机环境配置步骤,包括必要软件包和 Python 依赖安装方法。

安装 Ubuntu 软件包(推荐方式)

通过以下脚本可以自动检查开发主机操作系统版本,并根据不同版本安装编译软件包。目前支持操作系统版本包括 Ubuntu 18.0420.0422.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

注意事项

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

工具链解压安装

根据用户权限,可以选择以下两种方式工具链解压指定目录:

  1. sudo 权限用户 如果可以访问 /opt/ 目录,执行以下命令解压工具链:

    sudo tar -xvf toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
    
  2. 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                           # 系统编译的目标输出目录

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_appsdk.sh          # 打包 APPSDK,生成 platform-appsdk-<ver>.deb + 总包 .tar.gz
├── 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
│   ├── appsdk                        # APPSDK 打包产物(platform-appsdk-<ver>.deb + 总包 .tar.gz + 安装/验收脚本),由 ./bd.sh appsdk 生成
│   ├── 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       # 分区表信息,在使用刷机工具刷机时,会读取该文件来获取分区表列表

4.1.4. 编译过程命令

4.1.4.1. 编译过程

BSP 项目所有编译脚本存放build 目录下,xbuild.sh编译入口程序。为了方便用户操作, BSP 根目录提供链接 bd.sh,指向 xbuild.sh,用户根目录直接执行 bd.sh 开始编译。以下完整编译固件打包流程示意图:

image-20240314211537326

生成镜像功能说明:

  • 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 清理之前,该软链接文件一直存在,因此通常配置一次即可。

使用方法

  1. 首次配置 如果用户直接运行 ./bd.sh,而选择过板级配置文件,系统提示选择配置文件。

  2. 切换板级配置 若需更换板级配置文件,用户主动执行以下命令重新选择:

    ./bd.sh lunch
    
  3. 直接指定配置文件方便脚本调用,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 appsdk

miniboot uboot boot hbre system app 这些功能选项编程生成对应固件镜像,编译过程输出所有编译日志,方便模块编译直观查阅编译日志。一般实际内容分区对应功能选项完成镜像编译生成。用户调试可以单独调试一个模块功能,编译单独更新板端。所有模块化编译功能支持 cleandistclean 命令,例如:

# 单独编译 uboot
./bd.sh uboot
# 单独 clean uboot
./bd.sh uboot clean
# 单独 distclean uboot
./bd.sh uboot distclean

全部模块编译后,或者更新某个或者几个模块镜像,又想要生成完整镜像时,可以执行 pack 命令重新打包 emmc_disk.img

./bd.sh pack

hbreapp 编译支持细粒度编译,可以方便单独调试一个模块功能,例如单独编译 hbre 目录liblog

# 单独编译 liblog
./bd.sh hbre liblog

# 编译 liblog,并且重新打包 hbre.img
./bd.sh hbre liblog pack

# 如果不记得模块名,可以执行以下命令进入用户交互模式,通过输入数字选择模块
./bd.sh hbre module

factory 命令用来生成刷机工具需要用到固件,在 out/uart_usb存放,它执行需要完成 minibootuboot模块编译。刷机工具通过串口下载固件板端内存运行进入到 U-Boot 中,然后可以通过 usb 下载完整镜像烧写端的 eMMC 或者 NAND Flash 中。

./bd.sh factory

appsdk 命令用来打包 APPSDK(Application SDK,应用交叉编译 SDK),产出供应开发者使用包含 SDK 包。APPSDK 内含交叉工具链副本、sysroot(取自 out/deploy/system 运行库 + hbre 产物 + 工具链 libc)、hbre 库头文件、环境脚本等,应用开发者拿到无需完整项目源码即可编译 X5 应用。版本号从 BSP 大版本号自动提取,无需手动指定。

# 打包 APPSDK(需先 system unpack + hbre 构建完成)
./bd.sh appsdk

打包成功后,产物out/deploy/appsdk/images/ 目录:

out/deploy/appsdk/images$ ls platform-appsdk-*
platform-appsdk-v1.1.2.deb         # SDK 本体(deb 格式)
platform-appsdk-v1.1.2.tar.gz      # 总包(含 deb + install.sh + relocate-paths.sh + test-sdk.sh)

应用开发者拿到 tar.gz 总包后,解压执行 install.sh 安装、source environment-setup 激活环境即可编译。APPSDK 的安装、验收、编译应用完整使用说明请参阅 文件系统适配指南 - 使用 APPSDK 进行应用开发

注:APPSDK 打包依赖 Buildroot host sysroot,改了 hbre 后./bd.sh hbre && ./bd.sh appsdk 即可打包;它参与 ./bd.sh 完整编译流程(./bd.sh all 不会自动打包 APPSDK),单独执行

注:用户可以直接进入到 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"

Non-secure 固件编译操作与 Secure 固件相同,可参考 整体编译模块化编译

启动 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
./bd.sh appsdk clean      # 清 out/deploy/appsdk/images/ 下的 SDK 产物(platform-appsdk-*.deb、*.tar.*、install.sh、relocate-paths.sh、test-sdk.sh)

distclean

删除生成镜像中间文件,清除所有配置文件,包括板级配置文件链接、 U-Boot、 Linux Kernel 的 .config 文件等,支持完整工程的 distclean 和单独模块的 distclean。

# 完整工程 distclean,力求把 BSP 还原到未编译前的状态
./bd.sh distclean
# 单独模块 distclean
./bd.sh uboot distclean
./bd.sh boot distclean
./bd.sh appsdk distclean  # 等同 appsdk clean,清 out/deploy/appsdk/images/ 下的 SDK 产物

帮助信息

$ ./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 appsdk
... ( 和之前的章节内容重复,省略 ) ...

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 的过程如下:

  1. 更新系统:

    sudo apt update && sudo apt upgrade -y
    
  2. 添加 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 -
    
  3. 安装 Podman:

    sudo apt install podman -y
    
  4. 验证安装:

    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