4. 镜像升级

本章介绍如何使用HMDML工具升级后摩设备镜像。

4.1. 固件升级与回退机制

HMDML 固件升级接口支持基于A/B双分区的固件升级与回退机制,用于提升系统升级的可靠性与容错能力。该功能由后摩设备eFuse配置决定,仅在1.4.0或更高版本固件镜像中支持。

在启用该功能后,系统维护A与B两个分区。HMDML 固件升级接口根据内部策略仅对一个分区进行固件升级更新。

在升级过程中,若发生掉电或异常重启等情况,当前正在运行的系统不受影响,后摩设备仍可从另一可用分区启动。当新版本分区因镜像损坏、校验失败或启动异常导致无法正常启动时,后摩设备启动失败时自动回退至另一可启动分区继续启动,从而保障系统可恢复能力,降低升级失败导致设备不可用的风险。

在未启用双分区能力时,系统仅存在单一启动分区,不具备双分区交替升级与回退机制。

4.2. 升级镜像

下面以Android系统为例介绍如何升级镜像。

在Android主机端,通过HMDML后摩设备管理库C接口升级固件镜像。

4.2.1. 升级前操作

在主机端创建目录,用于存放固件升级示例程序、构建脚本、编译脚本,以及升级程序编译所需的接口头文件和 HAL 库文件。其中,接口头文件和 HAL 库文件需从已安装的驱动目录中获取。下面以 upgrade_firmware 为目录名,介绍如何完成固件升级前准备。

  1. 创建 upgrade_firmware 文件夹:

    mkdir -p upgrade_firmware
    
  2. 复制固件升级示例源码到 upgrade_firmware 目录下。固件升级可直接使用后摩提供的 hm_fw_upgrade_example.c 示例代码。

    cd /path/to/houmo-drv-xh2/hal/export/samples
    scp hm_fw_upgrade_example.c /path/to/upgrade_firmware/
    
  3. 构建脚本:参见 创建构建脚本

  4. 编译脚本:参见 创建编译脚本

  5. 从系统软件包的 /path/to/houmo-drv-xh2/hal/export/include 目录复制 hm_sys.hhm_api.hupgrade_firmware 目录下:

    cd /path/to/houmo-drv-xh2/hal/export/include
    scp hm_api.h hm_sys.h ../../../../upgrade_firmware/
    
  6. 从系统软件包的 /path/to/houmo-drv-xh2/hal/lib 目录复制 libhal_xh2a.alibhal_xh2a.soupgrade_firmware 目录下:

    cd /path/to/houmo-drv-xh2/hal/lib
    scp libhal_xh2a.a libhal_xh2a.so ../../../upgrade_firmware/
    

4.2.1.1. 创建构建脚本

镜像升级前,用户需在 upgrade_firmware 目录下创建一个CMake构建脚本,用于在主机端编译生成可执行文件。示例文件名为 CMakeLists.txt,主要操作如下:

  1. 设置 CMake 工程信息与 C++ 标准。

    • 指定 CMake 最低版本和工具链文件。

    • 设置 C++ 标准为 C++17,并开启调试信息。

  2. 配置 Android 平台信息。

    • ANDROID_NDK :替换为主机端实际 NDK 安装路径。

    • ANDROID_PLATFORM :指定 Android API 版本,例如 android-24。

    • ANDROID_ABI :指定目标架构,例如 arm64-v8a。

    • 设置 Android STL 为共享库 c++_shared

  3. 设置 HAL 库及头文件路径:

    • HAL_LIBRARY :替换为主机端驱动动态库 libhal_xh2a.so 的路径。该库位于驱动安装包中 houmo-drv-xh2_<release>_android_$arch/houmo-drv-xh2/hal/lib 下。

    • 通过 include_directories 指定头文件路径,例如工程通用头文件 ${CMAKE_BINARY_DIR}/../../common 和 Android 系统头文件 ${ANDROID_NDK}/sysroot/usr/include

  4. 添加可执行文件并链接库。

    • 通过 add_executable 设置输出可执行文件名。

    • 通过 target_link_libraries 链接 HAL 动态库,实现驱动接口调用。

完整示例如下,示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。

cmake_minimum_required(VERSION 3.16)
set(CMAKE_TOOLCHAIN_FILE ${ANDROID_NDK}/build/cmake/android.toolchain.cmake)
project(IpuTest)

# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")

# Android特定配置 - 需通过命令行传入ANDROID_NDK路径
if(NOT ANDROID_NDK)
    message(FATAL_ERROR "请通过-DANDROID_NDK=指定NDK路径")
