通过 GitHub 在 RTX 3080 VBIOS 上启用 Resizable Bar

Hacker News Top 工具

摘要

一份详细的指南和一组脚本,用于通过使用 nvflash 在 Linux 下刷写修改后的 VBIOS 来在 ASUS TUF RTX 3080 上启用 Resizable BAR,涵盖过程及恢复步骤。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/05/20 11:26

danindiana/rtx3080-rebar-vbios

来源:https://github.com/danindiana/rtx3080-rebar-vbios

RTX 3080 ReBAR VBIOS 刷写 —— Linux

在 Linux 环境下,为 ASUS TUF-RTX3080-O10G-GAMING 启用 Resizable BAR(8 GB BAR1),
无需 Windows、无需图形界面刷写工具,且不会变砖。

目录


背景

本仓库记录了在包含 RTX 5080 的双 GPU 系统上,为 ASUS TUF RTX 3080 10 GB 显卡启用 Resizable BAR 所进行的多次 Linux VBIOS 刷写尝试。RTX 5080 开箱即支持 ReBAR;而 3080 则不支持,因为其出厂 VBIOS 缺少 ReBAR 功能位。ASUS 以 Windows .exe 自安装程序形式提供 VBIOS 更新。本项目从安装程序中提取 ROM,并通过 Linux 版本的 nvflash 直接刷写,处理了在运行中的 X11 桌面环境下执行此操作且无备用恢复机器的所有复杂情况。

最终结果: VBIOS 从 94.02.42.40.65 (AS03) 升级到 94.02.42.40.66 (AS02),刷写退出码 0,需要重启以扩展 BAR1。


系统

组件详情
机器worlock
操作系统Xubuntu 22.04.5 LTS, Linux 6.8.12
主板ASRock X570 Taichi
CPUAMD Ryzen 9 5950X (32 线程)
内存128 GB DDR4
GPU 0RTX 5080 — PCIe 0E:00.0 — 16 GB — ReBAR 已启用 (对照)
GPU 1RTX 3080 — PCIe 0F:00.0 — 10 GB GDDR6X — ReBAR 目标
3080 子系统10DE:2206 / 1043:87B0 (TUF-RTX3080-O10G-GAMING)
显示连接到 GPU 1 (RTX 3080, Disp.A: On)
驱动NVIDIA 580.142 / CUDA 13.0
显示管理器LightDM (Xfce 默认)
推理框架Ollama — 双 GPU, CUDA_VISIBLE_DEVICES=0,1
nvflash5.867.0 (Linux x64 二进制)
目标 ROM94.02.42.40.AS02.rom (V6 包, 2023-10-18)

什么是 Resizable BAR,为什么重要?

PCIe 设备通过称为基址寄存器(BAR)的固定大小窗口向 CPU 暴露其内存。GPU BAR1 是 CPU 可直接读写 VRAM 的窗口。传统上,BIOS 固件会以固定 256 MiB 分配此窗口,无论 GPU 实际拥有多少 VRAM——这是 32 位地址空间限制的遗留问题。

Resizable BAR(也被市场营销称为 AMD Smart Access Memory / SAM)是一种 PCIe 特性,允许 BIOS 协商一个与 GPU 全部 VRAM 大小相同的 BAR1 窗口。在 10 GB RTX 3080 上,有效的 ReBAR 实现将 BAR1 从 256 MiB 扩展到 8192 MiB。

为什么是 8192 MiB,而不是 10240 MiB?

PCIe BAR 大小必须为 2 的幂。8 GiB 是能容纳在 10 GB 内的最大 2 的幂,因此 BIOS 会这样分配。剩余的约 2 GB VRAM 仍可由 GPU 内部访问;只有 CPU 可见的窗口受 BAR 限制。

对多 GPU 推理(Ollama)性能的影响

当 Ollama 在两个 GPU(RTX 5080 + RTX 3080)上加载模型时,运行时可能需要跨 PCIe 结构移动激活值、KV 缓存条目和层状态。ReBAR 将 CPU 可寻址窗口从 256 MiB 扩展到 8192 MiB,从而减少大传输的重新映射压力。这不等同于 CUDA 点对点访问,后者是一个独立的运行时能力,受拓扑、NVLink/PCIe 连接和驱动程序协商控制:

cudaDeviceCanAccessPeer(&canAccess, deviceA, deviceB);

ReBAR 改善了内存映射情况。它本身并不能保证 CUDA P2P。


前置条件

主板 BIOS(先执行此步骤)

