nvflash

nvflash 是NVIDIA显卡底层的固件闪存工具,直接与显卡上的 EEPROM (电可擦除可编程只读存储器) 通信。

nvflash 并不通过操作系统的驱动层(如 NVIDIA Driver)来读写数据,而是通过 PCIe总线 直接访问GPU的配置空间:

  • SPI总线通讯 : GPU芯片内部集成了一个SPI控制器,它连接着主板上的BIOS芯片。 nvflash 发送指令给GPU,命令GPU代理写入BIOS芯片

  • 跳过保护机制 : nvflash 能够通过特定命令(如 --protectoff )来解除芯片到写保护,或者通过强制参数( -6 )忽略SSID和Device ID的不匹配

  • 内存镜像映射 : 在刷写过程中, nvflash 会将ROM文件载入内存,进行校验(checksum)计算,确认无误后再按块(block)写入EEPROM

我之所以需要使用 nvflash 是因为我在 Dell T5820 GPU异常排查 时发现我购买的二手 Dell Precision T5820 工作站 无法使用数据中心的GPU运算卡,很有可能是因为T5820工作站不支持 reBAR (虽然2017年之后很多兼容机都已经支持),导致只能使用面向工作站的显卡而不支持面向服务器的GOU计算卡(需要申请巨大的BAR,如16GB或32GB)。

为了能够验证或者说解决 Dell Precision T5820 工作站 上使用 NVIDIA Tesla A2 GPU运算卡 启动问题,我尝试调整 A2 的gpu模式,调整为 graphics 模式来使用传统的 "Small BAR"。

警告

在使用 nvflash 之前,必须首先备份

下载nvflash

TechPowerUP提供了NVIDIA NVFlash下载

  • 通过解压缩并复制进行安装:

安装nvflash
# 创建临时目录
mkdir nvflash_work && cd nvflash_work

# 将下载的nvflash_5.867_linux.zip放在当前目录
unzip nvflash_5.867_linux.zip

# 解压缩后,当前目录下有多个不同架构的执行文件目录 aarch64 ppc64 x64 x86
chmod +x x64/nvflash

我在使用前先用 nvidia-smi 查看一下当前 NVIDIA Tesla A2 GPU运算卡 的工作模式: 当前是 Compute 模式

可以看到当前是Compute模式
Wed Apr 15 14:18:15 2026       
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 590.48.01              Driver Version: 590.48.01      CUDA Version: 13.1     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA A2                      Off |   00000000:01:00.0 Off |                    0 |
|  0%   37C    P8              8W /   60W |       0MiB /  15356MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+

使用准备

在使用 nvflash 之前需要先禁止NVIDIA内核模块(关键)

禁止驱动
sudo modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia

这里可能有模块无法移出,需要查看原因,例如我遇到:

移除模块报错
modprobe: FATAL: Module nvidia_uvm is in use.

原因是移除命令对模块的顺序是有依赖关系的,通过 lsmod | grep nvidia_uvm 可以看到 nvidia_uvm 似乎已经没有依赖使用它的模块

显示nvidia_uvm的依赖
nvidia_uvm           2076672  2
nvidia              99549184  12 nvidia_uvm

这确实是一个麻烦,没法移除模块?

由于可以看到 nvidia_uvm 还有 2 个引用,但是不是模块依赖,这表明是用户态进程在使用

所以要使用 lsof 来检查

检查哪个用户进程在使用nvidia模块
sudo lsof /dev/nvidia*

输出如下,显示有一个 dcgm-exporter 进程在使用nvidia设备:

dcgm-exporter 进程在使用nvidia设备
COMMAND    PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
dcgm-expo 1423 root  mem    CHR 195,255           788 /dev/nvidiactl
dcgm-expo 1423 root   12u   CHR 195,255      0t0  788 /dev/nvidiactl
dcgm-expo 1423 root   13u   CHR   195,0      0t0  789 /dev/nvidia0
dcgm-expo 1423 root   14u   CHR   509,0      0t0  790 /dev/nvidia-uvm
dcgm-expo 1423 root   15u   CHR   195,0      0t0  789 /dev/nvidia0
dcgm-expo 1423 root   16u   CHR   195,0      0t0  789 /dev/nvidia0
dcgm-expo 1423 root   17u   CHR   195,0      0t0  789 /dev/nvidia0
dcgm-expo 1423 root   19u   CHR 195,255      0t0  788 /dev/nvidiactl
dcgm-expo 1423 root   20u   CHR   195,0      0t0  789 /dev/nvidia0
dcgm-expo 1423 root   21u   CHR   195,0      0t0  789 /dev/nvidia0

