4.1. Setting Up the Development Environment and Compilation Instructions

4.1.1. Overview

This chapter aims to guide users in quickly setting up a development environment suitable for X5 BSP (Board Support Package), understanding the source code organization, and mastering the correct procedures for compiling system images. After completing this chapter, users will be able to achieve the following objectives:

  1. Set up the development environment:

    • Understand software and hardware requirements for development, including operating system versions, necessary toolchains, compilers, and related dependency libraries.

    • Configure the cross-compilation environment.

  2. Source code directory structure:

    • Detailed explanation of the X5 BSP source code directories, including functionality and file organization of each module.

    • Clarify the role of each module in system development, and how to locate and modify relevant code.

  3. System image compilation:

    • Step-by-step compilation process from source code to generating a complete system image.

    • Covering preparation of configuration files, usage of build scripts, common issues during image generation and their solutions.

    • Detailed explanation of the main files generated by X5 BSP compilation and their functions.

By reading this chapter, users will gain the ability to set up a development environment and successfully compile X5 system images, laying the foundation for subsequent system and application development and optimization.

4.1.2. Setting Up the Development Environment

X5 BSP adopts a cross-compilation development approach, meaning that program development and compilation targeting ARM-based embedded devices are performed on an x86 architecture host. The cross-compilation environment uses a specific toolchain to compile source code into binary programs suitable for running on target hardware. The resulting binaries must be transferred to the development board via serial port, network, USB, or other means for execution and debugging.

image-20240314211441326

4.1.2.1. Host Machine Specifications

To efficiently and smoothly complete system image compilation, the host machine should meet the following requirements:

Hardware / Operating System Requirements
CPU I3 or higher with 8+ cores, or equivalent E3/E5 processors; more cores reduce kernel compilation time
Memory 16GB or above
Operating System Ubuntu 20.04 is recommended; other versions may require adjustments to packages and environment configuration.

4.1.2.2. Configuring the Host Build Environment

To ensure smooth setup of the X5 BSP development environment, follow the detailed steps below for host environment configuration, including installation of required packages and Python dependencies.

Installing Python Packages (Required)

Depending on the Ubuntu version, install the following Python packages to support BSP development:

  • Ubuntu 18.04

pip3 install cryptography -i https://pypi.tuna.tsinghua.edu.cn/simple
  • Ubuntu 20.04 and Ubuntu 22.04

pip3 install cryptography==40.0.2 -i https://pypi.tuna.tsinghua.edu.cn/simple

Manual Installation of Ubuntu Packages (Optional Method)

If not using the automatic script, you can manually install required packages. Below are common development tools and dependencies.

Install based on your Ubuntu version:

  • 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

Notes

4.1.2.3. Installing the Cross-Compilation Toolchain (GCC)

X5 BSP uses the arm-gnu-toolchain-11.3.rel1 cross-compilation toolchain. This toolchain is provided as a compressed file in the BSP’s toolchain directory, named: arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz

Before compiling the BSP, extract the toolchain and place it in the directory specified by the board configuration file. Board configuration files are typically located in the device/horizon/x5 directory, offering multiple configurations. The example below uses board_x5_soc_debug_config.mk.

Default Toolchain Path

Using device/horizon/x5/board_x5_soc_debug_config.mk as an example, the toolchain path is typically set to /opt/, for example:

export TOOLCHAIN_PATH=/opt/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu

Extracting and Installing the Toolchain

Choose one of the following methods based on user permissions to extract the toolchain to the designated directory:

  1. Users with sudo privileges If you have access to the /opt/ directory, run:

    sudo tar -xvf toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/
    
  2. Users without sudo privileges If you cannot access /opt/, extract the toolchain to a user directory, e.g., /home/hobot/:

    tar -xvf toolchain/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C /home/hobot/
    

    Then update the TOOLCHAIN_PATH variable in the board configuration file:

    export TOOLCHAIN_PATH=/home/hobot/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu
    