在进行任何 VBIOS 刷写之前,必须激活以下设置:

  1. Above 4G Decoding → 启用 (ASRock X570 Taichi: Advanced → AMD CBS → NBIO Common Options → SMU Common Options)
  2. Re-Size BAR Support → 启用 (相同子菜单;也可能显示为 “SAM” 或 “Smart Access Memory”)
  3. CSM(Compatibility Support Module) → 禁用 (Boot → CSM → Disabled — ReBAR 是 UEFI 功能;CSM 会静默破坏它)

确认 5080(原生支持 ReBAR)已显示大 BAR1,以验证这些设置已生效:

sudo lspci -vvv -s 0e:00.0 | grep -A5 "Resizable BAR"
# 期望输出:BAR 1: supported: 64MB 128MB ... 16GB

内核参数

# 检查 pci=realloc 是否启用
cat /proc/cmdline | grep -o 'pci=realloc'
# 如果缺少则添加(编辑 /etc/default/grub):
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pci=realloc"
sudo update-grub
sudo reboot

所需工具

sudo apt install p7zip-full expect
  • 需要 expect,因为 nvflash 直接打开 /dev/console 进行确认提示,并且不会响应管道输入的 yes——必须使用伪 TTY。

脚本

脚本用途运行身份
preflight-check.sh只读前提检查。可随时安全运行。确认 nvflash、ROM、UEFI 模式、当前 BAR1 状态。用户
vbios-preflight.sh停止服务、卸载驱动、备份 VBIOS。终止 X 会话。root(在 TTY 下)
rebar-enable.sh完整的端到端刷写:停止服务 → 卸载 → 备份 → 刷写 → 重新加载 → 重启 X。root
vbios-verify.sh重启后验证。检查 VBIOS 版本、BAR1 大小、PCIe 能力寄存器、GPU 清单。用户

快速开始(如果前置条件满足)

# 1. 理智检查(只读,安全)
bash ~/vbios-work/preflight-check.sh

# 2. 运行刷写(会终止 X——桌面将变黑,然后恢复)
sudo ~/vbios-work/rebar-enable.sh

# 3. 重启
sudo reboot

# 4. 验证
bash ~/vbios-work/vbios-verify.sh

刷写工作原理

rebar-enable.sh 脚本在一次运行中编排整个刷写过程,设计为从 X 终端启动,即使它会在中途终止 X(通过 systemctl stop lightdm)。该脚本几乎是一个系统服务——一旦 LightDM 关闭,脚本将继续在后台作为启动它的 shell 的子进程运行。

逐步流程

[0] 停止所有 GPU 消费者
    ├── ollama.service (systemctl stop)
    ├── gpu-watchdog.service (stop + pkill -9, 有 Restart=always)
    └── nvidia-persistenced (先 MASK,然后 stop——mask 阻止自动重启)
[1] 停止 LightDM ← X 会话在此结束;终端窗口关闭(等待 4 秒让 Xorg 完全退出)
[2] 按依赖顺序卸载 NVIDIA 内核模块:
    nvidia_uvm → nvidia_drm → nvidia_modeset → nvidia
[3] nvflash --list (确认 GPU 1 可见,无需驱动)
[4] 备份当前 VBIOS (若 3080-backup-pre-rebar.rom 已存在则跳过)
    nvflash -i 1 --save backup.rom
[5] ROM 兼容性检查 (nvflash --check; 无论结果如何继续)
[5b] 关闭写保护 (nvflash --protectoff; expect 驱动)
[6] 刷写 ← 约 30 秒,EEPROM 写入
    nvflash -i 1 94.02.42.40.AS02.rom (expect 通过伪 TTY 驱动 y/n 确认)
[7] 回读验证 (nvflash --save /tmp/verify.rom; 检查非空)
[8] 重新加载 NVIDIA 模块 (nvidia → nvidia_modeset → nvidia_drm → nvidia_uvm)
[9] 恢复服务 (取消 mask + 启动 nvidia-persistenced, gpu-watchdog)
[10] 重启 LightDM ← 桌面恢复
[11] 报告 成功/失败 到 flash-session.log

参见 diagram 03 获取完整的带注释流程图。


ROM 选择

ASUS V6 包(2023-10-18, RTX3080_V6.exe, 15 MB)包含四个 ROM 文件。只有两个对 TUF-RTX3080-10G-GAMING(子系统 1043:87B0)有效:

ROM子系统版本对应显卡备注
AS021043:87B094.02.42.40.66TUF-RTX3080使用此版本。更新构建。
AS031043:87B094.02.42.40.65TUF-RTX3080有效的备用版本,较旧构建。
AS081043:87EBTURBO-RTX3080错误的显卡。不要刷写。
AS091043:87EBTURBO-RTX3080错误的显卡。不要刷写。

重要提示: 显示的小数后缀和 ASUS ASxx 编号在 ROM 集合中并非全局单调递增。

