news 2026/10/6 6:16:49

昇腾910B在openEuler上驱动固件MCU升级实操指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
昇腾910B在openEuler上驱动固件MCU升级实操指南

最近帮客户在openEuler 22.03 LTS上交付了一套昇腾910B AI训练环境,过程比想象中曲折不少。前前后后折腾了几个晚上,从初始驱动装不上、MCU版本不匹配导致设备掉线,到最后把驱动、固件、MCU升级流程彻底摸透,整理出一套带自动脚本的完整安装流程。这篇文章就把这次实操完整记录下来,包括环境检查、软件包选型、脚本设计、MCU升级的触发机制,以及npu-smi验证细节,给同样在国产服务器上做昇腾环境的朋友做个参考。

先说清楚你的目标:如果服务器刚到手,前面插了一张910B的PCIe卡,系统是openEuler 22.03 LTS,那么这张卡默认是没法直接用的。昇腾硬件和普通GPU不一样,板卡上不仅有计算用的NPU,还有一个独立的MCU(微控制单元)负责整块板的电源管理、温度监控和风扇策略。开箱后的板卡,MCU固件是出厂版本,跟新版驱动往往不匹配,你必须按顺序完成驱动安装、固件升级和MCU升级,硬件才能在Linux上稳定工作。下面就是一条龙解决这三个环节的实操记录。

1. 驱动、固件和MCU到底管什么:先把升级顺序想明白

在跑脚本之前,强烈建议你先搞清这层软件栈的关系,否则遇到问题会很难定位。

1.1 昇腾910B上的两套处理核心:NPU与MCU

昇腾910B不是一颗简单的加速芯片,它是一整块复杂的板卡。板上除了计算用的NPU,还有内存颗粒、电源管理模块、温度传感器,以及一颗专门负责“伺候”这些硬件的微控制器,也就是MCU。MCU在板卡里扮演的是“管家”角色:上电时序由它控制,每一路供电电压由它监控,传感器温度和风扇转速由它上报,甚至板卡的序列号、版本号信息也由它存储。

最关键的一点是,MCU是独立于NPU计算单元运行的。它有自己的固件,通过低速总线跟主控侧通信。驱动加载时,真正跟NPU芯片交互的是NPU固件;而驱动能否成功初始化PCIe设备、能否正确读取板卡信息,依赖的是MCU固件。两套固件同时正常,板卡才处于健康状态。

1.2 为什么顺序不能乱:先驱动,再固件

实际操作中,安装顺序有先驱动后固件和先固件后驱动两派。根据官方手册和这次实测下来的结论,建议顺序是:先装驱动,再装固件,因为固件包内部包含MCU升级流程。

这个顺序背后的逻辑是:

  • 驱动安装成功后,操作系统的PCIe子系统才能正确识别910B设备,生成 /dev/davinci0 等设备节点。
  • 固件升级工具需要借助驱动提供的系统接口和板卡通信,否则它无法访问设备的控制通道。
  • 固件包升级时会自动检测当前MCU版本,发现版本低于包内自带版本时执行MCU升级。驱动先行能保证这个检测和升级过程顺利。

如果你上来就刷固件,而驱动还没装或没正确加载,大部分固件包会直接报“no device found”。这不是包坏了,是顺序没搞对。

1.3 版本匹配的底层逻辑

昇腾HDK软件包命名有规律,比如Ascend-hdk-910b-npu-driver_23.0.rc1_linux-aarch64.run,其中23.0.rc1就是大版本号。驱动和固件必须处在同一个大版本内,驱动是24.0、固件是23.0的话,驱动加载后照样会报固件版本过低的错误。

MCU固件不会单独给一个下载链接,而是打包在固件run文件里。所谓“MCU升级”,本质上是固件安装过程中,检测到MCU版本不一致时自动触发的一次组件更新。固件安装脚本的执行顺序是:NPU固件版本检查 → MCU固件版本检查 → 按需升级MCU → 写入固件存储 → 复位板卡。