Notes

  • Directory Permissions If the extraction path requires sudo, ensure you have the appropriate permissions. Otherwise, choose a directory where you have write access.

  • Updating Configuration Files After changing the toolchain installation path, always update the TOOLCHAIN_PATH variable in the board configuration file to ensure the correct path is used during compilation.

4.1.3. BSP Source Code Directory Structure

4.1.3.1. Top-Level Directory Structure

Below is the top-level directory structure of the X5 BSP source code:

.
├── bd.sh -> build/xbuild.sh      # Symbolic link to main build script; users can execute this to start compilation
├── device                        # Board configuration directory, containing hardware configuration files, build options, and partition tables
├── build                         # Build system code directory, containing build scripts and tools
├── miniboot                      # Minimal boot firmware source directory, including BL2, DDR, BL3x, etc.
├── uboot                         # U-Boot source code
├── kernel                        # Linux Kernel source code
├── system                        # Root filesystem, including initramfs, buildroot, and Ubuntu root filesystem
├── hbre                          # Source code for user-space programs such as multimedia libraries and on-board tools
├── app                           # Application and test program source code
├── toolchain                     # Cross-compilation toolchain
├── prebuilts                     # Pre-built modules, such as closed-source libbpu and bpu-hw_io drivers
├── README.md -> build/README.md  # Built-in English xbuild usage guide, providing basic environment setup and command usage
└── out                           # Output directory for compiled system images

4.1.3.2. bd.sh File

bd.sh is the main entry script for BSP compilation. It simplifies user operations by linking to build/xbuild.sh. Users can simply execute bd.sh to start the full BSP compilation. Its functionality is identical to build/xbuild.sh.

4.1.3.3. device Directory

The device directory contains board-level hardware configurations, system partition tables, and configurable options for the BL2 stage:

device/
└── horizon
    └── x5
        ├── board_cfg                                  # Contains basic hardware configurations
           └── soc
               ├── bl2_cfg
                  ├── bl2_cfg.json                   # BL2 stage configuration, e.g., DDR parameters, watchdog settings
                  ├── bl2_rot_prikey.pem              # Private key used in BL2 stage
                  └── user_root.key                   # User root key
               ├── boot_its
                  ├── x5-common.its                   # ITS configuration for system image
                  ├── x5-enc-common.its               # ITS configuration for encrypted mode
                  ├── x5-enc-recovery.its             # ITS configuration for recovery mode
                  └── x5-recovery.its                # ITS configuration for recovery mode
               ├── initramfs_configs
                  └── recovery_ramfs_recipe_extern    # Initramfs configuration
               ├── key_files                           # Key files used for image encryption
                  ├── fde-origin-128.key
                  ├── fit_enc_iv.bin
                  └── fit_enc_key.bin
               ├── sub_config                          # Sub-partition tables; multiple tables can be combined in one JSON and referenced in the main table
                  ├── miniboot.json
                  └── miniboot_nand.json
               ├── x5-soc-debug-ab-gpt.json            # AB partition table used in Debug mode
               ├── x5-soc-debug-gpt.json               # GPT partition table for Debug mode
               ├── x5-soc-debug-nand-ab-ota-gpt.json    # NAND and OTA partition configuration
               ├── x5-soc-debug-nand-gpt.json          # NAND partition configuration
               ├── x5-soc-recovery-ota.json            # OTA partition table for recovery mode
               ├── x5-soc-release-gpt.json            # Partition table for Release mode, using single partition to reduce image size
               ├── x5-soc-ubuntu-debug-gpt.json        # GPT partition table for Ubuntu Debug mode
               └── x5-soc-ubuntu-release-gpt.json      # GPT partition table for Ubuntu Release mode
        ├── board_x5_evb_debug_config.mk               # Board config for X5 EVB, enabling Kernel Debug options
        ├── board_x5_evb_jammy_debug_config.mk         # Board config for X5 EVB with Jammy as main storage, enabling Kernel Debug
        ├── board_x5_evb_jammy_release_config.mk       # Board config for X5 EVB with Jammy, disabling Kernel Debug
        ├── board_x5_evb_nand_debug_config.mk          # Board config for X5 EVB with NAND Flash, enabling Kernel Debug
        ├── board_x5_evb_nand_release_config.mk        # Board config for X5 EVB with NAND Flash, disabling Kernel Debug
        ├── board_x5_evb_release_config.mk             # Board config for X5 EVB Release mode, disabling Kernel Debug
        ├── board_x5_soc_debug_config.mk               # Board config for X5 SoC Debug mode, enabling Kernel Debug
        ├── board_x5_soc_release_config.mk             # Board config for X5 SoC Release mode, disabling Kernel Debug
        └── dr_release_version.mk                      # System image version definition