endif()

# 设置Android平台和架构
if(NOT ANDROID_PLATFORM)
    set(ANDROID_PLATFORM android-24)  # 最低支持Android 7.0
endif()

if(NOT ANDROID_ABI)
    set(ANDROID_ABI arm64-v8a)  # 默认编译ARM64架构
endif()

# Android平台配置
set(ANDROID_STL c++_shared)  # 使用共享STL
set(ANDROID_USE_LEGACY_TOOLCHAIN_FILE FALSE)

# 设置库文件名称和搜索路径(Android平台)
set(HAL_LIBRARY_NAMES hal_xh2a)
set(LIB_SEARCH_PATHS
    ${CMAKE_CURRENT_SOURCE_DIR}/../lib/android/${ANDROID_ABI}/  # 按架构区分的库路径
    ${CMAKE_CURRENT_SOURCE_DIR}/../lib/android/  # 通用Android库路径
)
set(CMAKE_FIND_LIBRARY_SUFFIXES .so .a)  # Android常用库后缀

# 直接指定库文件绝对路径,替换所有 find_library 相关代码
set(HAL_LIBRARY /path/to/houmo-drv-xh2/hal/lib/libhal_xh2a.so)
if(NOT EXISTS ${HAL_LIBRARY})
    message(FATAL_ERROR "HAL库不存在:${HAL_LIBRARY}")
endif()
message(STATUS "找到HAL库: ${HAL_LIBRARY}")

# 包含头文件目录
include_directories(${CMAKE_CURRENT_SOURCE_DIR})

# 添加可执行文件
add_executable(upgrade_firmware hm_fw_upgrade_example.c)

# 链接库文件
target_link_libraries(upgrade_firmware PRIVATE ${HAL_LIBRARY})

4.2.1.2. 创建编译脚本

在主机端,需在 upgrade_firmware 目录下,创建一个用于编译固件升级示例程序的 shell 脚本,并保存为 .sh 文件,例如 compile.sh。主要内容如下:

  1. 设置编译目录。在示例中,将编译产物输出到 build_android 目录。

  2. 示例中用户需根据实际环境修改变量值:

    • NDK_PATH :主机端 Android NDK 的实际安装路径。

    • HOUMO_SDK_PATH :主机端后摩驱动路径,通常位于驱动安装包中 houmo-drv-xh2_<release>_android_$arch/houmo-drv-xh2 目录下。

    • ANDROID_ABI :目标架构,如 arm64-v8a

    • ANDROID_PLATFORM :Android平台版本,如 android-27

  3. 执行 CMake 生成 Makefile,并通过 Make 编译生成可执行文件。

完整示例如下,示例展示关键步骤代码,仅供参考,不可以直接拷贝运行。

#!/bin/bash

# 配置编译目录
BUILD_DIR=build_android
rm -rf $BUILD_DIR
mkdir -p $BUILD_DIR
cd $BUILD_DIR

# 关键:指定 NDK 路径(替换为你的实际 NDK 路径)
NDK_PATH="/path/to/android-ndk-r27c"  # 例如:~/Android/Sdk/ndk/r27d
HOUMO_SDK_PATH="/path/to/houmo_drv_xh2"
ANDROID_ABI="arm64-v8a"
ANDROID_PLATFORM="android-27"

# 执行 cmake 生成 Makefile(参数必须写在同一行,用空格分隔)
cmake --fresh .. \
-DANDROID_NDK=$NDK_PATH \
-DANDROID_PLATFORM=android-27 \
-DANDROID_ABI=arm64-v8a

# 编译(-j4 表示使用 4 线程加速)
make -j4

# 回到原目录
cd ..

4.2.2. 升级操作

4.2.2.1. 升级前准备

镜像升级前,完成镜像升级前准备:

  1. 确保符合 环境依赖

  2. 安装驱动。详情参看《软件平台驱动安装指南》

4.2.2.2. 升级步骤

