4.4.5. 快速启动使用指南

4.4.5.1. 概述

本章旨在指导用户快速熟悉 X5 快速启动开发环境,了解源码组织方式,以及掌握快速启动系统开发。

前置条件

项目 要求
存储介质 【仅支持 eMMC 】
Rootfs 镜像 【Buildroot】

4.4.5.2. 镜像准备烧录

1) 编译文件系统:

cd system/buildroot/source
./build.sh clean
./build.sh build x5_system_quickstart_defconfig  0.0.1

编译完成system/buildroot/source/framework/output/images 目录获取用于快速启动文件系统镜像 dr-system-quickstart_0.0.1~gcc11.3.1_all.deb

$ ls  system/buildroot/source/framework/output/images
deb_make  dr-system-quickstart_0.0.1~gcc11.3.1_all.deb  rootfs.tar  rtl_bt  rtlwifi

2) 将生成文件系统镜像复制到编译目录:

生成镜像复制到 system/buildroot/prebuilt 目录下,并修改 system/buildroot/prebuilt/series_quickstart 文件文件系统镜像名称dr-system-quickstart_0.0.1~gcc11.3.1_all.deb (即保持 series_quickstart配置实际文件系统镜像一致)

dr-system-quickstart_0.0.1~gcc11.3.1_all.deb
dr-libgtest_1.14.0~gcc11.3.rel1_arm64.deb
dr-libgdcbin_1.0.0~gcc11.3.rel1_arm64.deb
dr-perf_6.1.12~gcc11.3.rel1_arm64.deb
dr-libdnn_1.24.5~gcc11.3.rel1_arm64.deb
dr-libhpatchz_3.1.1~gcc11.3.rel1_arm64.deb

3) 快速启动 BSP 镜像编译:

注意执行 ./bd.sh distclean 命令清理之前编译产物,再执行 ./bd.sh 重新编译镜像,这里选择配置项为 board_x5_evb_quickstart_debug_config.mk即使选项 5 。

$ ./bd.sh distclean
$ ./bd.sh lunch

You're building on #1 SMP PREEMPT_DYNAMIC Thu Jun  5 18:30:46 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_quickstart_debug_config.mk
      6. horizon/x5/board_x5_evb_quickstart_release_config.mk
      7. horizon/x5/board_x5_evb_release_config.mk
      8. horizon/x5/board_x5_soc_debug_config.mk
      9. horizon/x5/board_x5_soc_release_config.mk
Which would you like? [0] : 5
You are selected board config: horizon/x5/board_x5_evb_quickstart_debug_config.mk

$ ./bd.sh

说明 快速启动提供 release 和 debug 配置,debug 配置默认开启 ADB、SSH、Telnet工具满足开发调试需求。

4) 镜像烧录:

快速启动支持 Xmodem + Fastboot,Xmodem + DFU,Fastboot,DFU 方式烧录,不支持网络烧录。

4.4.5.3. 优化前后启动耗时

EVB_V2P0 BLX阶段 uboot kernel rootfs kernel 命令行启动耗时 显示第一耗时
优化 0.962s 1.612s 0.730s 4.862s 8.167s 10.345s
优化 0.956s 0.964s 0.749s 0.225s 2.931s 4.251s

说明 内核优化收益体现在 U-boot 阶段。

阶段启动时间判断标志 摘要
BLX 阶段结束标志 I/TC: Primary CPU switching to normal world boot
u-boot 结束标志 Starting kernel ...
kernel 初始化完成标志 Run /sbin/init as init process
rootfs 启动完成标志 Please press Enter to activate this console. 或 Welcome to Buildroot

统计工具:

1) grabserial

虚拟机安装 grabserial 工具,来统计上电到内核命令行耗时。

sudo apt install grabserial
sudo grabserial -v -d "/dev/ttyUSB0" -b 921600 -w 8 -p N -s 1 -e 100 -t

参数说明:

  • -v –verbose 打印运行提示信息。

  • -d "/dev/ttyUSB0" 串口设备节点。

  • -b 921600 波特率 921600,需板端一致。

  • -w 8 数据位 8。

  • -p N 校验位 N = No parity(无校验)。

  • -s 1 停止位 1。

  • -e 100 100 秒退出。

  • -t –time 每一行日志前面打印相对时间。

2) 统计上电显示第一方法

使用相机或是手机以高率(如 60 fps 或高 fps 误差小些)对准屏幕同步参考点(在线时间、板卡指示灯),连续录像,事后播放器中逐慢放,以首稳定画面出现时间相对上电时刻(板卡指示灯起)的时间计算第一显示耗时。