4.1.3.4. build Directory

The build directory is used to compile and package various BSP modules:

build/
├── common                # Common Makefiles and configurations; mk_hbre.sh uses source code from this directory when compiling hbre
├── Dockerfile            # Used to generate BSP build Docker container, used with start_docker.sh
├── hbre_config           # hbre compilation configurations, defines which hbre modules to compile
├── install_host_deps.sh  # Installs host dependency packages
├── mk_app.sh             # Compiles app directory and generates app.img
├── mk_hbre.sh            # Compiles hbre and prebuilts/hbre, generates hbre.img
├── mk_boot.sh            # Compiles kernel and prebuilts/kernel, generates boot.img
├── mk_miniboot.sh        # Packages miniboot, generates miniboot.img
├── mk_system.sh          # Packages system root filesystem, generates system.img
├── mk_uboot.sh           # Compiles U-Boot, generates uboot.img
├── mk_appsdk.sh          # Packages APPSDK (cross-compilation SDK for applications), generates platform-appsdk-<ver>.deb + bundle .tar.gz
├── mk_fde.sh             # Example script for compiling encrypted partitions
├── pack_uart_usb.sh      # Packages images for UART/USB flashing
├── quickcmd.sh           # Provides common shortcut commands
├── README.md             # Built-in English xbuild usage guide, provides basic environment setup and command usage
├── start_docker.sh       # Used to generate and start Docker container for BSP compilation
├── tools                 # Tools for compilation, packaging, and signing
├── utils_funcs.sh        # Common utility functions
└── xbuild.sh             # Main build entry point

4.1.3.5. out Directory

The out directory stores all generated compilation files, including intermediate build artifacts, logs, system images, partition images, and configuration files:

out/
├── build                             # Out-of-source build output for U-Boot, Kernel, hbre, app, etc.
│   ├── app
│   ├── hbre
│   ├── hbre_deps
│   ├── kernel                        # Kernel output directory, specified by HR_KERNEL_OUTPUT_DIR in board config
│   └── uboot                         # U-Boot output directory, specified by HR_UBOOT_OUTPUT_DIR in board config
├── build_log
│   └── build_20250110_101641.log     # Compilation log; all output from bd.sh or xbuild.sh is saved here
├── deploy                            # Contents of each partition image; compiled data is packaged into *.img files in product directory
│   ├── app
│   ├── appsdk                        # APPSDK packaging artifacts (platform-appsdk-<ver>.deb + bundle .tar.gz + install/verify scripts), generated by ./bd.sh appsdk
│   ├── boot
│   ├── hbre
│   ├── miniboot
│   ├── ota_packages
│   ├── system
│   ├── uboot
│   └── vbmeta
└── product                           # Final compiled outputs: full system image and partition images; flashing tools use files from this directory
    ├── app.img                       # app partition image
    ├── board_config.mk               # For easy viewing of board configuration; not used during upgrade
    ├── boot.img                      # Linux Kernel partition image
    ├── emmc_disk.img                 # Complete system image, including miniboot_all.img, uboot.img, ubootenv.img, boot.img, and all filesystem images
                                      # emmc_disk.img can be used for fastboot, DFU, or TFTP upgrade
    ├── emmc_disk.simg                # Sparse format full image, smaller than emmc_disk.img; DFU upgrade does not currently support this format
    ├── gpt_back.img                  # Not packed into disk.img, currently unused, temporary build file
    ├── gpt.img                       # Partition table stored at eMMC address 0
    ├── hbre.img                      # hbre partition image
    ├── mbr.img                       # Partition info parsed by ROMCODE, records positions of BL2, DDR parameters, BL3x, etc.
    ├── miniboot.img                  # Contains BL2, BL31, optee, DDR parameters
    ├── miniboot_all.img              # miniboot_all.img = gpt.img + mbr.img + miniboot.img + misc.img
                                      # Can be directly written to eMMC or NAND Flash address 0
    ├── misc.img                      # Empty; runtime records upgrade info and current active partition in AB mode
    ├── ota_packages                  # Images used for OTA upgrade, generated via bd.sh otapackage
    ├── system.img                    # Root filesystem image
    ├── uart_usb                      # Firmware used by flashing tools when upgrading blank chips
    ├── ubootenv.img                  # Initially empty; stores U-Boot environment variables after saveenv command
    ├── uboot.img                     # U-Boot partition image
    ├── vbmeta.img                    # When secure boot is enabled, stores integrity verification info for Boot and System images
    └── x5-soc-release-gpt.json       # Partition table info; flashing tools read this file to get partition list