镜像升级主要步骤如下:

  1. 固件镜像位于系统软件tar包内,用户需要下载系统软件tar包来获取固件镜像。在主机端,执行下面步骤下载固件镜像:

    1. 登录后摩开发者社区

    2. 请先选择板级类别 下拉列表中选择使用的后摩板级产品。

    3. 在版本列表中选择下载的版本号,再在 AI模型类别筛选器平台架构筛选器操作系统筛选器 下拉菜单中分别选择AI模型类型、平台架构和操作系统,找到资源名为芯片固件的下载资源,选中该资源左边复选框。

    4. 点击 直接下载wget链接批量直接下载wget批量下载 按钮。

    5. 解压缩系统软件tar包。镜像位于解压后文件夹下。

  2. 解压缩固件镜像:

    tar -xf M50_DM2_fw-xh2_<release>.tar.gz
    

    解压后,固件镜像存放在 M50_DM2_fw-xh2 目录下。

  3. 完成 升级前操作

  4. 编译生成可执行文件。在主机端执行以下命令,生成可执行文件:

    cd upgrade_firmware
    chmod +x compile.sh
    ./compile.sh
    

    编译成功后,会在编译脚本中指定的输出目录中生成可执行文件。示例中,该目录为 build_android,可执行文件名称为 upgrade_firmware

  5. 传输文件至 Android 端。

    1. 将主机端的 upgrade_firmware 文件夹推送至 Android 端的 /data/houmo 目录:

      adb push upgrade_firmware /data/houmo
      
    2. 传输下载的镜像文件到 Android 端指定目录:

      adb push M50_DM2_fw-xh2/images /data/houmo/upgrade_firmware
      
  6. 启动Android开发板并进入 shell 模式:

    adb shell
    su
    
  7. 配置环境变量。在 Android 端设置驱动库路径:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/houmo/houmo-drv-xh2/hal/lib
    
  8. 升级镜像。在 Android 端,进入 upgrade_firmware 目录,执行以下命令升级。仅需升级 firmware.img 镜像。示例如下:

    cd /data/houmo/upgrade_firmware/build_android
    ./upgrade_firmware -f ../images/firmware.img -d all
    

    固件升级以逻辑设备(即单颗 M50 芯片)为基本单元。对于多颗芯片的产品(如 LQ50 Duo M.2卡),须确保完成卡内所有逻辑设备的升级,建议一次完成所有逻辑设备升级。

  9. 重启Android端。升级完成后,在 Android 端执行以下命令重启系统,使新固件生效:

    reboot
    

镜像升级后,需完成 设备检测与升级验证,确保镜像升级成功。

4.2.3. 设备检测与升级验证

本节用于在完成设备升级后,通过示例程序验证设备驱动与固件是否正常加载,并获取设备基础信息与运行状态。