组件文件形态安装方式升级结果
驱动driver的.run包--full内核模块加载,/dev/davinci* 出现
NPU固件firmware的.run包--full芯片固件更新,算力状态正常
MCU固件打包在firmware包内固件安装时自动触发电源/温度监控、板管理功能正常

MCU升级时,板卡会有一个短暂断电重启的过程,系统日志能看到相关I2C设备重新枚举,风扇会瞬间满转。这是正常现象,只要不是反复失败,不用慌。

2. 环境准备与软件包获取:动手前把这些坑先填平

2.1 操作系统与架构确认

打开终端先执行两条命令:

cat /etc/openEuler-release uname -m

正常输出类似:

openEuler release 22.03 (LTS) aarch64

昇腾910B驱动主要提供aarch64架构版本。如果你的服务器是x86平台,需要确认板卡是否支持x86环境。本文场景默认是ARM架构,也就是鲲鹏加昇腾的经典组合。

再看内核版本:

uname -r

openEuler 22.03 LTS默认内核一般是5.10.x。驱动安装时通过dkms编译模块或加载预编译ko,因此内核开发包必须和当前运行内核严格一致,这一点后面会反复提到。

2.2 下载昇腾HDK软件包并校验

从昇腾社区官网下载软件包时,需要拿两类文件:

  • Ascend-hdk-910b-npu-driver_x.x.x_linux-aarch64.run
  • Ascend-hdk-910b-npu-firmware_x.x.x_linux.run

下载后务必做完整性校验:

sha256sum Ascend-hdk-910b-npu-driver_*.run

拿这个结果去对比官网公布的校验值。这一步别省,网络传输导致文件损坏或被人篡改的情况不是没发生过。校验不一致的包,装上去了也是各种稀奇古怪的报错。

2.3 安装编译依赖与清理旧驱动

昇腾驱动编译需要内核头文件和工具链:

sudo yum install -y gcc gcc-c++ make dkms sudo yum install -y kernel-devel-$(uname -r) kernel-headers-$(uname -r)

如果yum报错找不到kernel-devel-$(uname -r),先尝试安装通用包:

sudo yum install -y kernel-devel kernel-headers

然后检查源码目录是否存在:

ls /usr/src/kernels/$(uname -r)

这个目录不存在或为空,驱动编译基本必失败,是昇腾安装里最常踩的坑之一。

旧驱动清理同样重要。之前装过旧版昇腾驱动,没有卸载干净就装新版,老ko模块会和新模块冲突,加载时报“File exists”。标准卸载命令是:

sudo /usr/local/Ascend/driver/script/uninstall.sh --uninstall sudo rm -rf /usr/local/Ascend

清理之后最好重启一次再继续,避免残留的内核模块状态影响新驱动加载。

3. 手写一键升级脚本:从裸机到可用环境的自动化

3.1 脚本设计思路

为什么不直接手动敲两条命令,非要写脚本?因为整个升级过程的检查点太多,任何一环失败后面都要重新排查。脚本把常见检查、清理、安装、验证步骤固化,既保证流程可复现,也让新认识的朋友或团队同事能在一台新服务器上快速完成部署。

脚本按六个步骤设计:

  1. 权限和前置条件检查
  2. 旧环境清理
  3. 安装编译依赖
  4. 安装驱动包
  5. 安装固件包(覆盖MCU升级)
  6. 设置环境变量与输出验证信息

每个步骤写日志到/var/log/ascend_upgrade/,便于事后回溯。任何一步失败立即退出并打印明确错误,不继续往下执行。

3.2 MCU升级在脚本里的处理方式

MCU升级没有独立的公开命令,它是固件安装包执行到某个阶段时弹出交互提示,询问是否升级MCU。自动化的处理方式,是通过管道往固件安装脚本里喂y应答,让它顺着提示走默认升级流程。

我实测下来,yes |方式在昇腾固件包上稳定有效。这也符合运维里常见的“交互式安装转自动化”套路。如果你更习惯手动安装,在固件包提示时输入y即可,效果一样。

3.3 完整脚本代码

下面是脚本全文,保存为ascend_910b_upgrade.sh:

#!/bin/bash set -euo pipefail # ============================================================= # 昇腾910B 驱动 + 固件 + MCU 升级脚本 (openEuler 22.03 LTS) # 用法: sudo bash ascend_910b_upgrade.sh <driver.run> <firmware.run> # 示例: sudo bash ascend_910b_upgrade.sh \ # Ascend-hdk-910b-npu-driver_23.0.rc1_linux-aarch64.run \ # Ascend-hdk-910b-npu-firmware_23.0.rc1_linux.run # ============================================================= DRIVER_PKG="${1:-}" FIRMWARE_PKG="${2:-}" ARCH="$(uname -m)" LOG_DIR="/var/log/ascend_upgrade" LOG_FILE="$LOG_DIR/upgrade_$(date +%Y%m%d_%H%M%S).log" mkdir -p "$LOG_DIR" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE" } fail() { log "[ERROR] $*" exit 1 } # 1. 权限检查 if [ "$(id -u)" -ne 0 ]; then fail "必须使用root权限执行,建议: sudo bash $0 <driver.run> <firmware.run>" fi # 2. 参数检查 if [ -z "$DRIVER_PKG" ] || [ ! -f "$DRIVER_PKG" ]; then fail "第一个参数必须指定driver.run文件路径" fi if [ -z "$FIRMWARE_PKG" ] || [ ! -f "$FIRMWARE_PKG" ]; then fail "第二个参数必须指定firmware.run文件路径" fi # 3. 架构检查 if [ "$ARCH" != "aarch64" ]; then fail "当前架构是 $ARCH,昇腾910B驱动仅支持 aarch64" fi # 4. 操作系统提示 if [ ! -f /etc/openEuler-release ]; then log "警告: 当前系统不是openEuler,若继续执行请自担风险" fi # 5. 定位run文件所在目录 SCRIPT_DIR="$(cd "$(dirname "$DRIVER_PKG")" && pwd)" DRIVER_NAME="$(basename "$DRIVER_PKG")" FIRMWARE_NAME="$(basename "$FIRMWARE_PKG")" cd "$SCRIPT_DIR" chmod +x "$DRIVER_NAME" "$FIRMWARE_NAME" log "========== 昇腾910B 升级开始 ==========" log "驱动包 : $DRIVER_NAME" log "固件包 : $FIRMWARE_NAME" log "日志 : $LOG_FILE" # 6. 清理旧驱动 if [ -d /usr/local/Ascend/driver ]; then log "检测到已有旧版驱动,开始卸载..." if [ -x /usr/local/Ascend/driver/script/uninstall.sh ]; then /usr/local/Ascend/driver/script/uninstall.sh --uninstall || log "卸载脚本返回非0,继续尝试清理" fi rm -rf /usr/local/Ascend log "旧驱动已清理,建议清理后重启一次再继续安装" fi # 7. 安装编译依赖 log "安装编译依赖..." if command -v dnf >/dev/null 2>&1; then dnf install -y gcc gcc-c++ make dkms \ kernel-devel-"$(uname -r)" kernel-headers-"$(uname -r)" || true else yum install -y gcc gcc-c++ make dkms \ kernel-devel-"$(uname -r)" kernel-headers-"$(uname -r)" || true fi if [ ! -d "/usr/src/kernels/$(uname -r)" ]; then log "警告: 未找到 /usr/src/kernels/$(uname -r),驱动编译可能失败" fi # 8. 安装驱动 log "开始安装驱动: $DRIVER_NAME" if yes | "$SCRIPT_DIR/$DRIVER_NAME" --full >> "$LOG_FILE" 2>&1; then log "驱动安装成功" else fail "驱动安装失败,请查看日志 $LOG_FILE" fi # 9. 安装固件(含MCU升级) log "开始安装固件(含MCU升级): $FIRMWARE_NAME" if yes | "$SCRIPT_DIR/$FIRMWARE_NAME" --full >> "$LOG_FILE" 2>&1; then log "固件安装成功,MCU升级流程已执行" else fail "固件安装失败,请查看日志 $LOG_FILE" fi # 10. 设置环境变量 log "配置环境变量..." cat > /etc/profile.d/ascend-env.sh <<'EOF' export ASCEND_HOME=/usr/local/Ascend export PATH=$ASCEND_HOME/driver/tools:$PATH export LD_LIBRARY_PATH=$ASCEND_HOME/driver/lib64:$LD_LIBRARY_PATH EOF chmod +x /etc/profile.d/ascend-env.sh source /etc/profile.d/ascend-env.sh # 11. 验证 log "========== 安装完成,输出设备信息 ==========" if command -v npu-smi >/dev/null 2>&1; then npu-smi info | tee -a "$LOG_FILE" || \ log "提示: npu-smi 暂时无法获取设备信息,可能需重启后生效" else log "未找到 npu-smi 命令,请检查驱动安装路径" fi log "========== 脚本执行结束 ==========" log "如果上面没有看到设备信息,执行: sudo reboot 后再运行 npu-smi info 验证"