4.1.4. Compilation Process and Commands

4.1.4.1. Compilation Process

All build scripts for the BSP project are located in the build directory, with xbuild.sh as the main entry point. For user convenience, a symbolic link bd.sh pointing to xbuild.sh is provided in the BSP root directory. Users can directly execute bd.sh from the root to start compilation. Below is a diagram of the complete compilation and firmware packaging process:

image-20240314211537326

Functionality of Generated Images:

  • miniboot.img: Low-level bootloader responsible for DDR initialization and loading U-Boot.

  • uboot.img: Bootloader that performs necessary initialization before launching the Linux Kernel.

  • boot.img: Contains the Linux Kernel image, device tree, and a minimal initramfs-based root filesystem.

  • system.img: Root filesystem image containing glibc libraries, Shell, utilities, and scripts.

  • hbre.img: Multimedia library image containing multimedia-related libraries.

  • app.img: Application image, defaults to test programs; users can replace with functional applications.

  • emmc_disk.img: Complete system firmware containing all above images; suitable for fastboot, DFU, TFTP upgrades.

  • uart_usb: Firmware dedicated for flashing tools.

4.1.4.2. Using the lunch Command to Select Board Configuration

Running ./bd.sh lunch allows the system to select a board configuration from files named board_***_config.mk under the device directory for BSP compilation (exact list may vary by BSP version). For detailed information on board configuration files, refer to Adding New Board Configuration.

Configuration Flow

After running ./bd.sh lunch, a symbolic link board_config.mk pointing to the selected board configuration file is created under the device directory (check current selection via ls -lha device/). This link persists until distclean is executed, so configuration usually needs to be done only once.

Usage Methods

  1. Initial Configuration If ./bd.sh is run without prior selection, the system prompts to choose a configuration.

  2. Switching Board Configurations To change the configuration, manually run:

    ./bd.sh lunch
    
  3. Directly Specifying Configuration For script convenience, lunch supports direct selection by number or filename:

    ./bd.sh lunch 5
    ./bd.sh lunch board_x5_evb_release_config.mk
    

Examples

  • First-time execution of ./bd.sh lunch displays configuration options:

    $ ./bd.sh lunch
    You're building on #1 SMP PREEMPT_DYNAMIC Mon Apr 21 17:08:54 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
    

    Enter the corresponding number to complete configuration (e.g., entering 5 selects horizon/x5/board_x5_evb_release_config.mk).

    Upon successful selection, a symbolic link board_config.mk is created in the device directory pointing to the selected configuration, eliminating the need for re-selection unless switching or cleaning the build environment.

  • Direct configuration via number or filename:

    $ ./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. Compilation Commands

The build system supports two compilation modes: Full Command Mode and Shortcut Command Mode.