我是因为 在Docker中Ollama使用NVIDIA A2 GPU运行大模型 中包含了 dcgm-exporter ,所以停止容器来解决这个模块移除问题

使用

  • 首先列出所有NVIDIA显卡及索引

列出NVIDIA显卡
sudo ./nvflash --list

显示有一个设备:

列出NVIDIA显卡显示输出
NVIDIA Firmware Update Utility (Version 5.867.0)
Copyright (C) 1993-2024, NVIDIA Corporation. All rights reserved.

NVIDIA display adapters present in system:
<0> Graphics Device      (10DE,25B6,10DE,157E) S:00,B:01,D:00,F:00
  • 备份固件:

保存ROM
sudo ./nvflash -i 0 --save origin_a2.rom

报错:

保存ROM报错
NVIDIA Firmware Update Utility (Version 5.867.0)
Copyright (C) 1993-2024, NVIDIA Corporation. All rights reserved.


ERROR: A system restart might be required before running the utility.
 Nvflash CPU side error Code:2Error Message: Falcon In HALT or STOP state, abort uCode command issuing process.

奇怪,为何要求重启系统才能运行工具?

暂时屏蔽nvidia模块

  • 先配置 blacklist-nvidia.conf 配置屏蔽掉自动加载nvidia模块,以便运行 nvflash

配置 /etc/modprobe.d/blacklist-nvidia.conf
sudo bash -c 'cat <<EOF > /etc/modprobe.d/blacklist-nvidia.conf
# 彻底屏蔽 NVIDIA 驱动及其所有子模块
blacklist nvidia
blacklist nvidia_drm
blacklist nvidia_modeset
blacklist nvidia_uvm
blacklist nvidia_modeset
alias nvidia off
alias nvidia_drm off
alias nvidia_modeset off
alias nvidia_uvm off
EOF'
  • 更新内核initramfs映像: 很多现代发行版(如 Ubuntu 24.04/26.04)会将显卡驱动打包进 initramfs(引导阶段的微型根文件系统)。如果你不执行这一步,内核在系统正式挂载根目录之前,可能已经从 initramfs 里把驱动加载了。

更新initramfs
# 更新当前所有内核版本的 initramfs
sudo update-initramfs -u
  • 修改 GRUB 引导参数(双重保险): 为了防止某些服务(如 gdm 或 cuda 运行库)尝试按需加载模块,编辑 /etc/default/grub 修订 GRUB_CMDLINE_LINUX_DEFAULT 添加 rd.driver.blacklist=nvidia modprobe.blacklist=nvidia :

修订 /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash rd.driver.blacklist=nvidia modprobe.blacklist=nvidia"

然后执行 sudo update-grub 更新grub,然后重启操作系统并验证

重启操作系统进行检查
# 检查模块是否已加载(输出应为空)
lsmod | grep nvidia

# 检查显卡是否处于待命状态
sudo ./nvflash --list

重启以后检查确实已经没有任何 nvidia 模块加载,但是我发现报错依旧:

保存ROM 依然报错
NVIDIA Firmware Update Utility (Version 5.867.0)
Copyright (C) 1993-2024, NVIDIA Corporation. All rights reserved.


ERROR: A system restart might be required before running the utility.
 Nvflash CPU side error Code:2Error Message: Falcon In HALT or STOP state, abort uCode command issuing process.

更换主机

我怀疑是我的兼容主机主板的问题(根据gemini提示有可能是PCIe的休眠或电源模式导致A2的GPU核心休眠),所以我换到 HPE ProLiant DL380 Gen9服务器 上再次执行。果然,更换到标准服务上,使用这块数据中心计算卡 NVIDIA Tesla A2 GPU运算卡 就顺利了很多:

列出NVIDIA显卡
sudo ./nvflash --list