4.4.5.4. 集成用户软件快速启动镜像

内置用户软件:

用户准备文件复制到路径 system/buildroot/prebuilt/boot-utils-runtime-quickstart/debugsystem/buildroot/prebuilt/boot-utils-runtime-quickstart/release 下,再重新编译 system 镜像即可自定义内容打包system 分区。

添加开机启动脚本:

由于 /etc/init.d/S??* (?? 代表数字)脚本文件并行处理,在添加开机启动脚本时,需要根据实际应用场景添加条件判断

1) 显示场景:

针对要求上电显示场景 可参照 boot-utils-runtime-quickstart/release/etc/init.d/S01display

#!/bin/bash

while [ ! -d /sys/class/vps/mipi_host3 ]; do
        sleep 0.01
done

while [ ! -d /dev/dri ]; do
        sleep 0.01
done

source /etc/profile.d/environment.sh
/app/platform_samples/sample_pipeline/single_pipe_vin_isp_vse_quickstart_display/single_pipe_vin_isp_vse_quickstart_display -s 3

while [ ! -d /sys/class/vps/mipi_host3 ]; do 等待 mipi csi 链路完成加载;while [ ! -d /dev/dri ]; do 等待 drm 显示通路完成加载;由于开机脚本并行处理,因此对于显示场景两个必要条件。

2) 非显示场景:

如果程序依赖 hbreuserdata 分区添加如下条件判断

#!/bin/bash
while ! grep -q "/usr/hobot" /proc/mounts; do
        sleep 0.01
done
...
#!/bin/bash
while ! grep -q "/userdata" /proc/mounts; do
        sleep 0.01
done
...

有些用户可能使用WIFI 功能,在开机自启过程出现程序启动失败现象,因此添加如下条件判断

#!/bin/bash
while [ ! -d /sys/class/net/wlan0 ]; do
        sleep 0.01
done
...

4.4.5.5. 快速启动链路优化说明

嵌入式系统开发过程中,优化系统启动耗时常用手段:裁剪非必要功能文件、缩短启动路径、并行启动方式,来达到缩短整体启动耗时目的。

U-Boot 优化

功能概述

U-boot 是一段运行在 CPU 上电之后、操作系统内核运行之前引导加载程序。负责完成必要硬件初始化镜像加载,并控制权移交 Linux 内核。本次优化聚焦缩短启动链路,并移除目标平台上非必需组件功能,在保证可靠性前提提升启动效率。

U-Boot 快启流程图

Block Diagram

启动链路核心改动

  • 快速启动默认链路:在 hb_quickstart_board_init_r完成板级第二阶段初始化。

  • 烧录串口:烧录工具依赖串口交互, 在 U-Boot 阶段保留中断等待时间,可通过 CONFIG_QUICKSTART_ABORT_DELAY_MS 配置。

  • 环境变量策略:env_get / env_set内存生效,不写回 eMMC,减少存储写入访问。

快速启动参数配置

Block Diagram

配置 示例 作用说明
CONFIG_QUICKSTART y 使能快速启动
CONFIG_QUICKSTART_KERNEL_ADDR 0x90000000 指定 FIT 镜像内存加载地址。
CONFIG_QUICKSTART_BOARD_ID 0x0205 指定硬件板卡 ID
CONFIG_QUICKSTART_ABORT_DELAY_MS 80 U-Boot 阶段保留中断等待时间

冗余功能启动链路裁剪

1) 冗余功能裁剪