Full Command Mode

  • Supports all build commands and options.

  • No need to configure environment variables; can be run from any terminal.

  • Execute in the BSP root directory:

./bd.sh [all | function] [module] [clean | distclean]

Command help:

==================================================================================
   \  //   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
==================================================================================

Shortcut Command Mode

Tip: If developing long-term in the same directory, add source <BSP workspace>/build/quickcmd.sh to ~/.bashrc or ~/.profile so shortcuts are available upon login.

Run source build/quickcmd.sh to bind common commands to short aliases for faster operations.

Shortcut Features:

  • Simplified commands with Tab completion.

  • Supports quick directory navigation (e.g., cr to jump to BSP root).

  • All shortcuts work from any directory (e.g., run b from $HOME to compile BSP source).

  • One terminal supports only one sourced source tree.

  • Only supports the listed command set.

Shortcut help:

==================================================================================
   \  //   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:
``````bash
        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
==================================================================================

Note: After entering the shortcut command mode, the terminal will display something similar to the following:

<xbuild>(base) sxq@DESKTOP-6VORLA0:~/projects/sdk_x5_1$

The quickcmd.sh script modifies the PS1 prompt by adding the <xbuild> string, indicating that you have entered the shortcut command mode. If you no longer need this mode, simply open a new terminal.

4.1.4.4. Full Build

Execute ./bd.sh without any parameters to compile all modules:

./bd.sh

After a successful build, all image files will be generated by default in the output directory (out).

4.1.4.5. Modular Build

Use the bd.sh script to build individual modules; the generated image files will be output to the out directory.

./bd.sh [all | function] [module] [clean | distclean]
Support functions :
        help lunch miniboot uboot factory boot hbre system app pack appsdk

The options miniboot, uboot, boot, hbre, system, and app are used to generate corresponding firmware images. All compilation logs are displayed during the process, making it convenient to review logs when building a single module. Typically, each partition with actual content has a corresponding function option for image generation. Users can debug a single module independently and update only that module on the target board. All modular build functions support the clean and distclean commands. For example:

# Build uboot only
./bd.sh uboot
# Clean uboot only
./bd.sh uboot clean
# Distclean uboot only
./bd.sh uboot distclean

After building all modules, or after updating one or several module images, you can execute the pack command to repack the full image emmc_disk.img:

./bd.sh pack

The hbre and app builds support finer-grained compilation, allowing convenient debugging of smaller submodules. For example, to build only liblog under the hbre directory:

# Build liblog only
./bd.sh hbre liblog

# Build liblog and repack hbre.img
./bd.sh hbre liblog pack

# If you don't remember the module name, run the following command to enter interactive mode and select the module by number
./bd.sh hbre module

The factory command generates firmware used by flashing tools, which is stored in out/uart_usb. This command requires that miniboot and uboot have already been built. The flashing tool downloads firmware via UART into the board’s memory and runs it to enter U-Boot, then allows downloading the full image via USB to flash it to the board’s eMMC or NAND Flash.

./bd.sh factory

The appsdk command packages the APPSDK (Application SDK, a cross-compilation SDK for applications), producing a self-contained SDK package for application developers. APPSDK includes a cross-toolchain copy, sysroot (sourced from out/deploy/system runtime libraries + hbre artifacts + toolchain libc), hbre libraries and headers, environment setup script, etc. Application developers can compile X5 applications without the full project source code. The version number is automatically extracted from the BSP major version HR_V_VER and lower-cased (e.g. _V1.1.2v1.1.2), no manual specification needed.

# Package APPSDK (requires system unpack + hbre build to be completed first)
./bd.sh appsdk

After a successful build, the artifacts are in the out/deploy/appsdk/images/ directory:

out/deploy/appsdk/images$ ls platform-appsdk-*
platform-appsdk-v1.1.2.deb         # SDK body (deb format)
platform-appsdk-v1.1.2.tar.gz      # Bundle (contains deb + install.sh + relocate-paths.sh + test-sdk.sh)