3.4 脚本关键段解释

有几点需要重点理解,不然脚本换到别的环境还是会踩坑。

set -euo pipefail:这一行是脚本的保险丝。set -e让任何命令返回非0时中断脚本;set -u让未定义变量直接报错;set -o pipefail保证管道中任意一段失败都能被捕获。对安装类脚本,这个组合特别关键,因为很多失败藏在管道深处,不开启这个选项你根本发现不了。

第6步旧驱动清理:卸载脚本可能因为系统服务状态返回非0,所以管道里用了|| log避免脚本因为卸载脚本的小问题卡死。但清理动作本身不能跳过,否则后面安装新驱动会撞上“insmod failed: File exists”的问题。

第7步依赖安装:openEuler 22.03的软件源在不同镜像上差异明显,依赖安装失败我故意不让脚本立即退出,而是保留后续检查。真正的硬性条件是/usr/src/kernels/$(uname -r)目录存在,那是dkms编译模块需要的内核头文件位置。这个检查比依赖安装命令本身更能反映真实问题。

第8、9步yes |:固件run安装脚本检测到MCU版本落后时会弹出确认,用yes自动应答所有确认问题。这是一个很基础的自动化技巧,但对昇腾固件包就是有效。装完你会看到日志里记录MCU升级成功的信息。

第10步环境变量:昇腾默认装到/usr/local/Ascend/driver,把tools和lib64加进 PATH 与 LD_LIBRARY_PATH,之后直接敲npu-smi就能用,不用每次都写全路径。

3.5 为什么脚本里没有单独的“MCU升级命令”

这是标题里最容易被误解的地方。很多人以为MCU升级有一条独立命令,实际上在昇腾910B的HDK固件包里,MCU升级是固件安装脚本内部编排的步骤。固件包安装会依次执行:NPU固件版本检查 → MCU固件版本检查 → 按需MCU升级 → 写入固件存储 → 复位板卡。外部只需要给它一个“同意升级”的应答。

如果真需要手动单独升级MCU,一般是先从固件包解压目录里找到mcu固件文件(可能是.hex或.bin格式),再进入板卡维护模式刷新。但这种操作只适用于MCU已经损坏、必须通过底层工具恢复的场景,正常业务部署不用走这条路。

4. 执行升级与结果验证:npu-smi怎么用才算真的会用了

4.1 脚本执行参考

把两个run文件放到同一个目录,然后执行:

sudo bash ascend_910b_upgrade.sh \ Ascend-hdk-910b-npu-driver_23.0.rc1_linux-aarch64.run \ Ascend-hdk-910b-npu-firmware_23.0.rc1_linux.run

执行过程会滚动输出日志。如果一切正常,最后几行会显示npu-smi抓到的设备信息:

[2025-01-12 15:22:33] ========== 安装完成,输出设备信息 ========== [2025-01-12 15:22:34] NPU ID ... Chip Count ... Total NPU Count ...

4.2 npu-smi基础检查

脚本结束不重启的情况下,设备节点可能还没完全就绪,先重启:

sudo reboot

重启后第一件事:

npu-smi info