对于此特定 1043:87B0 TUF PCB,AS02 显示为 .66,AS03 显示为 .65。 AS02 是首选的 V6 目标,而 AS03 是有效的备用——但此结论来自 ROM 元数据和包比较表,而非假设 .66 > .65AS03 > AS02

在整个包中,AS08/AS09 的 AS 编号更高,但属于 Turbo 1043:87EB 分支,不得刷写到 TUF 87B0 显卡。

ROM 选择不变规则

不要相信显示的后缀版本。 不要相信 AS 系列编号顺序。 不要相信 ROM 文件名或包名。

只相信:

  • 子系统 ID:必须为 1043:87B0
  • 功率目标:必须为 340 W,而非 320 W
  • 加速频率:必须为 1785 MHz,而非 1710 MHz
  • nvflash --check:必须报告无子系统不匹配

安全的比较器不是 .65.66,也不是 AS02AS03。 安全的比较器是:

subsystem + board family + power target + boost clock + nvflash check

参见 diagram 05 获取完整的决策树。


经验教训——最初哪里出错了

三次早期的刷写尝试静默失败。以下是发生的情况及原因。

根本原因:Linux 上使用了仅限 Windows 的 nvflash 标志

刷写脚本最初使用了:

nvflash -i 1 --force-subsystem-id --force-board-id rom.rom

这些标志在 Linux 版本的 nvflash 5.867 中不存在。当二进制文件遇到未知标志时,它会打印 Command format not recognized 并进入交互菜单模式,而不是中止。expect 脚本本是为处理直接刷写提示而编写的,但现在却导航到了意外的交互菜单。它以退出码 5 退出(nvflash 交互式兼容性检查失败码)。EEPROM 确实被写入了——但是通过交互路径,结果刷写了 AS03(.65),而不是预期的 AS02(.66)。

诊断方法:

strings ~/vbios-work/x64/nvflash | grep force
# 输出:--forcesub, --forceboard — 但这些也会失败
# Linux 二进制文件根本没有 Windows 强制标志的等价物(用于相同子系统的 ROM),
# 因为它们不需要:nvflash 接受匹配的 ROM 而无需任何强制标志

Linux 上的正确调用:

nvflash -i 1
# 就是这样。没有强制标志。如果子系统匹配,二进制文件会提示 y/n。

为什么 nvidia-persistenced 必须被 mask,而不仅仅是停止

nvidia-persistenced 会保持对每个 NVIDIA 设备文件(/dev/nvidia0, /dev/nvidia1, /dev/nvidiactl, /dev/nvidia-modeset)的文件描述符打开,即使没有 GPU 工作负载在运行。如果其单元文件有 Restart=always,则不能简单地用 systemctl stop 停止。解决方案是先 mask 该单元,防止 systemd 重启它,然后停止。刷写后,取消 mask 并重启。

systemctl mask nvidia-persistenced
systemctl stop nvidia-persistenced
# ... 刷写 ...
systemctl unmask nvidia-persistenced
systemctl start nvidia-persistenced

为什么 gpu-watchdog 需要 pkill -9

gpu-watchdog.service(一个热监控守护进程)也有 Restart=always。简单的 systemctl stop 发送 SIGTERM,systemd 会立即在停止完成前重启它。脚本使用 systemctl stop 后跟 pkill -9 -f gpu_thermal.watchdog 来在 systemd 响应前终止进程,然后等待单元达到 inactive 状态。