After application developers get the tar.gz bundle, they extract it, run install.sh to install, and source environment-setup to activate the environment for compilation. For complete usage instructions on APPSDK installation, verification, and compiling applications, refer to Root Filesystem Adaptation Guide - Using APPSDK for Application Development.

Note: APPSDK packaging does not depend on the Buildroot host sysroot; after modifying hbre, just run ./bd.sh hbre && ./bd.sh appsdk to repackage. It is not part of the ./bd.sh full build flow (./bd.sh all does not automatically package APPSDK) and must be run separately.

Note: Users can also directly enter the build directory and run the corresponding ./mk_*.sh build scripts to compile individual modules. For example:

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 Firmware

Overview

X5 chips can be categorized into Secure chips and Non-secure chips based on whether a Hash key has been programmed. For more information about Hash keys, refer to X5 eFuse Introduction

  • Secure chip: Has a pre-programmed D-Robotics Hash key; does not support customer-defined keys.

  • Non-secure chip: Contains no Hash key; customers may program their own custom keys. See Customer-defined Hash Key for details.

Secure chips require Secure firmware, while Non-secure chips require Non-secure firmware. By default, the X5 SDK compiles Secure firmware. The following section describes how to compile Non-secure firmware.

Build

Before building Non-secure firmware, modify the current board configuration file to enable the HR_ENABLE_CUSTOMER_KEY option as follows:

export HR_ENABLE_CUSTOMER_KEY="yes"

The build process for Non-secure firmware is the same as for Secure firmware. Refer to Full Build and Modular Build for instructions.

Boot log information

Non-secure firmware does not verify firmware during boot. The boot log appears as follows:

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 Functions

clean

Removes generated images and intermediate files, but does not remove BSP project configuration files such as board configuration file links, or .config files for U-Boot and Linux Kernel. Supports both full project and per-module clean.

# Full project clean
./bd.sh clean

# Per-module clean
./bd.sh uboot clean
./bd.sh boot clean
./bd.sh appsdk clean      # Clean SDK artifacts under out/deploy/appsdk/images/ (platform-appsdk-*.deb, *.tar.*, install.sh, relocate-paths.sh, test-sdk.sh)

distclean

Removes generated images and intermediate files, and clears all configuration files, including board configuration file links, .config files for U-Boot and Linux Kernel, etc. Supports both full project and per-module distclean.

# Full project distclean, aiming to restore the BSP to its pre-build state
./bd.sh distclean
# Per-module distclean
./bd.sh uboot distclean
./bd.sh boot distclean
./bd.sh appsdk distclean  # Equivalent to appsdk clean, cleans SDK artifacts under out/deploy/appsdk/images/

Help Information

$ ./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
... (repeated from earlier sections, omitted) ...

4.1.5. Building BSP Using Docker

To improve compatibility and flexibility of the build system, BSP supports building within Docker. Docker provides an isolated containerized environment without requiring complex dependencies to be installed directly on the host machine, enabling fast and consistent cross-platform builds.

4.1.5.1. Install Docker

Step 1: Install Docker

  • Run the following commands to install Docker:

sudo apt update
sudo apt install -y docker.io
  • Start the Docker service:

sudo systemctl start docker
  • Enable Docker to start automatically at system boot:

sudo systemctl enable docker

Step 2: Add User to Docker Group

  • Ensure your user account is part of the docker group. Run the following command:

sudo usermod -aG docker $USER

Note: $USER refers to your current login username. Make sure to replace it with the correct username if necessary.

Step 3: Configure Docker Proxy Settings

Docker Hub may be restricted in certain regions, preventing direct access. It is recommended to use a domestic Docker mirror accelerator.

Edit the daemon.json file (usually located at /etc/docker/ or ~/.docker/; create it manually if it doesn’t exist). Below is an example daemon.json configuration with multiple mirror sources:

{
    "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 will attempt to pull images in the order listed in registry-mirrors. If the first mirror fails, it will automatically try the next. It is recommended to place the most stable mirror at the top based on your network conditions.

After saving the daemon.json file, run the following commands to reload and restart Docker for the changes to take effect:

sudo systemctl daemon-reload
sudo systemctl restart docker

Step 4: Verify Docker Installation

  • Run the following command to check if Docker is installed correctly:

docker --version
  • Use the following command to run a simple container to verify Docker is working properly:

docker run hello-world

4.1.5.2. Build Container Image

cd build
docker build -t dr_xbuild/ubuntu20.04:1.0 .
  • docker build: Command used to build Docker images.

  • -t dr_xbuild/ubuntu20.04:1.0: The -t flag specifies the tag; the following argument is the image name and version. In this example, the image name is dr_xbuild/ubuntu20.04, and the version is 1.0.

  • .: This is the build context path. Docker needs a context when building an image, which contains all files and information required for the build. Here, . refers to the current directory—the directory where the Dockerfile is located. Docker will look for the Dockerfile in this path and use it to build the image.

4.1.5.3. Start Container

Enter the BSP root directory and run the following command to start the Docker container and enter it:

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. Remove Container

# Stop container
docker stop dr_xbuild
# Forcefully remove a running Docker container
docker rm -f dr_xbuild

Note: dr_xbuild is the default container name. If you used ./build/start_docker.sh -n to change the container name, replace dr_xbuild in the above commands with the actual container name.

4.1.5.5. start_docker.sh Usage Guide

This script helps you start a Docker container with specified configurations. If the container is not already running, it starts a new one; otherwise, it attaches to the existing container.

Usage

./build/start_docker.sh [-u username] [-p password] [-i image] [-w workdir] [-n container_name] [-h]

Options

  • -u username: Specify a new username. Default is the current host username.

  • -p password: Specify a password for the new user. Default is the predefined password (123456).

  • -i image: Specify Docker image version. Default is the predefined image (dr_xbuild/ubuntu20.04:1.0).

  • -w workdir: Specify the working directory inside the container. Default is the current directory.

  • -n container_name: Specify the container name. Default is dr_xbuild.

  • -h: Show help message.

Example

Running the script without any parameters will start the Docker container using default settings: the current host username, predefined password (123456), and the current script directory as the working directory.

./build/start_docker.sh

4.1.6. Use Podman to compile BSP

4.1.6.1. Podman Introduction

Podman is an open source container management tool that can be used as a replacement for Docker. It can be used to create and maintain containers, and has the characteristics of running without daemons and root privileges. Podman provides flexible container management capabilities and supports running containers as the root user or an unprivileged user. Through the libpod library, Podman can efficiently manage the entire container ecosystem, covering key components such as Pods, containers, container images, and container volumes. Podman focuses on providing comprehensive OCI container image management functions, including pulling, marking and other operations, making it easy to maintain and modify container images.

4.1.6.2. Podman installation

The process of installing Podman on Ubuntu is as follows:

  1. Update the system:

    sudo apt update && sudo apt upgrade -y
    
  2. Add Podman repository:

    . /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. Install Podman:

    sudo apt install podman -y
    
  4. Verify installation:

    podman --version
    

Finally you can see:

hobot@hobot-ThinkPad-T14-Gen-1:~/project/sdk_x5_cs1.0/build$ podman --version
podman version 3.4.4

At this point you can simply test Podman to verify whether Podman is working properly:

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/

You can see that hello-world has run successfully.

4.1.6.3. Configure Podman basic environment

The key files that need to be configured for Podman are as follows. If these files do not exist, you can use sudo vi to create them in sequence:

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 is Podman’s signature policy file, which is used to define how to verify the signature of the image. Podman uses this file to decide whether to trust the image pulled from the remote repository. An example is as follows:

{
    "default": [
        {
            "type": "insecureAcceptAnything"
        }
    ],
    "transports":
        {
            "docker-daemon":
                {
                    "": [{"type":"insecureAcceptAnything"}]
                }
        }
}

A brief description is as follows:

  • default: -The default signature policy is configured to insecureAcceptAnything, which means that Podman will accept any image without signature verification. This is common in development environments, but is not recommended in production environments as it reduces security.

  • transports:

    • Configure the signature policy of the docker-daemon transmission method, which is also set to insecureAcceptAnything. This is typically used for images pulled by the local Docker daemon.

registries.conf

registries.conf is Podman’s image repository configuration file, which is used to define how Podman resolves image names and which repositories to pull images from. Examples are as follows:

unqualified-search-registries = ["docker.io", "quay.io"]

Brief description:

  • unqualified-search-registries:

    • Defines the list of repositories that Podman will search when parsing incompletely qualified image names. Two warehouses are configured here: docker.io and quay.io. This means that when running podman pull ubuntu:20.04, Podman will first try to pull the image from docker.io, and if that fails, then try to pull it from quay.io.

registries.conf.d/999-mirror.conf

registries.conf.d is a directory used to store additional image warehouse configuration files. These files will be merged into the main registries.conf file. 999-mirror.conf is a specific configuration file, usually used to configure the mirror accelerator. The example is as follows:

[[registry]]
prefix = "docker.io"
location = "docker.m.daocloud.io"

Brief description:

  • [[registry]]:

    • Defines a specific mirror warehouse configuration.

  • prefix:

    • Specifies that the image name is prefixed with docker.io.

  • location:

    • The actual image warehouse address is specified as docker.m.daocloud.io, which is the public image accelerator address of DaoCloud (other public image accelerator addresses or private accelerator addresses can also be used).

4.1.6.4. Use Podman to build container images

Enter the build/ directory in the X5 BSP source code package and you can see the existing Dockerfile file. Execute the following command in the BSP source code directory to build the container image:

cd build
sudo podman build -t dr_xbuild/ubuntu20.04:1.0 .
  • podman build: Command used to build Podman image.

  • -t dr_xbuild/ubuntu20.04:1.0: -t represents the label, and the following parameters are the name and version number of the image. In this example, the image name is dr_xbuild/ubuntu20.04 and the version number is 1.0.

  • .: This is the path to build context. When building a Podman image, a context is required, which contains all the files and information required for the build. In this command, . represents the current directory, which is the directory where the current Dockerfile is located. Podman will look for the Dockerfile file in this path and use it to build the image.

Note: In order to avoid some permission errors, sudo is used to execute commands throughout the build process.

After the build is completed, you can use the following command to view the generated image:

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. Start the Podman container

Execute the start_podman.sh script to start the Podman container and enter 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

After the execution is completed, you will automatically enter the directory in the container. At this time, you can execute ./bd.sh to compile the X5 image.

4.1.6.6. Delete Podman container

# Stop the container
sudo podman stop dr_xbuild
# Force deletion of a running Podman container even if the container is running
sudo podman rm -f dr_xbuild

Note: dr_xbuild is the default container name. If you use ./build/start_podman.sh -n to modify the container name, you need to replace dr_xbuild in the above command with the actual container name.

4.1.6.7. start_podman.sh Instructions for use

This script helps you start a Podman container with a specified configuration. If the container is not already running, it will start a new container; otherwise, it will drop into an existing container. How to use:

./build/start_podman.sh [-u user] [-p password] [-i image] [-w working directory] [-n container name] [-h]

Options:

  • -u user: Specify a new username. Defaults to the current host username.

  • -p password: Specify the password of the new user. Defaults to the predefined password (123456).

  • -i image: Specify the Podman image version. Defaults to the predefined Podman image ( dr_xbuild/ubuntu20.04:1.0 ).

  • -w working directory: Specify the working directory of the container. Defaults to the current directory.

  • -n container name: Specify the container name, the default is dr_xbuild.

  • -h: Display help message.

Example:

If you run the script without any arguments, it will start the Podman container with the default configuration, including using the current host username, a predefined password ( 123456 ), and the current directory where the script is running as the working directory.

./build/start_podman.sh

4.1.6.8. Podman FAQ

Missing cache file

The error log is as follows:

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

Just create /root/.ccache manually:

sudo mkdir /root/.ccache