裁剪类别 目的 涉及配置
操作系统引导 移除对非 Linux 系统冗余镜像格式支持 CONFIG_BOOTM_NETBSDCONFIG_BOOTM_PLAN9CONFIG_BOOTM_RTEMSCONFIG_BOOTM_VXWORKS
启动调试日志 关闭启动阶段性能统计、控制台日志记录、预启动环境调试相关功能,避免额外内存操作日志输出耗时。 CONFIG_BOOTSTAGECONFIG_CONSOLE_RECORDCONFIG_USE_PREBOOT
命令集 移除启动阶段需要调试、测试、硬件操作命令,减少命令解析开销、缩短初始化时间,同时缩小镜像。 CONFIG_CMD_BDICONFIG_CMD_CONSOLECONFIG_CMD_BOOTDCONFIG_CMD_BOOTFLOWCONFIG_CMD_BOOTICONFIG_CMD_ELFCONFIG_CMD_XIMGCONFIG_CMD_RANDOMCONFIG_CMD_MEMTESTCONFIG_CMD_ADCCONFIG_CMD_GPIOCONFIG_CMD_I2CCONFIG_CMD_MTDCONFIG_CMD_SFCONFIG_CMD_SF_TESTCONFIG_CMD_USB_MASS_STORAGECONFIG_CMD_WDTCONFIG_CMD_DHCPCONFIG_CMD_MIICONFIG_CMD_PINGCONFIG_CMD_BOOTSTAGECONFIG_CMD_MTDPARTSCONFIG_FASTBOOT_FLASH_SPINANDCONFIG_CMD_LOGCONFIG_CMD_MEMDUMPCONFIG_CMD_UBICONFIG_CMD_UBI_RENAME
网络相关 关闭 U-Boot 网络协议栈、网络命令网络相关 Fastboot 功能,避免网卡、PHY、网络协议初始化耗时。 CONFIG_NETCONFIG_UDP_FUNCTION_FASTBOOT
存储与 Flash 关闭必需存储介质驱动、测试分区操作相关配置。 CONFIG_FASTBOOT_FLASH_SPINAND(依赖 CONFIG_CMD_MTDPARTS)、CONFIG_MTDCONFIG_AVB_VERIFY_MTDCONFIG_SPI_FLASH
外设驱动硬件 移除启动流程无需在 U-Boot 阶段初始化外设驱动,减少时钟配置、总线初始化开销。 CONFIG_GUC_ADCCONFIG_I2CCONFIG_PINCTRLCONFIG_USB_STORAGECONFIG_USB_KEYBOARDCONFIG_USB_HOST_ETHERCONFIG_HOBOT_BOARD_TYPE

2) 启动链路裁剪

  • 经 hb_quickstart_board_init_r 完成板级初始化:

init_fnc_t hb_quickstart_init_sequence_r[] = {
     initr_trace,    //初始化调试跟踪机制(Trace)
     initr_reloc,    //重定位后的收尾调整
     event_init,   //初始化事件处理框架(uboot驱动匹配相关)
     initr_caches,   //初始化 CPU 缓存(Cache)
     initr_reloc_global_data,    //重定位全局数据(gd,Global Data)
     initr_malloc,   //初始化堆管理器(malloc)
     initr_dm,   //初始化驱动模型(Driver Model,DM)
     initr_mmc,    //初始化 MMC 设备(SD 卡/eMMC)
     hb_quickstart_boot,    //指定硬件平台启动
}
  • ft_board_setup 裁剪如下:

int ft_board_setup(void *blob, struct bd_info *bd)
{
  (void)bd;
#ifdef CONFIG_CMD_SEND_ID
    hb_fdt_set_board_info(blob);
#endif
    hb_setup_ion_size(blob);
    fdt_rm_by_env(blob);
    return 0;
}

Kernel 优化

功能概述

内核优化牵涉模块,且主线内核自身启动路径较为精简,本次主要通过优化内核镜像压缩方式缩短整体启动时间。

压缩算法编译器优化

使用 LZO 压缩算法

CONFIG_KERNEL_LZO=y
CONFIG_EFI_ZBOOT=y
配置 作用 启动收益
CONFIG_KERNEL_LZO=y 使用 LZO 内核压缩算法。 提升内核解压速度。
CONFIG_EFI_ZBOOT=y 开启 CONFIG_KERNEL_LZO 依赖配置 依赖配置

System 优化

功能概述

保证多媒体功能正常前提下,通过精简启动链路、并行启动服务裁剪冗余功能,从而降低快速启动场景系统启动耗时。

主要改动说明

启动轻量级 init 程序

启用 BusyBox init,减小初始化框架自身资源时间开销,进入 menuconfig 界面进行配置:

Block Diagram

自启服务并行改造

/etc/init.d/rcS 改造并行启动 /etc/init.d/S??* (?? 代表数字)程序。

#!/bin/sh


# Start all init scripts in /etc/init.d
# executing them in numerical order.
#
for i in /etc/init.d/S??* ;do

     # Ignore dangling symlinks (if any).
     [ ! -f "$i" ] && continue

     case "$i" in
    *.sh)
        # Source shell script for speed.
        (
        trap - INT QUIT TSTP
        set start
        . $i
        ) &
        ;;
    *)
        # No sh extension, so fork subprocess.
        $i start &
        ;;
    esac
done

/etc/init.d/rcS 遍历所有以 S 开头 + 数字命名脚本,按文件名数字顺序加载。这里对 .sh 后缀脚本非 .sh 后缀脚本两种启动类型进行改造, " ) &""$i start &"后台并行执行,大幅缩短程序执行等待时间。