执行以下步骤进行设备检查:

  1. 在主机端创建 device_check 文件夹:

    mkdir -p device_check
    
  2. 复制设备信息获取示例源码到 device_check 目录下。设备信息获取可直接使用后摩提供的 hm_sys_info_examples.c 示例代码。

    cd /path/to/houmo-drv-xh2/hal/export/samples
    scp hm_sys_info_examples.c /path/to/device_check/
    
  3. device_check 目录下创建一个CMake构建脚本,用于在主机端编译生成可执行文件。示例文件名为 CMakeLists.txt。参数设置及说明,参看 创建构建脚本

    需在 add_executable 中设置目标可执行文件名称为 device_check,并且绑定本示例源码文件 hm_sys_info_examples.c

    需在 target_link_libraries 中设置目标可执行文件名称为 device_check

    cmake_minimum_required(VERSION 3.16)
    set(CMAKE_TOOLCHAIN_FILE ${ANDROID_NDK}/build/cmake/android.toolchain.cmake)
    project(IpuTest)
    
    # 设置C++标准
    set(CMAKE_CXX_STANDARD 17)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
    
    # Android特定配置 - 需通过命令行传入ANDROID_NDK路径
    if(NOT ANDROID_NDK)
        message(FATAL_ERROR "请通过-DANDROID_NDK=指定NDK路径")
    endif()
    
    # 设置Android平台和架构
    if(NOT ANDROID_PLATFORM)
        set(ANDROID_PLATFORM android-24)  # 最低支持Android 7.0
    endif()
    
    if(NOT ANDROID_ABI)
        set(ANDROID_ABI arm64-v8a)  # 默认编译ARM64架构
    endif()
    
    # Android平台配置
    set(ANDROID_STL c++_shared)  # 使用共享STL
    set(ANDROID_USE_LEGACY_TOOLCHAIN_FILE FALSE)
    
    # 设置库文件名称和搜索路径(Android平台)
    set(HAL_LIBRARY_NAMES hal_xh2a)
    set(LIB_SEARCH_PATHS
        ${CMAKE_CURRENT_SOURCE_DIR}/../lib/android/${ANDROID_ABI}/  # 按架构区分的库路径
        ${CMAKE_CURRENT_SOURCE_DIR}/../lib/android/  # 通用Android库路径
    )
    set(CMAKE_FIND_LIBRARY_SUFFIXES .so .a)  # Android常用库后缀
    
    # 直接指定库文件绝对路径,替换所有 find_library 相关代码
    set(HAL_LIBRARY /path/to/houmo-drv-xh2/hal/lib/libhal_xh2a.so)
    if(NOT EXISTS ${HAL_LIBRARY})
        message(FATAL_ERROR "HAL库不存在:${HAL_LIBRARY}")
    endif()
    message(STATUS "找到HAL库: ${HAL_LIBRARY}")
    
    # 包含头文件目录
    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
    
    # 添加可执行文件
    add_executable(device_check hm_sys_info_examples.c)
    
    # 链接库文件
    target_link_libraries(device_check PRIVATE ${HAL_LIBRARY})
    
  4. device_check 目录下创建编译脚本,如 compile.sh。用于执行交叉编译流程。建议直接复用镜像升级流程中的编译脚本。

  5. 从系统软件包的 /path/to/houmo-drv-xh2/hal/export/include 目录复制 hm_sys.hhm_api.hdevice_check 目录下:

    cd /path/to/houmo-drv-xh2/hal/export/include
    scp hm_api.h hm_sys.h ../../../../device_check/
    
  6. 从系统软件包的 /path/to/houmo-drv-xh2/hal/lib 目录复制 libhal_xh2a.alibhal_xh2a.sodevice_check 目录下:

    cd /path/to/houmo-drv-xh2/hal/lib
    scp libhal_xh2a.a libhal_xh2a.so ../../../device_check/
    
  7. 编译生成可执行文件。在主机端执行以下命令,生成可执行文件:

    cd device_check
    chmod +x compile.sh
    ./compile.sh
    

    编译成功后,会在编译脚本中指定的输出目录中生成可执行文件。示例中,该目录为 build_android,可执行文件名称为 device_check

  8. 传输文件至 Android 端。

    1. 将主机端的 device_check 文件夹推送至 Android 端的 /data/houmo 目录:

      adb push device_check /data/houmo
      
    2. 启动Android开发板并进入 shell 模式:

      adb shell
      su
      
  9. 配置环境变量。在Android端设置驱动库路径:

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/houmo/houmo-drv-xh2/hal/lib
    
  10. 获得设备信息。在Android端,进入 device_check 目录,执行以下命令获取设备信息。

    cd /data/houmo/device_check/build_android
    ./device_check
    

    设备信息输出示例如下:

    ===== Device 0 =====
    [dev 0] Basic Properties:
      vendor id: 0x1f6b
      serial: 0206020100002025004800000019
      name: LQ50 DUO-36GB
      computing power: 100 TFLOPS
      core count: 2
    [dev 0] Runtime Metrics:
      core util rate: 0.00
        core[0] util: 0.00
        core[1] util: 0.00
      avg ipu frequency: 1400000000 Hz
      ipu voltage: 750.00 mV
      memory: total 18304 MB, used 0 MB, avail 18304 MB
      temperature: 26.59 C
    [dev 0] PCIe / Board Info:
      PCIe BDF: 0001:11:00.00
      PCIe bandwidth: 8.0 GT/s PCIe -2lane
      board power: 12.59 W
    [dev 0] SDK and Firmware Info:
      SDK build time: May 19 2026 00:37:11
      SDK version: v1.3.0
      driver version: v1.3.0
      device firmware version: 1.3.0
      DDR size: 19327352832 bytes
      DVFS mode: 0
    
    ===== Device 1 =====
    [dev 1] Basic Properties:
      vendor id: 0x1f6b
      serial: 0206020100002025004800000019
      name: LQ50 DUO-36GB
      computing power: 100 TFLOPS
      core count: 2
    [dev 1] Runtime Metrics:
      core util rate: 0.00
        core[0] util: 0.00
        core[1] util: 0.00
      avg ipu frequency: 1400000000 Hz
      ipu voltage: 750.00 mV
      memory: total 18304 MB, used 0 MB, avail 18304 MB
      temperature: 26.88 C
    [dev 1] PCIe / Board Info:
      PCIe BDF: 0000:01:00.00
      PCIe bandwidth: 8.0 GT/s PCIe -2lane
      board power: 0.00 W
    [dev 1] SDK and Firmware Info:
      SDK build time: May 19 2026 00:37:11
      SDK version: v1.3.0
      driver version: v1.3.0
      device firmware version: 1.3.0
      DDR size: 19327352832 bytes
      DVFS mode: 0