正常输出会列出NPU卡数量、每张卡的温度、内存使用和算力状态。核心看这几个字段:

  • Chip Count:板上的芯片数量,910B单卡通常是1或2
  • Temperature:温度在合理区间,比如40度到70度之间
  • Memory Usage:显存是否正确识别,显示0或异常值说明固件没刷到位
  • AI Core状态:算力核是否正常

想查看更详细的板卡信息,包括MCU版本,执行:

npu-smi info -t board -i 0

这里-t是type,-i是设备ID。输出里会有PCB版本、固件版本、MCU版本等字段。把这些版本号记下来,跟HDK发布注记做对照,确认升级已生效。

再看内核模块是否加载:

lsmod | grep drv_

出现drv_mcu、drv_pcie、drv_davinci等模块,说明驱动加载成功。如果没有任何输出,需要检查dmesg和内核版本。

4.3 MCU和固件版本的验证细节

固件包安装完不代表MCU一定升级了。有一种情况:MCU当前版本和固件包要求版本一致时,固件脚本会跳过MCU升级,日志里会写类似“MCU version is already up to date, skip”。如果就是想强制刷新MCU,才需要单独手段。正常业务场景不做强制刷写。

MCU升级失败时会有典型现象:npu-smi info找不到设备,因为驱动依赖的MCU通信没正常起来;或者系统日志出现大量“mcu response timeout”、“i2c transfer error”。排查方向放在第5章。

还有一个容易忽略的点:昇腾驱动安装后默认创建名为HwHiAiUser的用户组。普通用户想调用NPU,需要加入这个组:

sudo usermod -a -G HwHiAiUser $USER

退出重新登录生效。不然后续跑训练程序会遇到权限报错。

5. 常见失败路径与修复清单

5.1 失败场景对照表

症状可能原因解决思路
驱动安装时找不到内核头文件kernel-devel未装或版本不匹配重新安装kernel-devel-$(uname -r),确认/usr/src/kernels/$(uname -r)存在
insmod failed: File exists旧驱动未清理卸载旧驱动,删除 /usr/local/Ascend,重启后重试
npu-smi找不到设备MCU升级失败或驱动未加载查看dmesg,重新执行固件安装;必要时进紧急维护模式恢复MCU
MCU response timeoutMCU固件损坏或升级中断重新执行固件包升级,过程中避免断电
重启后 /dev/davinci0 不存在驱动模块未自动加载检查模块加载状态,手动modprobe drv_pcie drv_mcu验证
固件包安装报 no device found驱动没装或设备没被系统识别确认卡已插好,BIOS里PCIe识别正常,再装驱动
Secure Boot开启导致模块加载失败驱动模块未签名进BIOS关闭Secure Boot后重启

5.2 MCU升级中断的恢复方法

MCU升级最怕中断。如果刷写过程中突然断电或系统崩溃,MCU可能进入半砖状态,NPU设备无法工作。不必太紧张,一般可以这样恢复:

  1. 把服务器完全断电,等待30秒再上电。
  2. 如果服务器有带外管理接口,登录管理页面的固件升级入口,选择固件包中的MCU固件文件强制刷写。
  3. 如果是普通PCIe服务器没有带外升级能力,用固件包解压后的scripts目录里的恢复脚本处理,比如recover_xxx.sh之类。

这个环节宁可慢不能急,MCU刷写过程绝对不要断电。

5.3 驱动模块加载失败快速定位

模块加载失败时,第一步看内核日志:

dmesg | tail -100

如果看到“No space left on device”,一般是板卡存储空间不足,核对固件包版本与当前硬件容量。如果看到“Operation not permitted”,大概率是Secure Boot没关。昇腾驱动模块没有在UEFI Secure Boot下签名,必须到BIOS里关掉Secure Boot,否则内核模块无法加载。新服务器的BIOS默认可能开着,这也是一个相当常见的新手坑。

5.4 一个容易误导人的场景:npu-smi正常但训练程序跑不起来

还有一种让人印象深刻的场景:npu-smi info看起来一切正常,卡也列得出来,但跑训练任务时进程直接挂掉,提示“device init failed”或“stream init failed”。这类问题多半不在驱动和MCU本身,而是驱动版本和CANN工具包版本不匹配。