为什么需要 expect(而不是 yes | nvflash

nvflash 直接打开 /dev/console 进行确认提示,绕过 stdin。管道输入的 yes 无效。expect 生成一个伪 TTY,nvflash 将其视为真实控制台,从而允许 y 响应到达二进制文件。


刷写结果

刷写于 2026-05-17 上午 11:41 CDT 执行。

刷写前 VBIOS:   94.02.42.40.65 (AS03 — 通过交互刷写事故到达)
刷写后 VBIOS:   94.02.42.40.66 (AS02 — 干净的直刷,退出码 0)
子系统:         1043:87B0 (正确 — TUF-RTX3080-O10G-GAMING)
刷写持续时间:   ~40 秒

刷写后立即进行的 nvflash 回读取认了 94.02.42.40.66,构建 GUID 为 36762E5D66904B30A099C58D53966BF5,且 IFR Subsystem ID: 1043-87B0

刷写后立即的 BAR1 状态(重启前):

BAR1 Memory Usage
Total           : 256 MiB   ← 预期;UEFI 重新分配将在重启时发生
Used            : 19 MiB
Free            : 237 MiB
BAR 1: current size: 256MB, supported: 64MB 128MB 256MB

需要重启才能使 UEFI 固件读取新 VBIOS 的 ReBAR 能力并分配扩展的 BAR1 窗口。

重启后 BAR1 验证

重启后,固件重新读取更新的 VBIOS 并分配更大的 BAR1 窗口。重启前,刷写后立即(已确认如上):

BAR1 Memory Usage
Total           : 256 MiB
Used            : 19 MiB
Free            : 237 MiB

重启后(预期):

$ nvidia-smi -q -i 1 | grep -A3 "BAR1 Memory Usage"
BAR1 Memory Usage
Total           : 8192 MiB
Used            : MiB
Free            : MiB
$ sudo lspci -vvv -s 0f:00.0 | grep -A5 "Resizable BAR"
BAR 1: current size: 8192MB, supported: 64MB 128MB 256MB ... 8192MB

同时记录两者的捕获命令:

{ echo "=== nvidia-smi BAR1 ==="
nvidia-smi -q -i 1 | sed -n '/BAR1 Memory Usage/,+3p'
echo
echo "=== lspci Resizable BAR ==="
sudo lspci -vvv -s 0f:00.0 | grep -A8 "Resizable BAR"
} | tee post-reboot-rebar-verification.txt

一旦重启完成,请用实际输出更新上面的 占位符。


刷写后步骤

# 1. 重启
sudo reboot
# 2. 重启后,验证 BAR1 已扩展
nvidia-smi -q -i 1 | grep -A3 "BAR1"
# 预期:
# Total           : 8192 MiB
# Used            : 0 MiB
# Free            : 8192 MiB
sudo lspci -vvv -s 0f:00.0 | grep -A5 "Resizable BAR"
# 预期:BAR 1: current size: 8192MB, supported: 64MB 128MB ... 8192MB
# 3. 使用 vbios-verify.sh 验证
bash ~/vbios-work/vbios-verify.sh
# 4. (可选) 更新 Ollama 服务以进行 ReBAR 后调优
sudo tee /etc/systemd/system/ollama.service.d/override.conf <<'EOF'
[Service]
Environment="CUDA_VISIBLE_DEVICES=0,1"
Environment="OLLAMA_MAX_LOADED_MODELS=2"
Environment="OLLAMA_GPU_OVERHEAD=0"
EOF
sudo systemctl daemon-reload && sudo systemctl restart ollama

恢复方案

如果 RTX 3080 在刷写后无法 POST:

  1. 关闭电源;仅重新插入 RTX 5080;单独用其启动(将显示器连接到 5080)。
  2. 在系统运行状态下重新安装 RTX 3080——它将作为无头设备出现在 PCIe 总线上。
  3. 使用备份 ROM 重新刷写:
sudo ~/vbios-work/x64/nvflash -i 1 ~/vbios-work/3080-backup-pre-rebar.rom
  1. 如果 nvflash 无法识别显卡:尝试使用 --bulldoze(最后手段,跳过所有检查)。
  2. 备份是在第一次刷写尝试之前保存的,包含原始出厂 VBIOS。其 SHA256 与其一同记录。

图表

所有图表位于 diagrams/ 文件夹中,包含 .dot 源文件、.png(150 dpi)和 .svg(可缩放)。使用 Graphviz 2.43.0 生成。

01 — 系统拓扑

双 GPU 系统概览:PCIe 拓扑、刷写前后的 BAR1 状态、操作系统/驱动栈以及 Ollama 与两个 GPU 的关系。

系统拓扑

02 — ReBAR 架构

BAR1 扩展的工作原理:CPU 地址空间、PCIe 结构、BAR 协商以及刷写前后 VRAM 可见性的差异。包括所有前置条件的完整列表。

ReBAR 架构

03 — 刷写工作流

rebar-enable.sh 的完整带注释流程图——每一步、每个决策点、中止路径以及重启后验证路径。

刷写工作流

04 — 服务依赖

相似文章

RTX 50系列的外部时钟生成技术

Hacker News Top

来自Xtreme Systems的超频玩家针对RTX 5090开发了一种外部时钟生成技术,通过使用Elmor External Clock Board(ECB),绕过了Nvidia在软件层面对显存和交叉开关时钟频率的限制。该方法目前仍在完善中,通过硬件级信号注入将GPU时钟提升至出厂限制以上,在基准测试中取得了显著的性能提升。

用于 Linux 的 Asus ZenVision 盖板 OLED 逆向工程用户空间驱动

Hacker News Top

这是一个针对 ASUS ZenVision 盖板 OLED 屏幕的逆向工程开源 Linux 用户空间驱动,允许用户在这块 256×64 的面板上显示图片和动画——而 ASUS 官方仅支持 Windows 平台。USB 协议通过 Ghidra 对 MyASUS 应用进行逆向分析后还原。