驱动模块加载脚本优化

S70loadko 分批后台并行加载驱动,避免显示链路加载完成过于滞后。

#!/bin/sh
...
start() {
  BOARD_ID=$(cat /sys/class/socinfo/board_id)
  echo "<6>Starting load kernel driver..." > /dev/kmsg

  WAIT_TRIES=200
  # camsys driver
  for m in vs_isc vs_cam_ctrl vs_cam_pulse vs_csi_wrapper; do
    start_bg "$m"
  done
  for m in hobot_osd hobot_vin_vnode hobot_vin_vcon vs_sif_nat; do
    start_bg "$m"
  done
  wait_pids || exit 1

  for m in \
    hobot_sensor hobot_mipiphy hobot_mipicsi hobot_mipidbg \
    vs_isp_nat vs_vse_nat \
    hobot_deserial hobot_gdc hobot_isi_sensor \
    panel-jc-050hd134 vio_n2d lontium_lt8618 \
    vs-x5-syscon-bridge \
    hobot_lpwm panel-drobot-csi vs_drm; do
    start_bg "$m"
  done
...

依赖关系内核模块划分若干批次,批次通过后台任务并行 modprobe 加载。

文件系统裁剪

移除调试、压测、网络串口必需工具服务,缩小文件系统体积。

裁剪类别 目的 涉及配置
调试工具 移除 gdbserver、minicom、lrzsz、sudo 等调试工具 BR2_PACKAGE_GDB_SERVERBR2_PACKAGE_MINICOMBR2_PACKAGE_LRZSZBR2_PACKAGE_SUDO
性能监测测试 移除 iozone、memstat、cpuload、htop 等性能监测压测工具 BR2_PACKAGE_IOZONEBR2_PACKAGE_MEMSTATBR2_PACKAGE_CPULOADBR2_PACKAGE_HTOP
存储分区格式化 移除 mtd-utils、mkfs.ubifs、mtdpart 等 MTD 分区格式化相关用户工具 BR2_PACKAGE_MTDBR2_PACKAGE_MTD_MKFSUBIFSBR2_PACKAGE_MTD_MTDPART
音频、日志网络服务 移除 tinyalsa、zlog、dnsmasq、gesftpserver 等音频命令行、日志组件小型网络服务 BR2_PACKAGE_TINYALSABR2_PACKAGE_ZLOGBR2_PACKAGE_DNSMASQBR2_PACKAGE_GESFTPSERVER
工具集 关闭 GNU coreutils(ls、cp、mv 等与 BusyBox 功能重叠) BR2_PACKAGE_COREUTILS

显示应用优化

功能概述

single_pipe_vin_isp_vse_quickstart_display一个用于验证单路视频采集显示功能快速显示示例。

注意事项示例适用于 SC230AI 传感器模组,其它型号传感器示例验证,请勿程序用于 SC230AI 以外传感器

代码位置目录结构

  • 代码位置 app/samples/platform_samples/sample_pipeline/single_pipe_vin_isp_vse_quickstart_display.c

  • 目录结构

├── Makefile
├── single_pipe_vin_isp_vse_quickstart_display
├── single_pipe_vin_isp_vse_quickstart_display.c
├── vp_display.c
└── vp_display.h

显示应用启动流程图

App 启动流程

整体上,显示应用优化重点是:通过线程并行(hbmem_open_worker/display_init_worker)和缓存探测路径 create_and_run_vflow准备时间,从而达到加速启动目的。

程序运行

source /etc/profile.d/environment.sh
/app/platform_samples/sample_pipeline/single_pipe_vin_isp_vse_quickstart_display/single_pipe_vin_isp_vse_quickstart_display -s 3

参数说明: 这里 sensor 使用 sc230ai-30fps 配置项。

4.4.5.6. FAQ

如何加载自定义内核模块

处理:在负责加载内核模块脚本中(例如 S70loadko)查找 modprobe bpu_hw_io_x5 位置,在之后添加即可。

如何开启 OTA(AB 分区)配置

处理: 在下列配置文件之一中,按构建类型选择实际使用配置文件(Debug / Release 以产品发布说明为准):

  • device/horizon/x5/board_x5_evb_quickstart_debug_config.mk

  • device/horizon/x5/board_x5_evb_quickstart_release_config.mk

HR_PART_CONF_FILENAME 设置修改为:

export HR_PART_CONF_FILENAME=${HR_BOARD_CONF_DIR}/x5-soc-debug-ab-gpt.json