昇腾的驱动、固件、CANN三者之间有严格的版本对应关系表,装完底层驱动和固件只是第一步,真正要跑训练还需要安装对应版本的CANN工具包。安装前先查版本配套表,别只看“最新版”就往上装。

6. 最后分享一点实操体会

整套流程走完,我的最大感受是:昇腾910B这套环境本身并不难,难的是信息不集中。官方文档分散在不同页面,版本对应关系表藏得深,升级顺序稍不留神就乱了。把自动化脚本沉淀下来之后,后来再在新服务器上重装整套环境,时间从三小时压到四十分钟左右,复制、执行、等结果就完事。

最后提醒一句:不管你是首次安装还是在做固件迭代升级,升级前把日志目录拷走备份,顺手拍一张产品序列号的照片,都是值得养成的习惯。MCU这种低层组件一旦出了问题,序列号和日志是最快的定位线索。祝大家都能顺利点亮手上的910B,把训练任务跑起来。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 6:16:45

统信UOS部署Proxmox VE虚拟化实战手册

简介&#xff1a;这份《开源PROXMOX-VE虚拟化解决方案部署手册》面向企业IT运维人员、系统集成工程师及虚拟化技术学习者&#xff0c;聚焦统信服务器企业版V20与Proxmox VE 5.4-1的整合部署场景&#xff0c;帮助读者将物理服务器资源抽象为可动态调配的逻辑资源池&#xff0c;实…

作者头像 李华
网站建设 2026/10/6 6:16:14

SGLang多芯插件机制解析与昆仑芯部署调优实战

1. 从"一套代码跑多种芯片"说起&#xff1a;多芯插件机制到底在解决什么如果你最近在折腾大模型推理部署&#xff0c;大概率会遇到一个很现实的问题&#xff1a;手里拿到的硬件五花八门&#xff0c;有英伟达的卡&#xff0c;也有国产加速卡&#xff0c;但推理框架往往…

作者头像 李华
网站建设 2026/10/6 6:15:53

数据结构课程设计:哈夫曼编码、跳马与长整数运算算法实现拆解

简介&#xff1a;《数据结构课程设计》报告PDF涵盖四个经典算法实践专题&#xff1a;哈夫曼码编/译码系统、递归替换问题、跳马问题与长整数运算&#xff0c;面向计算机专业本专科学生及正在准备课程设计或相关考试的开发者。每个专题均按“数据类型定义—算法设计—函数调用关…

作者头像 李华
网站建设 2026/10/6 6:15:23

智能体知识库实战:RAG流水线从切块到检索的工程指南

1. 为什么智能体需要「超体」知识库1.1 从「一本正经胡说八道」说起但凡折腾过智能体&#xff08;Agent&#xff09;的人&#xff0c;大概率都经历过这个场景&#xff1a;你问它一个公司内部流程问题&#xff0c;它张口就来&#xff0c;语气笃定、格式工整、逻辑自洽&#xff0…

作者头像 李华
网站建设 2026/10/6 6:14:37

ZYNQ7020 FPGA实现FOC电流环全流程实战

1. 为什么非得在ZYNQ7020的FPGA里硬啃FOC电流环&#xff1f;我第一次把FOC电流环塞进ZYNQ7020的PL端时&#xff0c;手边只有一块黑金AX7020开发板、三相逆变桥模块和一台PMSM电机。当时脑子里想的是&#xff1a;STM32跑FOC已经很稳了&#xff0c;为啥还要费劲在FPGA里重写&…

作者头像 李华
网站建设 2026/10/6 6:14:23

D455+VINS-Fusion+Octomap实时三维感知闭环构建指南

1. 这不是“拼凑三个工具”&#xff0c;而是构建一个可落地的实时三维感知闭环你在网上搜“D455VINS-FusionOctomap”&#xff0c;十有八九会看到一堆零散的ROS教程、GitHub issue截图、还有人抱怨“跑不通”“地图飘”“点云炸开”。但我要说句实话&#xff1a;这套组合从来就…

作者头像 李华