显示:

在DL380 gen9上看到的A2
NVIDIA Firmware Update Utility (Version 5.867.0)
Copyright (C) 1993-2024, NVIDIA Corporation. All rights reserved.

NVIDIA display adapters present in system:
<0> Graphics Device      (10DE,25B6,10DE,157E) S:00,B:0B,D:00,F:00

而且执行ROM备份也成功了:

保存A2的ROM
sudo ./nvflash -i 0 --save origin_a2.rom

输出显示

保存A2的ROM时显示输出
NVIDIA Firmware Update Utility (Version 5.867.0)
Copyright (C) 1993-2024, NVIDIA Corporation. All rights reserved.

Reading EEPROM (this operation may take up to 30 seconds)

Build GUID            : 274F6EC1722F486FB38C104BD52CD4A1  
Build Number          : 30517502
IFR Subsystem ID      : 10DE-157E
Subsystem Vendor ID   : 0x10DE
Subsystem ID          : 0x157E
Version               : 94.07.5B.00.55
Image Hash            : N/A
Hierarchy ID          : Normal Board
Build Date            : 10/11/21
Modification Date     : 11/19/21
UEFI Version          : No Version Found or Out-dated (  )
UEFI Variant ID       : No Variant ID Found ( No Variant ID Found )
UEFI Signer(s)        : Unknown signer
XUSB-FW Version ID    : N/A
XUSB-FW Build Time    : N/A
InfoROM Version       : G179.0220.00.01
InfoROM Backup        : Present
License Placeholder   : Present
GPU Mode              : N/A
CEC OTA-signed Blob   : Present

这里输出信息有点奇怪:

  • UEFI Version: No Version Found or Out-dated (  ) 显示没有找到版本,A2 的原厂固件里可能没有包含有效的 UEFI GOP 驱动。

  • GPU Mode : N/A 实际上表明A2不支持GPU模式切换(见下文尝试切换失败)

  • 在尝试切换图形模式之前,我先检查一下A2的BAR size,执行 lspci -vvv -s 0b:00.0 查看A2卡详情:

执行 lspci -vvv -s 0b:00.0 查看A2卡详情
0b:00.0 3D controller: NVIDIA Corporation GA107GL [A2 / A16] (rev a1)
	Subsystem: NVIDIA Corporation GA107GL [A2 / A16]
	Physical Slot: 2
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx+
	Latency: 0, Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 16
	IOMMU group: 59
	Region 0: Memory at 93000000 (32-bit, non-prefetchable) [size=16M]
	Region 1: Memory at 39000000000 (64-bit, prefetchable) [size=16G]
	Region 3: Memory at 39c20000000 (64-bit, prefetchable) [size=32M]
	Capabilities: <access denied>
	Kernel driver in use: nouveau
	Kernel modules: nvidiafb, nouveau

可以看到BAR size是16G

  • 尝试切换graphics模式:

切换graphics模式
sudo ./nvflash -i 0 --gpumode graphics

输出显示:

切换graphics模式
NVIDIA Firmware Update Utility (Version 5.867.0)
Copyright (C) 1993-2024, NVIDIA Corporation. All rights reserved.


WARNING: This operation updates the firmware on the board and could make
         the device unusable if your host system lacks the necessary support.

Are you sure you want to continue?
Press 'y' to confirm (any other key to abort): 
y
Specifed GPU Mode "physical_display_enabled_256MB_bar1"

Graphics Device      (10DE,25B6,10DE,157E) S:00,B:0B,D:00,F:00

Specified GPU mode not supported on this device 0x25B6.

这里输入 y 执行,但是发现 NVIDIA Tesla A2 GPU运算卡 不支持graphics模式

gemini建议我使用 GOPUpd 来处理备份出来的 origin_a2.rom ,注入针对NVIDIA Ampere 架构的 GOP模块,这样就能为 NVIDIA Tesla A2 GPU运算卡 添加亮机的能力。

不过,我考虑到A2不会用在 Dell Precision T5820 工作站 上,我准备还是采用 AMD Radeon Instinct MI50 来进行这个GOP注入和BAR size修订。

参考

  • 本文实践主要在gemini指导下完成,原理部分摘自gemini