ubuntu昇腾310P驱动安装手册
昇腾310P(A300-3010)驱动移植与安装实战:在内核7.0上从编译失败到10卡全识别
一句话背景:华为 2022 年发布的 A300-3010(Ascend 310P)驱动源码面向 4.19/5.x 内核,在 Ubuntu 26.04 + 内核 7.0 上直接安装会因大量 API 变更而编译失败。本文完整记录了将驱动源码移植到内核 7.0 并完成官方安装的全过程。
最终成果:10 张 Ascend 310P 全部被
npu-smi识别,Health 全 OK,驱动 23.0.0 + 固件 7.1.0.3.220 双向配套。适用读者:需要在新内核上部署昇腾 NPU、或对内核驱动移植感兴趣的开发者。
目录
引言
为什么写这篇文章
昇腾(Ascend)系列 NPU 在国产 AI 算力中占有重要地位。然而,华为官方驱动的更新节奏往往滞后于 Linux 内核的演进——2022 年发布的 A300-3010 驱动 23.0.0 源码基于 4.19/5.x 内核编写,当它遇上 Ubuntu 26.04 自带的内核 7.0 时,会因为大量内核 API 的删除与变更而无法编译。
网上关于"昇腾驱动装不上"的帖子不少,但大多停留在"换个旧内核"的权宜之计。本文记录的是另一条路:不降级内核,而是把驱动源码移植到 7.0 上编过,并且仍然使用华为官方安装器完成 ko 落盘、依赖注册和环境配置。
环境速览
| 项目 | 内容 |
|---|---|
| 操作系统 | Ubuntu 26.04 LTS |
| 内核 | 7.0.0-31-generic |
| 编译器 | gcc 15 |
| 硬件 | 10 × Huawei 19e5:d100(Ascend 310P),虚拟机直通 |
| 驱动包 | A300-3010-npu-driver_23.0.0_linux-x86_64.run |
| 固件包 | A300-3010-npu-firmware_7.1.0.3.220.run |
你将收获
读完本文,你将能够:
- 理解旧驱动源码在新内核上编译失败的三类根因;
- 掌握 30+ 处内核 API 迁移的具体做法(能力位、定时器、页表、GUP、MSI 等);
- 学会与官方安装器配合——把补丁替换进它的 payload,而非绕过它;
- 获得一份可直接复制执行的安装命令集(全为官方命令)和踩坑对照表。
第一部分 安装操作(官方流程)
本章的命令全部来自华为官方安装包与官方文档,可直接复制执行。
核心原则:不绕过官方安装器。驱动源码的移植改动在第二部分说明,本章只涉及如何把移植后的源码交给官方安装器执行。
一、环境准备
# 1) 官方文档要求的依赖(Debian/Ubuntu 系)
apt-get update
apt-get install -y dkms gcc make linux-headers-$(uname -r) pciutils net-tools
# 2) 官方要求的存在用户/属组
groupadd -f HwHiAiUser
useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash 2>/dev/null || true
# 3) 确认物料齐全
ls -l /root/downloads/A300-3010-npu-driver_23.0.0_linux-x86_64.run
ls -l /root/downloads/A300-3010-npu-firmware_7.1.0.3.220.run
提示:若机器上还没有"已移植好的驱动源码",需要先恢复一份。源码本身就是驱动包内的
driver/kernel,移植改动见第九章。本机源码备份位于/root/docs/davinci_hiai-1.0-patched.tar.gz:tar -xzf /root/docs/davinci_hiai-1.0-patched.tar.gz -C /usr/src
二、安装驱动内核模块
官方 .run 每次执行都会重新解包并覆盖驱动源码目录,而包内源码编不过内核 7.0,所以必须先解包、用移植后的源码替换包内源码、再执行官方安装脚本。
# 1) 若之前有失败的安装,先把 /etc/ascend_install.info 去重
# (下面这条输出 >1 才需要处理;详见踩坑记录 #3)
grep -c "^Driver_Install_Path_Param=" /etc/ascend_install.info 2>/dev/null
# 需要处理时执行:
# cp /etc/ascend_install.info /etc/ascend_install.info.bak
# awk -F= '!seen[$1]++' /etc/ascend_install.info > /tmp/ai && mv /tmp/ai /etc/ascend_install.info
# 2) 驱动包只解包、不执行
cd /root/downloads
./A300-3010-npu-driver_23.0.0_linux-x86_64.run --noexec --nox11 --extract=/tmp/drvpayload
# 3) 重装场景:先解除已装目录的"不可变"属性(首次安装可跳过)
chattr -iR /usr/local/Ascend/driver/kernel 2>/dev/null
# 4) 用移植后的源码覆盖包内源码(首次安装这一条就够了)
rsync -a /usr/src/davinci_hiai-1.0/ /tmp/drvpayload/driver/kernel/
# 重装场景再多同步一份到安装器取样目录:
[ -d /usr/local/Ascend/driver/kernel ] && rsync -a /usr/src/davinci_hiai-1.0/ /usr/local/Ascend/driver/kernel/
# 5) 执行官方安装脚本
# install.sh 的前两个参数是 run 包名与包路径(脚本会截掉前两个字符得到绝对路径)
# 已装过会问 y/n,用管道自动回答
cd /tmp/drvpayload
printf 'y\ny\ny\n' | bash driver/script/install.sh "A300-3010-npu-driver_23.0.0_linux-x86_64.run" \
".//root/downloads" --full --install-for-all
成功标志:
[INFO]Driver package installed successfully! Reboot needed for installation/upgrade to take effect!
三、重启并确认驱动就绪
reboot # 必须重启:驱动在此过程中向芯片下发镜像、把芯片拉起来
# 机器起来后(约 1-2 分钟)执行以下检查
lsmod | grep -cE "^(drv_|ascend_|dbl_)" # 期望 20
npu-smi info # 期望 10 张卡,Health 均为 OK
dmesg | grep -c "Set device boot finish" # 期望 10(10 张芯片全部启动完成)
dkms status # 期望 davinci_hiai/1.0, <内核>, x86_64: installed
四、升级固件并复验
固件工具要求芯片在线,所以必须在驱动就绪(上一步重启完成)之后再执行:
cd /root/downloads
./A300-3010-npu-firmware_7.1.0.3.220.run --full
# 成功标志:The firmware of [10] chips are successfully upgraded.
reboot # 必须再重启一次,新固件才会在芯片上生效
# 最终复验
npu-smi info
/usr/local/Ascend/driver/tools/upgrade-tool --device_index -1 --system_version # 0-9 号设备都应能读到版本
dmesg | grep -c "Set device boot finish" # 10
grep -m1 '^Version=' /usr/local/Ascend/firmware/version.info # 7.1.0.3.220
完成判据:npu-smi info 出现 10 张 310、Health 全 OK;dkms status 为 installed;固件版本 7.1.0.3.220。
五、常见报错对照表
| 屏幕上的关键词 | 原因 | 怎么做 |
|---|---|---|
Operation not permitted + mkstemp ... /usr/local/Ascend/driver/kernel/... | 安装器给已装文件加了"不可变"属性(chattr +i) | 先执行 chattr -iR /usr/local/Ascend/driver/kernel 再覆盖 |
| 安装器长时间不动(>10 分钟无输出) | 已装过驱动时会问 [y/n],没有输入就卡住 | 用管道喂答案:printf 'y\ny\ny\n' | bash driver/script/install.sh ... |
Unrecognized parameters | 调 install.sh 少了前两个参数 | 前两参必须是 (run 包名, ".//绝对路径"),见第二章第 5 步 |
install path /usr/local not exists | /etc/ascend_install.info 被写重复了 | 按 key 去重该文件(见第二章第 1 步) |
None of the chips are up | 芯片还没启动(驱动没加载或需要复位) | 先整机 reboot;起来后 dmesg | grep -c "boot finish" 应为 10 |
Unknown symbol xxx(模块加载时报) | 驱动源码里还有新内核删掉的 API,属移植漏网 | 见第九章;用编译验证命令复现并补掉该符号 |
Wait boot mode from bios time out | 在下发固件的过程中卸载了驱动,卡停在异常态 | reboot 整机复位即可恢复(不要在驱动加载/下发固件时 rmmod) |
Dkms install failed / There has no xxx.ko | DKMS 编译失败 | 看编译日志 /var/lib/dkms/davinci_hiai/1.0/build/make.log 里第一条 error: |
dcmi module initialize failed | 用户态库读不到驱动(模块没加载 / 芯片没起来) | 确认 lsmod | grep -c drv_ 非 0,且 dmesg | grep -c "boot finish" 等于卡数 |
三条通用规则:
- 命令都要 root;
- 安装动作会写
/usr/local、/etc、/lib/modules、/usr/src,需在无沙箱/只读限制的环境执行;- 每一步可重复执行,失败修好后直接重跑该步。
第二部分 原理与移植实录
六、环境与物料
| 项目 | 内容 |
|---|---|
| 操作系统 | Ubuntu 26.04 LTS(resolute),apt 体系(无 yum/dnf) |
| 内核 | 7.0.0-31-generic(/usr/src/linux-headers-7.0.0-31-generic) |
| 编译器 | gcc 15(/usr/lib/gcc/x86_64-linux-gnu/15) |
| 硬件 | 10 × Huawei 19e5:d100(Ascend 310P),0000:00:0B.0 ~ 0000:00:14.0,虚拟机直通 |
| 驱动包 | A300-3010-npu-driver_23.0.0_linux-x86_64.run |
| 固件包 | A300-3010-npu-firmware_7.1.0.3.220.run |
| 驱动源码 | 随驱动包发布,安装时释放到 /usr/src/davinci_hiai-1.0(2022 年代码,面向 4.19/5.x 内核) |
| 用户/属组 | HwHiAiUser:HwHiAiUser(安装器强制要求) |
七、问题分析
7.1 现象
安装器(.run --full --install-for-all)在 DKMS 阶段失败:
[ERROR]Dkms install failed, details in : /var/log/ascend_seclog/ascend_install.log
[ERROR]Driver_ko_install failed, details in : /var/log/ascend_seclog/ascend_install.log
[INFO]Failed to install driver package, please retry after uninstall and reboot!
make.log 显示的是"旧驱动源码 × 新内核 API"的典型冲突:fatal error: linux/genhd.h: No such file、static assertion failed: "pointer type mismatch in container_of()"、too many arguments to function 'get_user_pages_remote'、'PROFILE_TASK_EXIT' undeclared 等。
7.2 根因(三条)
- API 代差:驱动源码基于 4.19/5.x 编写,内核 7.0 删改了大量接口(能力位结构、
del_timer、follow_pfn、hrtimer_init等)。 - 安装器会覆盖补丁源码:每次执行
.run都会重新解包,cp -rf覆盖/usr/local/Ascend/driver/kernel/,再由run_driver_dkms_install.sh拷贝到/usr/src/davinci_hiai-1.0。在源码树里改完直接重跑安装器,补丁必被抹掉。 - 状态残留:多次失败安装把
/etc/ascend_install.info写成重复键值块,安装器据此解析出"两条安装路径",直接报install path ... not exists;此外在驱动向卡下发镜像的过程中卸载模块,会使卡停在异常态(探针报Wait boot mode from bios time out)。
八、总体思路
整个排查与修复过程可以用下面这张流程图概括:
核心策略:先在源码树上把移植补丁编绿,再把补丁源码替换进官方安装包的 payload,最后仍由官方安装脚本完成 ko 落盘、依赖注册、环境配置——不绕过、不手工替代官方安装器的任何环节。
九、内核 API 移植改动清单
下表汇总了本次移植中处理的所有内核 API 变更:
| 类别 | 内核 7.0 的变化 | 移植做法 | 涉及位置 |
|---|---|---|---|
| 能力位 | kernel_cap_t 变为单个 64 位标量,CAP_FOR_EACH_U32 删除 | 以 CAP_VALID_MASK 做特性判断,改用 cap_issubset() 比较 | 6 个文件(ascend310/ascend910 container、dms_hotreset、uda_access、docker_query、urd_container) |
| 指针容器 | container_of() 新增类型断言,const struct file * 触发 pointer type mismatch | 改用 container_of_const()(老内核走带 uintptr_t 转换的分支) | davinci_intf_init.c |
| 事件通知 | PROFILE_TASK_EXIT / profile_event_register() 随 profile 子系统移除 | #if defined(PROFILE_TASK_EXIT) 条件编译,保留旧内核路径 | logic_cq.c、uda_access.c |
| 定时器 | del_timer/del_timer_sync → timer_delete_sync;from_timer 删除;hrtimer_init → hrtimer_setup | 逐处替换;hrtimer_setup 用版本分支保留老内核写法 | del_timer 7 处、from_timer 3 处、hrtimer_init 3 处 |
| 用户页(GUP) | get_user_pages_remote() 去掉 vmas 参数(6 参) | 采用 ≥5.9 的 6 参调用形式 | svm_mem_mng.c |
| 页表遍历 | follow_pfn() 删除;模块内 pte_offset_map() 依赖未导出的 __pte_offset_map | 封装 follow_pfnmap_start/end();改用 pte_offset_kernel() | 6 文件 7 处 + 2 文件 4 处 |
| PCIe / MSI | pci_enable/disable_pcie_error_reporting() 删除(AER 恒开);for_each_pci_msi_entry 删除 | 本地空实现替代;改用 msi_for_each_desc() + __msi_lock/unlock_descs() | devdrv_pci.c |
| 内存/页 | nth_page() 删除 | 展开为 pfn_to_page(page_to_pfn(p) + i) | tsdrv_osal_mm.c |
| 符号导出 | 对 static(本地)符号 EXPORT_SYMBOL 成为错误 | 无用的导出删除;确有外部用途的符号先改全局再导出 | dms_init.c、davinci_intf_init.c |
| 构建系统 | EXTRA_CFLAGS 失效;stdarg.h/stdbool.h 无 libc 头;内核符号不透明化 | 批量改 ccflags-y(48 个 Makefile/*.mk)、导出 HIAI_DKMS_DIR、补 gcc include 与 linux/stdarg.h | 构建层全量 |
| 其他 | class_create(THIS_MODULE,…)、netif_napi_add、PDE_DATA、`vm_flags | =、struct kernel_symbol` 不透明 | 按新签名改写或降级为兼容桩 |
9.1 移植补丁的编译验证(改源码后必做)
修改源码后,不要直接跑安装器,而是先在独立副本里编译验证。这样可以快速定位问题,避免每次都等安装器走完整个流程。
cp -a /usr/src/davinci_hiai-1.0 /tmp/buildcheck
cd /tmp/buildcheck
make all KERNEL_UNAME=$(uname -r) DAVINCI_HIAI_DKMS=y TARGET_PRODUCT=mini TARGET_CHIP_ID=hi1910 \
CUSTOM_OS_CCFLAGS="-I/usr/lib/gcc/x86_64-linux-gnu/15/include -Wno-error=missing-prototypes \
-Wno-error=implicit-function-declaration -Wno-error=maybe-uninitialized" 2>&1 | tee /tmp/buildcheck.log
grep -c "error:" /tmp/buildcheck.log # 期望 0
grep -o 'WARNING: modpost: "[^"]*" \[[^]]*\] undefined!' /tmp/buildcheck.log | sort -u # 期望空
关键经验:必须同时看 modpost 的 undefined 符号。构建参数里
KBUILD_MODPOST_WARN=1把"未定义符号"从错误降级为警告,编译能"全绿",但modprobe时会报Unknown symbol。本项目就先后补掉了hrtimer_init(改名hrtimer_setup)与一处被误放进#ifdef CFG_FEATURE_VFIO内的辅助函数。
十、验证结果
10.1 编译与安装
$ dkms status
davinci_hiai/1.0, 7.0.0-31-generic, x86_64: installed
$ find /lib/modules/7.0.0-31-generic/updates/dkms -name "*.ko.zst" | wc -l
22
10.2 运行状态(冷启动后)
npu-smi info(节选):
+-------------------------------+-----------------+------------------------------------------------------+
| NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page) |
| Chip Device | Bus-Id | AICore(%) Memory-Usage(MB) |
+===============================+=================+======================================================+
| 88 310 | OK | 12.8 68 0 / 969 |
| 0 0 | 0000:00:0B.0 | 0 577 / 7759 |
| 96 310 | OK | 12.8 62 0 / 969 |
| 0 1 | 0000:00:0C.0 | 0 575 / 7759 |
| ...(共 10 张:Chip 88/96/104/112/120/128/136/144/152/160,Device 0–9) |
其余实测数据:
$ dmesg | grep -c "Set device boot finish"
10
$ /usr/local/Ascend/driver/tools/upgrade-tool --device_index -1 --system_version
Get system version(23.0.0) succeed, deviceId(0..9)
10.3 版本配套
| 组件 | 版本 | 配套要求 | 结果 |
|---|---|---|---|
| 驱动 | 23.0.0 | 固件 [7.0.0, 7.1.99] | — |
| 固件 | 7.1.0.3.220 | 驱动 [23.0.rc3, 23.0.0] | ✅ 双向满足 |
| npu-smi | 23.0.0 | — | ✅ |
十一、踩坑记录与规避
| # | 坑 | 现象 | 规避 |
|---|---|---|---|
| 1 | .run 覆盖补丁源码 | 改完源码重跑安装器,补丁全部丢失,编译报 drv_log.h: No such file | --noexec --extract 解包 → 替换 payload/driver/kernel → 跑 install.sh |
| 2 | install.sh 参数格式 | 直接 bash install.sh --full 报 Unrecognized parameters | 前两参必须是 (run 包名, ".//绝对路径"),脚本会截掉前两个字符得到绝对路径 |
| 3 | install.info 重复写入 | 报 install path /usr/local/Ascend /usr/local not exists | 按 key 去重 /etc/ascend_install.info |
| 4 | modpost 未定义符号被降级 | 编译全绿,modprobe 报 Unknown symbol hrtimer_init | 构建后强制检查 undefined! 列表,要求为空 |
| 5 | 固件下发期间卸载模块 | 卡停在异常态,探针报 Wait boot mode from bios time out,upgrade-tool 报 None of the chips are up | 不要在驱动加载/下发镜像过程中 rmmod;异常后用整机重启恢复 |
| 6 | 沙箱/权限拦截 | 安装器写 /usr/local、/etc、/lib/modules 时被拦 | 安装动作需在无沙箱/特权环境执行 |
| 7 | 安装目录被加 immutable 属性 | 安装完成后,/usr/local/Ascend/driver/kernel 下 1600+ 文件被 chattr +i;再次覆盖时 rsync/cp 报 Operation not permitted | 覆盖前先 chattr -iR /usr/local/Ascend/driver/kernel(官方 install.sh:943 也是这么做的) |
| 8 | 重装时安装器交互等待 | 已装过驱动时会问 do you want to continue? [y/n],非交互环境下进程挂在管道读上(无任何日志输出) | 用管道喂答案:printf 'y\ny\ny\n' | bash driver/script/install.sh ...,或加 --quiet |
十二、功能取舍与风险
以下为内核 7.0 缺少对应能力而做出的有意取舍,不影响编译、加载与设备识别:
- 进程退出清理钩子缺失:
PROFILE_TASK_EXIT通知器(logic_cq的等待 TID 清理、uda的 NS 节点回收)在新内核不可用,已条件编译关闭。极端情况下若用户进程在等待中途被强杀,可能残留少量等待表项。 - PTE 读取无锁:
svmdrv由pte_offset_map()(模块不可用)改为pte_offset_kernel(),与旧驱动同样不持 PTE 锁。 - PCIe AER 开关变为空实现:新内核 AER 恒开,
pci_enable/disable_pcie_error_reporting()由本地空函数替代。 follow_pfn语义替换:follow_pfnmap_start/end()仅支持VM_IO|VM_PFNMAP映射,与原follow_pfn的适用面一致;逐页调用相比原实现略有开销。
十三、结论与交付物
本次移植的核心结论:
- 该驱动在内核 7.0 上的不兼容点全部属于 API 迁移类,无架构性阻塞;共处理 30+ 处、跨 40 余个文件(含 48 个构建文件)。
- 迁移成功的关键工程经验有三条:
- 用独立副本做编译验证并检查 modpost 未定义符号——这是发现
hrtimer_init等漏网之鱼的唯一可靠手段; - 不要与安装器的覆盖行为对抗,而要把补丁替换进它的 payload——这是避免补丁被反复抹掉的关键;
- 芯片类驱动必须用整机重启完成状态复位与固件生效——任何模块级别的卸载/重载都可能使卡停在异常态。
- 用独立副本做编译验证并检查 modpost 未定义符号——这是发现
交付物清单:
- 本手册:
/root/docs/昇腾310P驱动安装手册(含移植实录).md - 移植后的驱动源码:
/usr/src/davinci_hiai-1.0(与/usr/local/Ascend/driver/kernel同步) - 源码备份(供新机器恢复):
/root/docs/davinci_hiai-1.0-patched.tar.gz(3.1 MB) - 已安装内核模块:
/lib/modules/7.0.0-31-generic/updates/dkms/(22 个)
附录:装完之后怎么用
npu-smi info # 看卡的总体状态(型号/温度/功耗/显存/健康)
npu-smi info -t usages -i 0 # 看 0 号卡的利用率
watch -n 2 npu-smi info # 每 2 秒刷新
关键词标签:昇腾310P、Ascend NPU、A300-3010、驱动移植、内核7.0、Ubuntu 26.04、DKMS、npu-smi、华为昇腾、内核开发
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐


所有评论(0)