通过 GitHub 在 RTX 3080 VBIOS 上启用 Resizable Bar
摘要
一份详细的指南和一组脚本,用于通过使用 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、无需图形界面刷写工具,且不会变砖。
目录
- 背景
- 系统
- 什么是 Resizable BAR,为什么重要?
- 前置条件
- 脚本
- 刷写工作原理
- ROM 选择
- 经验教训——最初哪里出错了
- 刷写结果
- 刷写后步骤
- 恢复方案
- 图表
- 文件清单
- 分析:ReBAR 加速模型
- 分析:BAR1 机制
背景
本仓库记录了在包含 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 |
| CPU | AMD Ryzen 9 5950X (32 线程) |
| 内存 | 128 GB DDR4 |
| GPU 0 | RTX 5080 — PCIe 0E:00.0 — 16 GB — ReBAR 已启用 (对照) |
| GPU 1 | RTX 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 |
| nvflash | 5.867.0 (Linux x64 二进制) |
| 目标 ROM | 94.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 刷写之前,必须激活以下设置:
- Above 4G Decoding → 启用 (ASRock X570 Taichi: Advanced → AMD CBS → NBIO Common Options → SMU Common Options)
- Re-Size BAR Support → 启用 (相同子菜单;也可能显示为 “SAM” 或 “Smart Access Memory”)
- 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 | 子系统 | 版本 | 对应显卡 | 备注 |
|---|---|---|---|---|
| AS02 | 1043:87B0 | 94.02.42.40.66 | TUF-RTX3080 | 使用此版本。更新构建。 |
| AS03 | 1043:87B0 | 94.02.42.40.65 | TUF-RTX3080 | 有效的备用版本,较旧构建。 |
| AS08 | 1043:87EB | — | TURBO-RTX3080 | 错误的显卡。不要刷写。 |
| AS09 | 1043:87EB | — | TURBO-RTX3080 | 错误的显卡。不要刷写。 |
重要提示: 显示的小数后缀和 ASUS
ASxx编号在 ROM 集合中并非全局单调递增。对于此特定
1043:87B0TUF PCB,AS02 显示为.66,AS03 显示为.65。 AS02 是首选的 V6 目标,而 AS03 是有效的备用——但此结论来自 ROM 元数据和包比较表,而非假设.66 > .65或AS03 > AS02。在整个包中,AS08/AS09 的 AS 编号更高,但属于 Turbo
1043:87EB分支,不得刷写到 TUF87B0显卡。
ROM 选择不变规则
不要相信显示的后缀版本。 不要相信 AS 系列编号顺序。 不要相信 ROM 文件名或包名。
只相信:
- 子系统 ID:必须为
1043:87B0- 功率目标:必须为
340 W,而非320 W- 加速频率:必须为
1785 MHz,而非1710 MHznvflash --check:必须报告无子系统不匹配安全的比较器不是
.65对.66,也不是AS02对AS03。 安全的比较器是: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:
- 关闭电源;仅重新插入 RTX 5080;单独用其启动(将显示器连接到 5080)。
- 在系统运行状态下重新安装 RTX 3080——它将作为无头设备出现在 PCIe 总线上。
- 使用备份 ROM 重新刷写:
sudo ~/vbios-work/x64/nvflash -i 1 ~/vbios-work/3080-backup-pre-rebar.rom
- 如果 nvflash 无法识别显卡:尝试使用
--bulldoze(最后手段,跳过所有检查)。 - 备份是在第一次刷写尝试之前保存的,包含原始出厂 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 可见性的差异。包括所有前置条件的完整列表。
03 — 刷写工作流
rebar-enable.sh 的完整带注释流程图——每一步、每个决策点、中止路径以及重启后验证路径。
04 — 服务依赖
相似文章
RTX 50系列的外部时钟生成技术
来自Xtreme Systems的超频玩家针对RTX 5090开发了一种外部时钟生成技术,通过使用Elmor External Clock Board(ECB),绕过了Nvidia在软件层面对显存和交叉开关时钟频率的限制。该方法目前仍在完善中,通过硬件级信号注入将GPU时钟提升至出厂限制以上,在基准测试中取得了显著的性能提升。
我意外地用一条隐藏的PCIe 2.0 x4插槽削弱了4x RTX 3090 LLM设备的性能,修复后使Mistral 128B的性能翻倍。
用户发现,Threadripper 工作站主板上一处隐藏的 PCIe 2.0 x4 电气限制导致四块 RTX 3090 中的一块性能受限,从而影响了多 GPU 大语言模型推理性能。通过调整插槽布局并切换至张量分裂模式,Mistral 128B 的吞吐量从约 11 tok/s 翻倍至约 24.7 tok/s。
club-5060ti: 实用的RTX 5060 Ti本地LLM笔记与配置
一个GitHub仓库,提供在双RTX 5060 Ti 16GB显卡上使用vLLM和llama.cpp运行本地LLM(如Qwen3.6 27B)的实用配置和基准测试。
用于 Linux 的 Asus ZenVision 盖板 OLED 逆向工程用户空间驱动
这是一个针对 ASUS ZenVision 盖板 OLED 屏幕的逆向工程开源 Linux 用户空间驱动,允许用户在这块 256×64 的面板上显示图片和动画——而 ASUS 官方仅支持 Windows 平台。USB 协议通过 Ghidra 对 MyASUS 应用进行逆向分析后还原。
Project Blackwell:最终会成功——让RTX Pro 6000在Dell R730上以650K上下文运行
一名开发者记录了为在旧款戴尔PowerEdge R730服务器上运行NVIDIA RTX Pro 6000 Blackwell GPU所需进行的大量硬件和固件破解工作,从而实现了650K上下文长度的本地AI推理。