InfiniBand 专题【左扬精讲】—— InfiniBand HCA 固件升级:工具链、版本识别、固件烧录与验证
InfiniBand 专题【左扬精讲】—— InfiniBand HCA 固件升级:工具链、版本识别、固件烧录与验证
本系列前面十篇讲的都是"子网已经跑起来之后"的事——但没有一篇讲过这张卡最初是怎么被点亮的。子网管理器要遍历拓扑、分配 LID、编程转发表,前提是每一台 HCA 上的固件本身是活的、版本是对的。一张卡固件版本不对,它连 SMP 报文都应答不了,SM 就永远发现不到它——表现为"接了线、驱动装了、但这个节点在子网里根本不存在"。
本篇是 InfiniBand 专题【左扬精讲】系列的 第 14 篇,主题是HCA 固件升级:什么时候必须升、用哪三个工具升、怎么保证烧对了卡、以及怎么验证真的升成功了。全文按"为什么升 → 用什么升 → 怎么升 → 怎么验 → OEM 卡有什么不同"的顺序展开,工具能力与参数语义全部引自 NVIDIA 官方 MFT 文档。
本篇的核心命题只有一句:HCA 固件升级是一次"三段式"操作——采集身份、写入 flash、加载生效,三段各自有独立的失败模式,而绝大多数升级事故都发生在"写对了但没加载"或"加载了但没验"这两处。
开篇必读:课程口语转写里的十组高频误听,本文全部按真实标识符纠正
本篇素材来自一段英文课程的口语转写,转写引擎对专有名词与命令名的还原率很低。以下对照是全文可复现性的前提——照着转写稿敲命令一定敲不通:
| # | 转写稿里的说法 | 真实写法 | 说明 |
|---|---|---|---|
| 1 | "mlxfw manager" | mlxfwreset | 这是本篇最关键的一处纠正。mlxfwmanager 是另一个工具,职责是查询/更新固件镜像(见 FAQ Q15);烧录之后负责 reset 并加载新固件的是 mlxfwreset |
| 2 | "ib dev info" | ibv_devinfo | rdma-core 用户态库提供的设备信息查询工具 |
| 3 | "ib stat" | ibstat | infiniband-diags 包提供的端口状态查询工具 |
| 4 | "o fed" / "m l nxo fed" | MLNX_OFED | 驱动发行版名称;校验命令是 ofed_info |
| 5 | "e nvidia" / "invidia" | NVIDIA | 转写引擎把 NVIDIA 反复听成了两个不同的词 |
| 6 | "l spci" | lspci | PCI 设备枚举工具 |
| 7 | "MT four one two three"(当作 PSID 讲) | 4123 是 PCI Device ID,不是 PSID | 它出现在 /dev/mst/mt4123_pciconf0 路径里,来源是 ibv_devinfo 的 vendor_part_id。PSID 是另一串 16 字符,详见第八节 |
| 8 | "PS ID parameters set identification" | PSID = Parameter-Set IDentification | NVIDIA 固件下载页脚注给出的官方展开 |
| 9 | "mlx five o" 被当作 HCA 型号 | mlx5_0 是内核枚举出来的设备名 | 它由驱动加载顺序决定,不携带任何型号信息。型号要看 CA type 或 vendor_part_id,详见第六节 |
| 10 | "pseudo privileges" | root 权限(sudo) | mstflint README 原文:"Typically, you will need root privileges for hardware access" |
另外有一处表述需要收紧:转写稿说 "这个 PS ID 总是以 MT_ 开头"。这个说法对 NVIDIA 自家交付的板卡成立,对全部板卡不成立——MFT 的 PSID 文档明确要求 OEM 使用自己的厂商符号以保证唯一性,只有在不知道自己的厂商符号时才需要联系 NVIDIA FAE 索取。详见第八节与第十三节。
本篇核心术语:
HCA Host Channel Adapter 主机通道适配器 / Channel Adapter 通道适配器
NIC Network Interface Card 网络接口卡 / Fabric 织物 / VPI Virtual Protocol Interconnect
Firmware 固件 / Flash 闪存 / NVMEM 非易失存储器 / ROM Expansion ROM 扩展只读存储
Verbs verbs 软件动词 / GUID Global Unique Identifier 全局唯一标识
PCI Device ID PCI 设备标识 / OPN Ordering Part Number 订购件号
PSID Parameter-Set IDentification 参数集标识 / Vendor Symbol 厂商符号
Board ID 板卡标识 / Board Type Symbol 板型符号 / Board Version Symbol 板版本符号
Parameter Set Number 参数集编号 / VSD Vital System Data 关键系统数据
MFT Mellanox Firmware Tools 固件管理工具包 / MST Mellanox Tools 工具与服务
mst daemon MST 驱动服务 / MST device MST 设备节点
failsafe 容错烧录 / non-failsafe 非容错模式 / semaphore 信号量
Secure Host 安全主机 / HW access key 硬件访问密钥 / reset level 复位级别
OEM Original Equipment Manufacturer 原始设备制造商
本篇核心命令:
lspci -d 15b3: / ibv_devinfo / ofed_info -s / mst start / mst status
flint -d <device> -i <image> b / flint -d <device> query / mlxfwreset -d <device> reset -y / ibstat
本篇权威依据:
MFT 文档 flint – Firmware Burning Tool —— 五项功能、命令行语法、命令参数表、返回值定义、failsafe 说明
MFT 文档 Burning a Firmware Image —— 烧录命令行格式、PSID 匹配规则、--allow_psid_change
MFT 文档 mlxfwreset – Loading Firmware on 5th Generation Devices Tool —— 语法、reset level、加载提示语
MFT 文档 Assigning PSID —— PSID 16 字符字段结构、MT_0030000001 官方示例、OEM 厂商符号要求
MFT 文档 mlxfwmanager – Firmware Update and Query Tool —— 与 mlxfwreset 的职责边界
NVIDIA Firmware Downloads / Firmware Update Instructions —— 下载中心路径、mst 设备名格式、官方烧录示例
OpenFabrics Alliance Basic Commands —— ibv_devinfo 输出字段与 man page 选项
公开文档中的 ibv_devinfo / ibstat / flint query 实际输出样例(见文末参考资料)
InfiniBandHCA固件升级FirmwareMFTflintmstmlxfwresetmlxfwmanagerPSIDOPNvendor_part_idibv_devinfoibstatlspciofed_infoMLNX_OFEDConnectXfailsafeOEM 定制固件NVMEM
★ 学完这一篇你能掌握什么(渐进式路径:1→2→3→4 不可跳跃)
- 第 1 步 · 分清"固件"与"驱动"(第二节、第三节)
• What:HCA 是连接设备到 InfiniBand fabric 的网络接口卡,固件为它提供执行基础动作的指令;HCA 固件可以脱离 OFED 安装单独升级
• How:能判断当前场景是否真的需要升级——OFED 刚装完通常不需要升,只有版本失配、安装异常、版本有已知缺陷这三种情况才升
• Why:理解 "为什么固件不随内核自动升级"——它烧在设备侧的 NVMEM 里,与主机操作系统是两套独立的生命周期- 第 2 步 · 认全三个工具与 flint 的能力边界(第四节、第五节)
• What:三个主用工具 = mst 服务(定位设备)/ flint(烧录与查询)/ mlxfwreset(加载新固件);flint 官方文档列出五项功能
• How:能读懂 flint -d <device> -i <image> b 中三个要素各自的作用,并能说出 flint 的三个返回值 0 / 1 / 7 分别代表什么
• Why:理解 "为什么 flint 默认是容错烧录、而 -nofs 只在特定场景才用"——容错机制保证了任意时刻 flash 上都有一份有效镜像- 第 3 步 · 采集身份并对上号(第六节、第七节、第八节、第九节)
• What:必须记下四项信息 = hca_id / fw_ver / vendor_part_id / board_id;PSID 是 16 个 ASCII 字符,字段结构为 3+3+3+4+3
• How:能把 /dev/mst/mt4123_pciconf0 里的 4123 与 ibv_devinfo 的 vendor_part_id 对上;能在一台插多张 HCA 的机器上唯一定位要烧的那张
• Why:理解 "为什么 mlx5_0 不能用来判断型号"——它是内核枚举顺序的产物,同一台机器上换卡后名字不变而芯片不同- 第 4 步 · 会烧会验,并知道 OEM 卡的差异(第十节至第十四节)
• What:七步流程 = 确认型号 → 采集四项信息 → 定位 MST 设备 → 下载镜像 → flint 烧录 → mlxfwreset 加载 → 双证据验证
• How:能解释为什么烧完立刻 ibstat 看到的还是旧版本,以及 flint 结尾那句 "To load new FW run mlxfwreset or reboot machine" 的判读方法
• Why:理解 "为什么 OEM 定制固件必须走另一套流程"——板卡型号不同、PSID 由 OEM 自定义、获取渠道也不在 NVIDIA 公开下载中心★ 阅读前提 & 本篇不涉及的内容
- 前置知识:本系列第一篇《InfiniBand 架构简介:从五层模型到子网管理》中的 GUID 概念与设备角色;本系列第八篇《子网初始化:拓扑发现、LID 分配、路径计算与子网激活》中的 SMA 机制——固件不响应就是 SMA 不响应,这是本篇所有故障现象的共同根因;本系列第九篇《SM 监控与拓扑变化:选举、故障切换、扫描与重收敛》中的 ibstat 字段判读。本篇不重复解释这些内容
- 信息来源:本篇出现的全部工具名、命令行语法、参数语义、返回值定义、PSID 字段结构、下载中心导航路径与官方输出样例,均引自文末「参考资料」列出的 NVIDIA MFT 官方文档与 NVIDIA 固件下载页;本篇不含任何未经上述来源核实的工具行为描述
- 本篇不涉及:交换机固件升级(命令族相同但设备路径与流程细节不同)、BlueField DPU 的固件升级、OFED 驱动本身的版本升级流程、固件签名与 secure boot 的密钥体系、mstconfig 配置项的读写
📑 本节目录(按"为什么升 → 用什么升 → 怎么升 → 怎么验"的顺序)
- 一、开篇必读:十组误听与一处需要收紧的表述
- 二、HCA 的定位:硬件、固件与"升级到底在改什么"
- 三、什么时候该升、什么时候不该升:三种触发条件
- 四、工具全景:MFT 包与三个主用工具
- 五、flint 的能力边界:五项功能与它的安全约束
- 六、第一步:确认型号与 PCI Device ID
- 七、第二步:采集四项关键信息(ibv_devinfo 精读)
- 八、PSID 解码:16 个字符如何唯一定位一份固件配置
- 九、第三步:定位 MST 设备路径
- 十、第四步:下载固件镜像
- 十一、第五步与第六步:烧录(flint)与加载(mlxfwreset)
- 十二、第七步:验证——两条独立的证据链
- 十三、OEM 定制固件:为什么流程不同
- 十四、FAQ 高频问答(20 组)
- 十五、Roadmap 后续预告
一、开篇必读:十组误听与一处需要收紧的表述
本节已在开头的 note-block 中完整给出十组对照表,此处不重复,只讲为什么这张表必须放在最前面。
固件升级是本系列中唯一一个"命令敲错会直接损坏设备"的主题。本系列前面几篇的命令——ibstat、ibroute、smpquery——全部是只读查询,敲错了最坏结果是"命令报错";而 flint -d ... -i ... b 敲错设备号或镜像名,后果是把这张卡不该装的固件写进了它的 flash。
因此本篇的组织方式与其他各篇有一个刻意不同之处:先把所有标识符的"出处"讲清楚,再讲命令。第九节的 /dev/mst/ 设备路径、第八节的 PSID、第六节的 PCI Device ID,这三样东西在课程里都是一带而过的一句话,但它们恰恰是实际操作中最容易张冠李戴的地方。
本节关键记忆:1 个方法论
- 1 个方法论:固件升级的每一步都要能回答"这个值是从哪条命令的哪个字段读来的"。凡是说不清出处的值,都是事故的前兆
- 1 个最高频误听:mlxfwmanager ≠ mlxfwreset,前者管镜像,后者管加载
- 1 个最高频混淆:mlx5_0 是设备名不是型号;4123 是 PCI Device ID 不是 PSID
二、HCA 的定位:硬件、固件与"升级到底在改什么"
What — 课程给出的三个定义
课程对这条链路上每一个角色的定义都相当精确,逐条抄录如下:
- 通道适配器(Channel Adapter):一张把设备连接到 InfiniBand fabric 的网络接口卡(a network interface card that connects a device to an InfiniBand fabric)
- 主机通道适配器(HCA):为主机设备提供接口,并支持 InfiniBand 规范中定义的全部软件 verbs(provides an interface to a host device and supports all software verbs defined in the InfiniBand specification)
- 固件(Firmware):为 HCA 执行一组基础任务与功能提供所需的指令,课程给的唯一例子是:对一个收到的数据包执行某个动作(executing an action on an incoming packet)
这三个定义合起来划出了一条清晰的边界:硬件是接口,固件是接口后面那个"必须有东西在跑"的执行体。HCA 不是一块纯被动的高速 SerDes 收发器——它上面跑着固件,固件要在收到包之后做出判断并采取动作。
2.1 一个只有固件能回答的致命问题
Why — 固件不响应,在子网视角下等于这块卡不存在
把本系列的另一条结论接进来,整件事的严重性就出来了。本系列第八篇已经确认:子网中的每个被管理节点都必须有一个 SMA(Subnet Manager Agent),SM 通过它与该节点通信并配置它;缺少 SMA 的节点对 SM 而言就是不可见的。
那么问题来了:SMA 是主机操作系统上的软件,还是设备侧的固件的一部分?答案可以从本篇的升级流程反推出来——如果固件版本不对,设备连最基础的"收到包并做出动作"都做不到,那么它连最基本的 SMP 应答都发不出来。而 SMP 应答正是 SMA 存在的全部意义。
于是这条因果链是闭合的:
固件版本异常向上传导的因果链
┌──────────────────────────────────────────────────────────────┐
│ 根因:HCA 固件版本错误 / 损坏 / 与驱动不匹配 │
└───────────────────────────┬──────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ 设备侧:固件无法完成"对收到的包执行动作"这一基础功能 │
│ 表现:ibv_devinfo 可能仍能读到静态信息(GUID / PSID 在 flash)│
│ 但端口无法进入 Active,SMP 不应答 │
└───────────────────────────┬──────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ 主机侧:SMA 拿不到 SMP 响应 │
│ 表现:ibv_devinfo 端口 state 停在 PORT_ACTIVE 之前 │
└───────────────────────────┬──────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ 管理面:SM 的定向路由发现走到这个节点时收不到响应 │
│ 表现:该节点不会出现在 SM 的节点清单里 → 不分配 LID │
│ (本系列第八节:LID 分配必须覆盖清单里的每一个受管理节点) │
└───────────────────────────┬──────────────────────────────────┘
▼
┌──────────────────────────────────────────────────────────────┐
│ 业务面:ibstat 显示该端口 Base lid = 65535,State = Down │
│ 运维直觉:「网线插了、驱动装了、ibv_devinfo 也认得, │
│ 为什么这个节点就是不通?」 │
└──────────────────────────────────────────────────────────────┘
根因在最底下那一步,但症状出现在最上面那一步。
这就是为什么固件版本必须作为独立检查项,而不是「装完驱动就不用管」。
这条链解释了一个非常常见的困惑:为什么 ibv_devinfo 能读出这台机器上所有卡的信息,SM 却"看不见"其中某几张。ibv_devinfo 读的是驱动从设备取回的静态信息(GUID、PSID、Device ID 都在 flash 里,固件坏了也读得到),而 SM 依赖的是该节点对 SMP 报文的实时应答。两者衡量的是完全不同的东西。
把一次 HCA 部署涉及的软件分层摆开,会发现"固件升级"这个词在其中的位置比想象的更靠底层,也更容易被误解。把层与层之间的调用方向理清楚,"为什么要单独升固件"就不需要额外解释了。
最上层是应用。它通过 verbs 发起 RDMA 操作。verbs 的定义在 InfiniBand 规范里——课程在第二节的 HCA 定义里说的"支持规范定义的全部 software verbs",指的就是这一层的接口形态。这一层由规范固定,不随任何单一厂商的实现变化。
verbs 之下是主机驱动与用户态库。内核里的 mlx5 驱动与 rdma-core 用户态库负责把 verbs 翻译成对设备寄存器的操作。这一层随 MLNX_OFED 发行版一起更新,它管的是"怎么和这块卡说话"。
再往下才是设备侧固件。它管的是"这张卡自己怎么工作"——收到包之后做什么、链路训练怎么收敛、流量怎么在内部缓冲与调度。这一层烧在设备自己的 NVMEM 里,主机侧没有任何软件包能替换它。MFT 文档在讲 PSID 时把这件事说得很直白:PSID 保存在设备 NVMEM 的固件镜像中,固件烧录工具正是用这个字段在升级版本时保留固件配置。能被"保留"的东西,前提是它本来就不在主机上。
这个分层的直接推论是:主机侧的更新无法覆盖设备侧。课程在第三节讲的"OFED 安装过程会同时升级固件",是一个由安装脚本主动调用 MFT 完成的附带动作,不是内核机制自动完成的。这意味着两件事:一是固件有自己独立的、不随操作系统升级的生命周期;二是如果绕过了 OFED 安装器(比如手工装驱动、或在容器里部署),固件就不会被顺带升——这正是第三节说的"HCA 固件可以脱离 OFED 单独升级"这个能力存在的现实理由。
本节关键记忆:3 个定义 + 1 条因果链 + 1 个分层结论
- 3 个定义:Channel Adapter = 连接设备到 fabric 的网卡;HCA = 为主机提供接口并支持全部 verbs;固件 = 为 HCA 执行基础任务提供指令,示例是"对收到的包执行动作"
- 1 条因果链:固件异常 → 包处理不了 → SMP 不应答 → SMA 失效 → SM 发现不到 → 不分配 LID → 业务不通
- 1 个关键区分:ibv_devinfo 读得到静态信息 ≠ SM 发现得到这个节点。前者读 flash,后者依赖实时应答
- 1 个分层结论:固件烧在设备侧 NVMEM,主机侧软件栈无法覆盖它;OFED 顺带升固件是安装脚本的主动行为,不是内核机制
三、什么时候该升、什么时候不该升:三种触发条件
What — 课程给出的前置判断与三种触发条件
课程在进入工具之前先立了一条判断规则,这条规则决定了后面所有操作是不是必要动作:一般而言,如果刚装过 OFED,固件不需要升级,因为 OFED 的安装过程会同时完成固件升级。
紧接着,课程给出了固件可以脱离 OFED 单独升级这个事实,并列出三种应当考虑升级的情形。这三条是本节的核心,逐条拆开讲:
- OFED 版本与固件版本失配(the OFED version and the firmware version are out of sync)
- 安装固件的过程中发现了问题(an issue was noticed during the installation of the firmware)
- 固件版本已损坏,或存在已被修复的缺陷(the firmware version is corrupted or has bugs that have been addressed)
这三条的共同结构是:它们都不是"例行更新",而是"已经观测到了某个具体问题"。这是理解固件升级定位的关键——它是一个带触发条件的修复动作,不是一个应当定期执行的保养动作。
3.1 三种触发条件各自的判据与观测手段
| 触发条件 | 怎么判定它发生了 | 用哪条命令观测 | 不处理的后果 |
|---|---|---|---|
| OFED 与固件版本失配 | OFED 发行版版本与 ibv_devinfo 的 fw_ver 不属于配套组合 | ofed_info -s 读 OFED 版本 ibv_devinfo 读 fw_ver |
驱动与固件接口不一致,行为未定义 |
| 安装固件时发现问题 | 烧录或加载阶段出现错误、警告,或烧录后版本号未按预期变化 | flint 的输出与返回值 flint -d <dev> query 回读 |
卡停在半途状态,需要重做 |
| 版本损坏或缺陷已修复 | 端口无法 up、链路异常、间歇性掉线,或修复公告中点名了当前版本 | ibstat 读端口状态 flint -d <dev> query 读 flash 实际内容 |
第二节那条因果链的任一环节 |
关于第一条"版本失配"的判定必须说清楚边界。OFED 版本与固件版本之间是配套发布的关系,但本文不给出任何"哪个 OFED 版本必须配哪个固件版本"的对照表——这类对照表随每一代 ConnectX 产品、每一个 OFED 发行版而变化,任何写死在文章里的对照都会在几个月内失效。正确的判定方式是:以随该 OFED 发行版一同发布的官方文档与 release note 为准,而不是以本文或其他二手文章为准。
3.2 与本系列其他篇的衔接:故障现象 → 固件嫌疑
Why — 把固件版本纳入排查清单的实际收益
本系列第八篇给出了端口状态的判读口诀,第九篇补上了 SM 侧的扫描与重收敛机制。在那两篇的框架里,固件版本是一个默认被排除的变量——因为正常的排查起点是"物理层与驱动都正常"。
把本篇接上去之后,排查链条上多了一个明确的检查点,而且它的位置很特殊:它位于"物理层已通"与"SMP 能否应答"之间的夹缝里。具体来说:
- 如果 ibstat 显示物理状态 LinkUp 但逻辑状态停在 Initializing(本系列第八节的判读结论:管理面问题),那么"固件版本不对"是这个结论下的一个具体候选,而 flint -d <dev> query 读出的 PSID 与 FW Version 是判定它的直接手段
- 如果链路层反复掉线或速率反复协商(本系列第八节第九节的"重收敛"话题),固件缺陷是继物理层与配置之后的第三个排查方向,而升级到已修复版本正是第三条触发条件所覆盖的情形
- 如果 ibv_devinfo 的 vendor_part_id 与预期型号不符,那么问题不在固件而在硬件识别,应当先解决识别问题
换句话说,把固件版本当作一个需要主动核对的量,而不是一个"装好了就不用管"的前提,是本篇对整条排查链路最大的贡献。
本节关键记忆:1 条前置判断 + 3 种触发条件 + 1 个定位
- 1 条前置判断:刚装过 OFED 通常不需要升固件——OFED 安装过程会同时升级固件
- 3 种触发条件:OFED 与固件版本失配 / 安装过程中发现问题 / 固件损坏或缺陷已修复。三条都是"已观测到具体问题",不是例行保养
- 1 个定位:固件版本处于"物理层已通"与"SMP 能否应答"之间的夹缝,是"LinkUp + Initializing"的一个具体候选
- 1 条边界声明:本文不提供 OFED 版本与固件版本的对照表——该对照随产品代次与发行版变化,须以官方文档为准
四、工具全景:MFT 包与三个主用工具
What — MFT 是什么,以及为什么本单元只用三个工具
课程对 MFT 的定义是:NVIDIA MFT 包是一套固件管理工具,用于生成固件镜像、查询固件信息,以及把镜像烧录到 NVIDIA 设备上。这个包里的工具有若干个,但本单元只使用其中三个,课程明确点了名并给出了分工:
- mst 服务 —— 在升级固件之前查询所需信息
- flint —— 把镜像烧录到设备上
- mlxfwreset —— 在烧录完成之后复位设备并加载新固件
课程同时给了一条获取补充信息的指引:想了解其余工具,请参考上文链接的 MFT 用户手册。本篇第五节会给出 flint 的完整功能清单,第十一节会给出另外两个工具的完整语法,三者合起来就覆盖了本单元需要的全部能力。
4.1 MFT 与 OFED 的关系:装了就有了,但不是同一个东西
课程给了一条非常实用的经验:如果已经安装了 OFED 驱动,那么 MFT 包也已经装上了;如果需要,也可以把 MFT 包单独下载安装。这条经验在两个层面都有价值:
- 排查层面:"命令找不到"这类问题的第一嫌疑就是 MFT 没装,而不是命令名写错。课程在演示步骤里也专门提到了这条——先跑 ofed_info 确认 MLNX_OFED 驱动是否已安装,因为 MFT 是作为 MLNX_OFED 驱动安装的一部分被装上的
- 部署层面:在容器化部署、只装 inbox 驱动、或自定义内核的场景下,MFT 可能并不随 OFED 而来,此时需要单独安装——这就是课程说"可以单独下载安装"的实际场景
关于 mst 服务是"装就有"还是"要启动":这是两个不同的问题。MFT 包被安装,意味着 flint / mlxfwreset / mst 这些可执行文件在磁盘上;但 mst 作为一个驱动服务,还需要被启动才能在 /dev/mst/ 下创建代表设备节点的特殊文件。NVIDIA 的固件升级指引把 mst start 列为烧录的第一步,并明确这一步只适用于 Linux——第九节会展开这一点。
4.2 三个工具在数据流上的位置
把三个工具按"数据从哪来、到哪去"排一遍,会发现它们在升级流程里各自负责一段,段与段之间的交接物就是那四项身份信息:
三个工具的分工与交接物
┌──────────────┐ ① 采集身份 ┌──────────────────┐
│ ibv_devinfo │ ───────────────────────► │ 人工记录四项 │
│ (只读查询) │ hca_id │ hca_id │
│ │ fw_ver │ fw_ver │
│ │ vendor_part_id │ vendor_part_id │
│ │ board_id │ board_id=PSID │
└──────────────┘ └────────┬─────────┘
│
┌─────────────────────────────┤
│ 用 vendor_part_id │ 用 PSID
│ 定位 mst 设备 │ 定位固件
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ mst 服务 │ │ NVIDIA 固件 │
│ mst start │ │ 下载中心 │
│ mst status │ │ 按 OPN + PSID │
└──────┬───────┘ │ 选版本并下载 │
│ └────────┬─────────┘
│ 输出 /dev/mst/mt4123_pciconf0 │ 解压得 .bin
└──────────────────┬─────────────────────────┘
▼
┌────────────────────────────────┐
│ 输入 A:-d 设备节点(来自 mst)│
│ 输入 B:-i 镜像文件(来自下载)│
│ 命令 :b[urn] │
└────────────────┬───────────────┘
▼
┌────────────────────────────────┐
│ flint │
│ 把 .bin 写入设备的 flash │
│ 结尾提示:To load new FW run │
│ mlxfwreset or reboot machine │
└────────────────┬───────────────┘
▼
┌────────────────────────────────┐
│ mlxfwreset -d reset -y│
│ 停止驱动 → PCI 复位 → 启动驱动 │
│ → 重启 MST → FW 加载成功 │
└────────────────┬───────────────┘
▼
┌────────────────────────────────┐
│ 验证:flint query 读 flash │
│ ibstat 读运行态 │
└────────────────────────────────┘
注意中间那两条箭头:它们的交汇点是「人工记录的四项信息」。
记录不全 → 定位不到设备或选不对镜像 → 烧错。
上面这张图里,最容易被质疑的环节是中间那个方框——信息在 ibv_devinfo 和下载中心之间是"经人转手"的。既然可以让脚本全自动完成,为什么课程要专门强调"把这些信息记下来,下一步还要用"?
第一个原因是:这三段动作发生在三个不同的系统上,介质不同、时刻不同。身份信息是在要升级的这台主机上采的;固件镜像是在任意一台能上网的机器上下载的;烧录又回到目标主机。课程演示的形态是"在目标主机上采集 → 拿信息去下载 → 把文件弄回目标主机"。人工记录是这个跨机流程里唯一可靠的传递方式——而它同时也是唯一可以被人工复核的一环。
第二个原因是:三项信息的作用域各不相同,只有第四项能唯一定位一份镜像。这一条值得展开,因为它是第四节最容易被忽略的技术细节:
- hca_id(课程列的第一项)的作用是在一台机器上区分多张卡。它解决的是"是哪一张",不解决"该装哪个版本"
- fw_ver(第二项)的作用是判断升级是否必要。课程明确说这一项是用来"确认是否真的需要升级"的——它是一道闸门,不是一项下载依据
- vendor_part_id(第三项,课程称 HCA part ID)的作用是构造 mst 设备路径。第九节会证明这正是 /dev/mst/mt4123_pciconf0 里那个 4123 的来源
- board_id / PSID(第四项)的作用是在 NVIDIA 固件下载中心的下拉框里选中正确的那个条目。它解决的是"该装哪个镜像"
把四项的作用域排开,会得到一个很实用的判断:如果一个新人只知道记 vendor_part_id,他能把设备找对但下不对镜像;如果只知道记 PSID,他能下对镜像但烧不到这台机器上。四项缺一不可,而且它们各自守住流程的一段,没有一项能替另一项顶班。
第三个原因是人工记录带来了一次交叉校验的机会。课程要求写下的 fw_ver 是"升级前的版本",而第十二节的验证步骤要拿它与"升级后的版本"对比。这个前后对照是升级是否成功唯一的直接判据——如果没有事先记下来,事后就只能凭印象说"好像变了"。这个细节看似琐碎,但它把"验证"从一个动作变成了一次可审计的对照实验。
本节关键记忆:1 个包 + 3 个工具 + 4 项信息 + 3 段交接
- 1 个包:MFT,用于生成镜像、查询信息、烧录镜像;装了 MLNX_OFED 通常就已装上,也可单独安装
- 3 个工具:mst 服务(升级前查询信息)/ flint(烧录镜像)/ mlxfwreset(烧录后复位并加载)
- 4 项信息:hca_id 区分卡 / fw_ver 判必要性 / vendor_part_id 构造设备路径 / board_id 选镜像
- 3 段交接:采集 → 下载 → 烧录,跨越不同机器与不同时刻,人工记录是唯一可靠的传递方式,且提供交叉校验机会
五、flint 的能力边界:五项功能与它的安全约束
What — MFT 官方文档对 flint 的完整定义
课程对 flint 的描述是:用于升级 HCA 固件的主要工具是 flash interface(即 flint)工具。MFT 官方文档给出了更完整的定义,把 flint 的全称为 Flash interface utility,并逐条列出它执行的五项功能。这五条是本节的第一手依据:
- 把二进制固件镜像烧录到连接到适配器或交换机设备的 flash 器件上
- 把扩展 ROM(Expansion ROM)镜像烧录到连接到适配器的 flash 器件上
- 查询固件属性(版本、GUID、UID、MAC、PSID 等)
- 支持从命令行对 flash 存储器执行多种操作(用于调试/生产)
- 禁用/启用对设备硬件寄存器的访问,并更改用于启用的密钥(此特性仅在被烧录的固件支持时有效)
逐条对照课程原话,会发现课程把第 1、4、5 条都提到了,但把第 2、3 条压缩成了一句话。课程还漏掉了 flint 的命令行语法本身与返回值定义——这两项恰恰是判断"升级有没有成功"的直接依据,第十二节会用到。
5.1 课程描述与官方定义的逐条对照
| 官方功能 | 课程的处理 | 本篇补充的官方细节 |
|---|---|---|
| ① 烧录二进制固件镜像到适配器/交换机的 flash | 讲到,并强调"这是主要工具" | 命令行 flint -d <device> -i <fw-file> burn,其中 b 与 burn 等价 |
| ② 烧录扩展 ROM 镜像到适配器的 flash | 讲到,并限定在 ConnectX 系列适配器 | 官方另有独立的 ROM 子命令:brom / drom / rrom / qrom,本单元不涉及 |
| ③ 查询固件属性 | 压缩为一句"同时查询固件属性" | 命令 q[uery] [full],查询项含版本、GUID、UID、MAC、PSID、Image VSD、Device VSD、ROM Info 等;这是第十二节验证链的第一条证据 |
| ④ 支持命令行执行多种 flash 操作 | 讲到,并限定为"调试/生产用途" | 官方命令表列出底层操作:hw query、e[rase] <addr>、rw / ww、rb / wb 等;本单元不要碰这些 |
| ⑤ 禁用/启用硬件寄存器访问并更换密钥 | 讲到,未展开 | 命令 set_key [key] 与 hw_access <enable|disable> [key];官方注明新密钥仅在设备复位后生效,且密钥丢失无法用该工具恢复 |
5.2 三条安全约束:官方文档里最该先读的部分
约束一:flint 的返回值不是布尔值。官方文档明确定义了三个返回值,其中返回值 7 具有明确的成功性含义:
- 0 —— 成功完成(Successful completion)
- 1 —— 发生错误(An error has occurred)
- 7 —— 对于 burn 命令:用户在提示时没有选择烧录新固件,因此烧录过程被中止(The option of burning new firmware was not chosen by the user when prompted. Thus, the firmware burning process was aborted.)
返回值 7 是自动化脚本里最容易漏判的一个——它既不是成功也不是失败,而是"人为中止"。一个只判断 $? -eq 0 的脚本会正确地把它当失败处理,但一个只判断 $? -ne 1 的脚本会把它当成功。写自动化脚本时必须显式区分这三个值。
约束二:默认是容错(failsafe)烧录,-nofs 是例外而非默认。官方对 -dual_image 选项的说明里给出了当前默认算法的准确描述:当前的默认容错烧录过程只烧写一份镜像,并写在交替的位置上(Current default failsafe burn process burns a single image (in alternating locations));而 -dual_image 才是"烧写两份镜像",被标注为"以前的默认算法"。-nofs 的语义是"以非容错方式烧录镜像"。
约束三:设备不支持的 reset 级别会直接报错。官方在 mlxfwreset 的限制清单里列明:执行一个由 query 命令显示为不支持的 reset level / reset type / reset sync 会产生错误。这就是为什么 mlxfwreset 的语法里 --level 只接受 0、3、4 三个值——这是设备能力的边界,不是可以随便填的参数。
把 flint 的两条机制放在一起看,会发现它们防的是两种完全不同的事故:容错烧录防的是"写到一半断电",PSID 校验防的是"写错版本"。这两道闸门在设计上是正交的,缺任何一道都留下一类无法挽回的后果。
先看容错烧录。官方描述的默认算法是"只烧写一份镜像,并写在交替的位置上"。这句话里有两个关键点:"一份"意味着 flash 上始终只有一份被视为有效的镜像;"交替的位置"意味着每次烧录写入的物理位置与上次不同。两者组合的效果是:写入新镜像的过程中,旧的镜像所在的扇区没有被触碰。因此如果在中途断电,设备上仍然留有一份完整的旧镜像,可以继续启动。这是一个把"单点写入失败"降级为"这次升级没生效"的机制——代价是每次烧录都只更新一半的容量,需要多次交替才能完成全部更新。
把这个机制与 -dual_image 对照,容错的必要性就更清楚了。双镜像方案(烧两份)的容错性更差:如果第一份写成功、第二份写失败,flash 上就同时存在一份新镜像和一份不完整镜像,设备该信任哪一份由固件内部的版本判定逻辑决定,而判定依据本身也可能来自那次失败写入的残缺数据。所以官方把双镜像降级为"以前的默认算法",把单镜像交替提升为当前默认——这是一个明确的"更保守的默认值胜出"的设计决策。
再看 PSID 校验。官方对标准行为的表述是:设备 PSID 与镜像 PSID 必须完全一致,或者使用 --allow_psid_change 标志来覆盖这一要求。这条规则防的是完全不同的一类事故:你下载错了镜像,或者想给一块卡刷一个不属于它的固件变体。容错机制在这种情况下帮不上任何忙——镜像本身是"完整写入"的,failsafe 过程会非常成功地把一份错误的固件写进去。
把两道闸门并排,触发条件与失败后果的对照关系就清楚了。
| 维度 | 容错烧录(failsafe) | PSID 精确匹配校验 |
|---|---|---|
| 防的事故 | 写入过程中断电、写入中断、flash 写坏 | 刷入不属于本卡的固件配置变体 |
| 判据来源 | 写入位置是否与上次交替 | 设备 NVMEM 中的 PSID 与镜像内 PSID 逐字符比对 |
| 失败时的现场 | 旧镜像完好,设备仍可用旧版本启动 | 烧录被拒绝,设备保持原状 |
| 是否可事后修复 | 重新烧录即可 | 重新选择正确镜像即可,同样可修复 |
| 关闭开关 | -nofs(非容错烧录) | --allow_psid_change(覆盖匹配要求) |
| 本单元是否使用 | 不关,用默认 | 不覆盖,让它拦住错镜像 |
两条对照共同指向一条操作原则:这两个开关都应当保持默认。-nofs 与 --allow_psid_change 各自都有明确的合理使用场景,但那些场景的前提是操作者已经确认了设备身份与镜像归属。在本单元这个"学习并走通标准流程"的语境下,绕过任何一道闸门都是在用安全性换取便利,而这里的便利没有任何价值——多花三十秒核对一次 PSID,永远比烧错之后想办法救砖划算。
本节关键记忆:5 项功能 + 3 条约束 + 2 道闸门
- 5 项功能:烧录固件镜像 / 烧录扩展 ROM 镜像 / 查询固件属性 / 命令行执行 flash 操作 / 禁用启用硬件寄存器访问
- 3 条约束:返回值有 0 / 1 / 7 三个(7 = 用户提示时未选择烧录,过程被中止);默认是容错烧录,-nofs 是例外;不支持的 reset 级别会直接报错,--level 只接受 0 / 3 / 4
- 2 道闸门:容错烧录防"写到一半断电"(单镜像交替位置);PSID 校验防"刷错版本"(需完全一致,或用 --allow_psid_change 覆盖)
- 1 条操作原则:-nofs 与 --allow_psid_change 在本单元都应保持默认——它们是为"已确认身份"的操作者准备的逃生门,不是常规路径
六、第一步:确认型号与 PCI Device ID
What — 课程给出的第一条命令与它的输出
课程在升级流程的第一条命令上停了一下,给出了一句明确的话:第一件要知道的事是 HCA 的类型和版本,而 lspci 命令会为你查询这些信息。
课程随后描述了输出内容:命令输出显示两块双端口 HCA,一块是 ConnectX-5,另一块是 ConnectX-6;本次将对 ConnectX-6 这块卡执行固件升级。在演示环节,课程给出的命令形态是用 lspci 配合 grep 过滤出 Mellanox / NVIDIA 的设备。
这里有一个必须澄清的精度问题:lspci 能给出型号与 PCI Device ID,但给不出固件版本。课程在同一段落里把这两件事并列了("类型和版本"),实际上"类型"来自 lspci,而"版本"来自第七节的 ibv_devinfo。这不是转写错误,是课程表述的简化,但照着做的时候必须知道去哪条命令取哪个值。
6.1 命令形态与两种过滤方式
课程演示用的是关键字过滤,官方文档给的是厂商 ID 过滤,两者都可用且各有优势。
- 关键字过滤(课程演示形态):按 Mellanox 或 NVIDIA 字样抓取整行,优点是能直接看到设备描述文本(含型号名),缺点是依赖描述字符串的措辞,不同代次的描述里厂商名可能不同
- 厂商 ID 过滤(mstflint README 形态):lspci -d 15b3:,按 PCI 厂商 ID 精确筛选。这个 15b3 是 Mellanox / NVIDIA 历史上的 PCI 厂商 ID,mstflint 的 README 里就是用它来"列出所有 NVIDIA(或 Mellanox)设备"的。它的优点是不依赖描述文本,缺点是不显示型号——型号要从输出的设备描述里读
推荐做法:两条都跑。先用厂商 ID 过滤拿到完整清单确认没有漏掉设备,再用关键字过滤确认每张卡的型号描述。
6.2 为什么这一步不能跳:型号决定了后面所有分支
Why — 型号不是标签,是后续三处选择的输入
把"确认型号"这一步的输出往后追,会发现它不是一个孤立的确认动作,而是三个分支条件的共同输入:
- 决定下载路径。NVIDIA 固件下载中心的主页面是一个按产品线 × 网络协议组织的二维表。课程描述的导航动作——"找到 HCA 类型和协议,本例是 ConnectX-6 与 InfiniBand VPI"——就是在这张表的两个维度上各选一格。选错产品线会走到没有对应固件的页面,选错协议会拿到 VPI 之外的、以太网侧的固件
- 决定设备 ID。型号后面跟着一串十六进制的 PCI Device ID,而这串 ID 的十进制形式正是 /dev/mst/ 设备路径里那个数字。第九节会给出完整的换算关系
- 决定"升级哪一块"。课程明确说本次升级的对象是两块卡中的 ConnectX-6 那块。如果这一步跳过,烧录命令会作用于错误的目标
因此这一步的正确产出不是一个结论,而是两个可核对的值:
- 型号名(如 ConnectX-6)→ 用于下载中心导航
- PCI Device ID(十六进制,输出里以 [15b3:4123] 这样的形式出现)→ 用于换算 mst 设备路径
一个必须避免的误读:不要把 mlx5_0 当成型号。这是本篇开篇纠正表里的第 9 条,这里给出它的完整依据。公开文档中可以看到两个明确冲突的例子:有一台机器上 ibv_devinfo 报 hca_id: mlx5_0 而 vendor_part_id: 4119;另一台机器上 hca_id: mlx5_0 而 vendor_part_id: 4099。同一个设备名对应了不同的芯片——这足以证明 mlx5_0 不携带型号信息。原因是它的命名规则是"驱动族名 mlx5 + 枚举序号 _0",由内核枚举 PCI 设备的顺序决定,与设备是什么型号无关。换卡之后名字可能不变而芯片全变。
要查型号,用这两个字段之一:ibstat 的 CA type(形如 MT4123,是设备型号代号),或 ibv_devinfo 的 vendor_part_id(十进制纯数字,对应 PCI Device ID)。
本节关键记忆:1 条命令 + 2 个产出 + 3 个下游分支
- 1 条命令:lspci,可用关键字过滤(看型号)或厂商 ID 过滤(lspci -d 15b3:,看全量),推荐两条都跑
- 2 个产出:型号名(决定下载中心导航路径)+ PCI Device ID(决定 mst 设备路径)
- 3 个下游分支:下载中心的产品线与协议 / 设备 ID 换算 / 多卡时选哪一张烧
- 1 个必须避免的误读:mlx5_0 是驱动族名 + 枚举序号,不是型号;查型号用 CA type 或 vendor_part_id
七、第二步:采集四项关键信息(ibv_devinfo 精读)
What — 课程明确要求"一定要记下来"的四项
课程在这一步用了一个很强的措辞:有四段信息是你应该查看、并且一定要写下来的,因为下一步会用到它们。课程给出的实例值是:HCA ID 是 mlx5_0,当前固件版本是 20.32.1010,厂商分配给它的 HCA part ID 是 4123,第四项课程单独解释为板卡 ID 或 PS ID。
逐项说明课程给出的每一项的用途:
- 第一项 — 节点 HCA ID。课程的动机说明得很实际:有些系统装了好几块 HCA,你要确保更新的是正确那一块的固件
- 第二项 — 当前固件版本。课程说这一项是用来检查当前版本,以确保是否真的需要升级。它是第三节那条"闸门"的判据
- 第三项 — 厂商分配的 HCA part ID。示例值 4123。第九节会证明它就是 mst 设备路径里的那个数字
- 第四项 — 板卡 ID 或 PS ID。课程对它的定义是:PS ID 参数集标识是一个嵌在固件镜像中的 16 个 ASCII 字符的字符串,为该固件配置提供唯一标识,并且指出 这个 PS ID 总是以 MT_ 开头,是在 NVIDIA 网站上找到正确固件镜像时的关键信息
这四项在 ibv_devinfo 的输出里分别对应四个不同的字段名,第八、九节会逐一建立映射。
7.1 ibv_devinfo 输出字段逐项对照
ibv_devinfo 属于 rdma-core,它按"设备级字段 → 端口级字段"两层组织输出。公开文档中的实际输出样例(ConnectX-6 实例)如下,本节只取设备级字段,端口级字段与本篇无关:
[root]# ibv_devinfo
hca_id: mlx5_0
transport: InfiniBand (0)
fw_ver: 20.31.1014
node_guid: e8ebd30300fd0788
sys_image_guid: e8ebd30300fd0788
vendor_id: 0x02c9
vendor_part_id: 4123
hw_ver: 0x0
board_id: MT_0000000223
phys_port_cnt: 1
...(端口级字段,此处略)
↑ 本篇关心的四个字段在这里,其余字段用于其他目的
采集结果(对应课程的"四项"):
┌──────────────────┬───────────────────┬────────────────────────────┐
│ 课程说的"四项" │ ibv_devinfo 字段 │ 在本篇中的作用 │
├──────────────────┼───────────────────┼────────────────────────────┤
│ 节点 HCA ID │ hca_id │ 一台机器上区分多卡 │
│ 当前固件版本 │ fw_ver │ 判断是否需要升级 + 前后对照 │
│ HCA part ID │ vendor_part_id │ 换算 /dev/mst/ 设备路径 │
│ 板卡 ID / PS ID │ board_id │ 在下载中心选中正确镜像 │
└──────────────────┴───────────────────┴────────────────────────────┘
Why — board_id 与 vendor_part_id 为什么必须是两个不同的值
上面这张表里最容易被误读的是第三、四项:它们都指向"这块卡是什么",但指向的是完全不同的两个层面。
vendor_part_id 描述的是芯片。它由 PCI 规范分配,是设备在 PCI 总线上的身份。它的粒度是"这块卡用的是哪一颗控制器",与卡上刷的是什么固件配置、这块卡被卖给了谁完全无关。它的作用范围是硬件寻址——第九节的 mst 设备路径就是靠它构造的。
board_id 描述的是固件配置。MFT 官方文档的表述是:PSID 作为固件镜像的一部分保存在设备 NVMEM 中,固件烧录工具正是用这个字段在升级固件版本时保留固件配置。这句话点明了它的本质:PSID 是"配置"的标识,不是"硬件"的标识。同一种芯片、同一个 vendor_part_id,可以因为固件参数集不同而拥有不同的 PSID。
这个区分有直接的工程后果:vendor_part_id 相同的两张卡,PSID 可能不同,因此需要的固件镜像也可能不同。MFT 文档在讲 PSID 的分配流程时给了一个具体例子:NVIDIA 某块 HCA 板卡的 PSID 是 MT_0030000001,其中 003 是板型符号、000 是板版本符号、0001 是参数集编号。把固件配置改掉、换一个参数集编号,PSID 就变了,而 vendor_part_id 一点没变。
所以两个字段的用法是完全不同的,不能互相替代:vendor_part_id 用来回答"这台机器上的哪一块设备",board_id 用来回答"这块设备需要哪一份固件配置"。把 vendor_part_id 当成下载依据是最常见的一类错误——它会让你找到一个"芯片对得上"的下载页,但那个页面上可能有多个 PSID 的条目。
7.2 采集的顺序与建议
采集前后的两条建议:
- 建议一:先跑 ibv_devinfo -l 拿到设备名列表,再对每台设备逐个跑完整查询。ibv_devinfo -l 的语义是"只列出 RDMA 设备名",这样可以先确认这台机器上到底有几块 HCA,避免看漏
- 建议二:把 fw_ver 的采集和验证放在同一个记录里。课程第十二节的验证步骤是拿升级后的版本与升级前对比,如果升级前没记,事后无法判断究竟升没升。最省事的做法是在采集时就把它写进工单或变更记录,而不是记在便签上
本节关键记忆:4 项信息 + 1 个字段对照 + 1 组必须区分的概念
- 4 项信息:hca_id(区分卡)/ fw_ver(判必要性 + 前后对照)/ vendor_part_id(换算设备路径)/ board_id(选镜像)
- 1 个字段对照:board_id 即 PSID;vendor_part_id 即 PCI Device ID 的十进制形式
- 1 组必须区分:vendor_part_id 描述芯片(硬件寻址),board_id 描述固件配置(配置标识)。同一 vendor_part_id 可以有不同 PSID,因此所需镜像也可能不同
八、PSID 解码:16 个字符如何唯一定位一份固件配置
What — MFT 官方文档对 PSID 字段结构的完整定义
第七节引了课程对 PSID 的定义(16 个 ASCII 字符、为固件配置提供唯一标识),但没有给字段结构。MFT 官方文档给出了完整的结构定义,这是本节的第一手依据:
PSID 字段是一个 16 字符(字节)的 ASCII 字符串。如果指定的 PSID 长度不足 16 个字符,剩余字符由烧录工具以二进制 0 填充。
官方给出的字段结构表把 16 个字符切分为五段:
- 厂商符号(Vendor Symbol) —— 3 个字符
- 板型符号(Board Type Symbol) —— 3 个字符
- 板版本符号(Board Version Symbol) —— 3 个字符
- 参数集编号(Parameter Set Number) —— 4 个字符
- 保留位(Reserved) —— 3 个字符,以 \0 填充
官方给出的完整示例是:一块 NVIDIA HCA 板卡的 PSID 为 MT_0030000001,逐段拆解为 MT_ 是厂商符号、003 是板型符号、000 是板版本符号、0001 是参数集编号。
PSID 看起来只是一串用来查表的字符串,但把它按 3+3+3+4+3 拆开之后,会发现这三个设计决定各自对应一个真实的工程需求,缺一不可。
第一个决定:定长 16 字节,不足用 \0 补齐。如果 PSID 是变长的,那么"两个 PSID 是否相同"这个问题就没法用简单比较来判断——必须先知道它们各自在哪里结束。定长把它变成了一个可以直接按 16 字节逐位比对的定值,这正是第五节说的"PSID 精确匹配校验"能够存在的前提。这个校验的官方表述是"设备 PSID 与镜像 PSID 必须完全一致","完全一致"这四个字只有在定长编码下才是廉价操作。
第二个决定:按 3+3+3+4 分段,而不是 16 个字符随意切。分段的直接收益是可解析性。定长保证了可比对,分段保证了可解释。看 MT_0000000223 与 MT_0000000891 两个 PSID,肉眼无法判断它们是不是"同一块板的不同版本";但按段拆开之后,板型符号与板版本符号完全一致、只有参数集编号不同,这个结论立刻成立。换句话说,字段结构让"这两个 PSID 差在哪"变成一个可以回答的问题,而不是一个只能看到"字符串不一样"的事实。
第三个决定:厂商符号由各厂商自行定义,唯一性由厂商自己保证。这一条是本节最需要展开的,因为课程的表述在这里有偏差。课程说"这个 PS ID 总是以 MT_ 开头"——这个说法只对 NVIDIA 自家交付的板卡成立。MFT 文档在讲"给定制固件分配 PSID"的流程时明确要求:使用你自己的厂商符号以保证 PSID 唯一性;如果你不知道自己的厂商符号,请联系你本地的 NVIDIA FAE。
把这条要求与字段结构放在一起看,就能理解厂商符号这一段存在的意义了:它是给"非 NVIDIA 板卡"预留的命名空间。OEM 或板卡制造商可能基于 NVIDIA 的控制器做自己的板子、设自己的固件参数集,如果所有人都用 MT_ 开头,PSID 就会冲突。因此前三段的第一段是由谁定的标识,后三段才是"这块板的什么配置"。
最后一段保留位用 \0 填充这个细节也有实际作用。它保证了一个不变式:任何 PSID 在补齐之后长度恒为 16,因此解析程序不需要判断字符串是否已经到头。代价是打印出来的 PSID 末尾可能带不可见字符——所以手工输入或比对 PSID 时应当按定长 16 处理,不要按"看起来的"字符数。
8.1 用官方示例解码一遍
把官方给的 MT_0030000001 逐字符拆开,并标注每一段在工程决策中的作用,这张表是本节最该记住的内容:
| 字符位 | 长度 | 官方字段名 | 官方示例取值 | 在选镜像时的作用 |
|---|---|---|---|---|
| 1 – 3 | 3 | 厂商符号 Vendor Symbol |
MT_ | 决定"这是谁家的板"。NVIDIA 自家为 MT_;OEM 须用自有符号保证唯一 |
| 4 – 6 | 3 | 板型符号 Board Type Symbol |
003 | 决定"是哪一块板"。同型号不同板型在此区分 |
| 7 – 9 | 3 | 板版本符号 Board Version Symbol |
000 | 决定"是这个板的哪个硬件版本"。板卡 rev 变化时此处变化 |
| 10 – 13 | 4 | 参数集编号 Parameter Set Number |
0001 | 决定"用哪套固件参数"。这是 OEM 定制固件的主战场——换参数即换编号 |
| 14 – 16 | 3 | 保留位 Reserved |
\0 | 恒以二进制 0 填充,作用是保证总长恒为 16,使解析无需判断字符串终止 |
把这张表与第七节的现场数据对读一次,就能完成本篇最关键的一次串联。公开文档中某台 ConnectX-6 主机的实际输出是 ibv_devinfo 报 vendor_part_id: 4123、board_id: MT_0000000223,同时 ibstat 报 CA type: MT4123。这三条记录指向同一块板:
- CA type: MT4123 里的 MT4123 是型号代号,其中的 4123 与 vendor_part_id 一致,也与 lspci 输出里的 PCI Device ID 一致
- board_id: MT_0000000223 按上表拆开是:厂商符号 MT_,板型 000,板版本 000,参数集编号 0223。注意最后一段 0223 与前面的 4123 数字相同但含义不同——这正是本篇开篇纠正表第 7 条要防的混淆
- 三者的关系是:4123(芯片)→ MT4123(型号)→ MT_0000000223(固件配置)
这条链条的价值在于它把"找设备"和"选镜像"彻底分开了。前两步的产物是硬件身份,第四步的产物是配置身份;烧录命令的 -d 用前者,下载页面的下拉框用后者。本篇后面所有的操作,都是在消费这两个互相独立的身份。
8.2 第四项之外的补充:VSD 也在同一个查询里
PSID 不是唯一的固件属性,但它是本单元唯一必须人工记录的那一个。flint 的查询命令会返回一组属性,公开文档中的实际输出样例包含:Image type、FW Version、FW Release Date、Product Version、Rom Info、Description、UID GuidsNumber、Base GUID、Base MAC、Image VSD、Device VSD、PSID、Security Attributes。
本单元对这组属性的使用方式是分工的:PSID 用于下载(第八节)、FW Version 用于验证(第十二节)、Image VSD 与 Device VSD 两个值的存在本身就是一个有用的信息——Device VSD 记录的是设备上现有的 VSD,Image VSD 记录的是镜像里的 VSD,正常升级时这两者应当保持一致,因为升级保留配置。VSD(Vital System Data)的写入由 flint 的独立命令 sv 负责,本单元不涉及。
本节关键记忆:1 个结构 + 1 个示例 + 1 条身份链 + 1 处纠正
- 1 个结构:PSID = 厂商符号(3) + 板型符号(3) + 板版本符号(3) + 参数集编号(4) + 保留位(3),总长 16 ASCII 字符,不足以 \0 补齐
- 1 个官方示例:MT_0030000001 = MT_ 厂商 + 003 板型 + 000 板版本 + 0001 参数集
- 1 条身份链:vendor_part_id 4123(芯片)→ CA type MT4123(型号)→ board_id MT_0000000223(固件配置)。-d 用前者,下载用后者
- 1 处纠正:PSID 不总是以 MT_ 开头——那是 NVIDIA 的厂商符号;OEM 必须使用自有符号以保证唯一性
九、第三步:定位 MST 设备路径
What — 课程给出的两条命令与它们各自的目的
课程在下载镜像之后、正式烧录之前,插入了两条命令,并明确说接下来这一段"非常重要":
- mst status —— 课程说明这条命令会检查 mst 是否已启用,以及 mst 设备的路径是什么
- mst start —— 课程说明如果 mst 没有启用,就用这条命令启动它,并给出一个关键事实:这条命令会在 /dev/mst/ 目录下创建代表 NVIDIA HCA 设备的特殊文件
课程还回扣了第七节:当时建议记下的四项信息里有一项是厂商 part ID(4123);如果设备有多块 HCA,你要选中正确的那一块。这句话把第七节与第九节接了起来——下面会证明,正是那个 4123 组成了设备路径里的数字。
9.1 设备名格式:dev_id 就是 vendor_part_id
NVIDIA 固件升级指引给出的设备名格式是:Linux 为 /dev/mst/mt<dev_id>_pci{_cr0|conf0}。把这里的 dev_id 与第七节的 vendor_part_id 对照,两者是同一个数字:
- 证据一:官方烧录示例。NVIDIA 官方文档给出的 ConnectX-6 烧录命令是:flint -d /dev/mst/mt4123_pciconf0 -i fw-ConnectX6-rel-20_42_1000-MCX654106A-HCA_Ax-UEFI-14.35.15-FlexBoot-3.7.500.bin burn。同一个示例页面里,mt4123 里的 4123 与该卡 vendor_part_id: 4123 一致
- 证据二:公开输出样例。Oracle 的 InfiniBand 命令示例文档里,ibv_devinfo 报 vendor_part_id: 26428,同页的 flint 查询输出报 Device ID: 26428,而该卡的 mst 设备名形如 mt26428_pci_cr0——三处同一个数字
此外 lspci 输出的十六进制 PCI Device ID 与之对应:4123 的十六进制是 0x101b,26428 的十六进制是 0x673c。因此第六节 lspci 输出的 [15b3:101b] 与 ibv_devinfo 的 vendor_part_id: 4123 是同一件事的两种进制表示——这一步换算把第六节与第九节接上了。
9.2 _cr0 与 _conf0:访问方式的选择
Why — 两种后缀对应两条不同的访问路径
设备名格式里的 _cr0 与 _conf0 不是随意写的后缀,它们对应两种访问硬件的方式。mstflint 的 README 给出了这两条路径的说明:
- 内存映射访问(PCI Memory Mapping):通过 lspci 显示的 PCI ID(形如 bus:dev.fn)或 IB 设备名访问,速度快,是常规路径
- PCI 配置周期访问(PCI Configuration Access):官方对它的评价是"更慢且不如内存访问安全",并明确要求只在内存访问的两种方式都不可用时才使用它。强制使用配置访问的方式是采用 /proc/bus/pci/<dev.fn> 形式的设备名
因此选择原则是明确的:先用 mst status 给出的路径,不要自己拼。mst status 的输出会直接告诉你这台机器上每个设备实际的完整路径,照抄它比理解后缀的含义更可靠。如果照抄 mst status 的输出仍然失败,那属于需要单独排查的问题(驱动状态、权限、设备异常),不是切换后缀能解决的。
另外两条实测层面的注意事项:
- 权限。mstflint README 在硬件访问章节明确注明:通常需要 root 权限。课程演示里提到"可能需要特殊权限",对应的就是这个要求
- 平台差异。NVIDIA 固件升级指引把 mst start 标注为仅适用于 Linux 操作系统,并在同一张表里把 Windows 一栏标为不适用。本篇全篇的命令流程以 Linux 为准
一次固件升级的操作对象上挂着三个编号,它们在字面上高度相似,混淆的后果也最直接。把它们并排看,能把本篇前八节的知识一次性收拢。
| 标识符 | 出现位置 | 它标识的对象 | 谁消费它 | 混淆后的后果 |
|---|---|---|---|---|
| 4123 (十六进制 0x101b) |
lspci 的 [15b3:101b] ibv_devinfo 的 vendor_part_id /dev/mst/mt4123_pciconf0 |
PCI 设备(硬件寻址) | flint -d / mlxfwreset -d 的设备参数 | 找不到设备,或作用于错误的那块 |
| MT4123 | ibstat 的 CA type | 卡型号代号(人读的型号名) | 第六节的型号确认、下载中心的产品线选择 | 选错下载页,得到不匹配的镜像 |
| MT_0000000223 | ibv_devinfo 的 board_id flint query 的 PSID 下载中心的 PSID 下拉框 |
固件配置(NVMEM 中的持久标识) | 第十节的镜像选择;flint 烧录时的 PSID 匹配校验 | PSID 校验直接拒绝烧录 |
从这张表能读出一个很实用的结论:三个标识符分别由三条独立的命令产出,彼此之间不存在"自动推导"关系。4123 从 lspci 或 ibv_devinfo 来,MT4123 从 ibstat 来,MT_0000000223 从 ibv_devinfo 的 board_id 或 flint 查询来。它们之间只有"属于同一块板"这层关系,值本身不可互相推导。
一个必须警惕的现象:MT4123 与 MT_0000000223 在字面上共享前缀 MT,而第三段数字恰好也出现 4123 与 0223 的数字重合现象。这些视觉上的相似性会诱使人把它们当作同一个标识的不同写法。而它们的实际角色完全不同——一个是型号代号,一个是配置标识,前者用于选产品线、后者用于选镜像条目。本篇开篇纠正表的第 7 条针对的正是这个混淆。
最后一层设计意图值得指出:这三个标识符分别对应三种不同的稳定性。4123 由 PCI 规范分配,对这块卡终身不变;MT4123 是厂商的产品型号,在产品生命周期内不变;MT_0000000223 是 NVMEM 中的配置标识,可以因为固件参数集变化而变化。稳定性递减这一点,直接决定了操作时的容错策略:前两个可以放心当作常量记录,第三个必须在每次下载前重新读一次。
本节关键记忆:2 条命令 + 1 个格式 + 1 个换算 + 3 个标识符
- 2 条命令:mst status(查是否启用 + 查设备路径,输出照抄)/ mst start(未启用时启动,在 /dev/mst/ 下创建设备节点,仅 Linux)
- 1 个格式:/dev/mst/mt<dev_id>_pci{_cr0|conf0};配置周期访问更慢且不如内存访问安全,仅在前两者都不可用时使用
- 1 个换算:dev_id = vendor_part_id = lspci 里 PCI Device ID 的十进制形式(4123 ↔ 0x101b)
- 3 个标识符:4123(PCI 设备,-d 用)/ MT4123(型号,下载页用)/ MT_0000000223(PSID,镜像用)。稳定性依次递减,PSID 每次下载前需重读
十、第四步:下载固件镜像
What — 课程给出的下载路径与镜像形态
课程对这一步的描述包含三个要点:
- 导航到 NVIDIA 固件下载站点,按 HCA 类型与协议查找。课程给的实例是 ConnectX-6 与 InfiniBand VPI;进入后会看到一个选择固件版本的界面
- 下载得到的镜像文件是一个 zip 包,需要解压后才能使用。课程明确说本例使用命令行上的 unzip 来解压文件以备使用
- 必须确保把正确的固件 bin 文件弄到要升级的那台系统上。课程给的实例版本变化是:从当前的 20.32.1010 升级到更新的 20.33.1048
课程还提到了两条并行的获取方式:一条是使用站点的虚拟助手(virtual agent),依次点击最新发布、适配器、下载最新固件,然后输入 PSID(也就是 HCA 的板卡 ID);另一条是打开浏览器直接导航到固件下载页面,选择需要的 HCA 与协议,然后在下载中心里按 OPN 与 PSID 找到可下载的二进制文件。本节以第二条为主线展开——它的每一步都能在官方文档中找到对应。
10.1 下载中心的实际结构:两个导航层级 + 三个下拉框
NVIDIA 固件下载中心主页是一张按"设备类别 → 产品线 × 网络协议"组织的表,适配器卡这一类下面列出了 ConnectX-9、ConnectX-8、ConnectX-7、ConnectX-6 DE、ConnectX-6 Lx、ConnectX-6 Dx、ConnectX-6、ConnectX-5、ConnectX-4 Lx、ConnectX-4、ConnectX-3 Pro、ConnectX-3 等产品行,每行旁边按协议拆成两到三列(例如 ConnectX-7 是 InfiniBand/Ethernet 一列,ConnectX-6 DE 是 InfiniBand 一列)。
点击对应格子后进入该产品的固件下载中心矩阵页。官方文档对这一层的操作给出了明确的三个步骤:
- 选择 CURRENT VERSIONS 标签页
- 依次选择三个下拉框:版本(Version,当前版)、OPN(订购件号)、PSID
- 点击对应的固件链接下载 .bin 文件
OPN 与 PSID 这两个下拉框的分工必须说清楚,这是本节最容易出错的地方。二者都是"收窄范围"的条件,但收窄的东西不同:
- OPN = Ordering Part Number,订购件号。它是你向厂商下单时用的商业件号。官方文档在 ConnectX-7 的示例里给出了对照:ConnectX-7(Cluster)的 OPN 是 MCX750500B-0D00,ConnectX-7(Storage)的 OPN 是 MCX755206AS-NEA——同一个产品线,因为用途不同(集群/存储)而有不同的 OPN
- PSID = Parameter-Set IDentification,参数集标识。它是这块卡上固件配置的唯一标识,也就是第七节采集的 board_id。同一示例中,Cluster 版的 PSID 是 MT_0000000891,Storage 版是 MT_0000000892
结论:OPN 决定"买的是哪一款",PSID 决定"这块板的固件配置是哪一个"。下载时两个都要对上,而 PSID 必须在现场从 ibv_devinfo 读出来,不能推断。查 PSID 最直接的方式就是读取本机 board_id 字段。
10.2 镜像文件名本身就是一份可核对的信息
官方文档给出的 ConnectX-6 烧录示例中,镜像文件名是:fw-ConnectX6-rel-20_42_1000-MCX654106A-HCA_Ax-UEFI-14.35.15-FlexBoot-3.7.500.bin。把这个文件名拆开,会发现它把第七节与第十节采集的多个信息都编码进去了:
| 文件名片段 | 含义 | 对应本篇哪一步采集的信息 |
|---|---|---|
| fw-ConnectX6 | 产品线 | 第六节的型号确认 |
| -rel-20_42_1000 | 固件版本(下划线即点号) | 目标版本;与 ibstat 的 Firmware version 格式对应,便于前后对照 |
| -MCX654106A-HCA | OPN 相关标识 | 第十节 10.1 的 OPN 选择 |
| _Ax | 板卡版本标识 | 与 PSID 第 7–9 段(板版本符号)对应 |
| -UEFI-14.35.15 | UEFI 版本 | 与扩展 ROM 相关(第五节功能②,本单元不单独升级) |
| -FlexBoot-3.7.500 | FlexBoot 版本 | 同上 |
下载后、烧录前的三条核对清单:
- 产品线对不对 —— 文件名里的型号与 lspci / ibstat 读出的型号一致
- 版本对不对 —— 文件名里的版本号是目标版本,且与第七节记录的旧版本确实不同。如果两者相同,升级没有意义,应当回第三节重新判断必要性
- 解压彻底没有 —— flint 的 -i 参数需要指向 解压后的 .bin 文件,不是那个 zip 包。课程强调"要能使用它就得解压",就是这个意思
本节关键记忆:2 层导航 + 3 个下拉框 + 1 个文件名读法 + 1 个平台前提
- 2 层导航:产品线 × 网络协议(如 ConnectX-6 × InfiniBand)→ 进入该产品的下载中心矩阵页
- 3 个下拉框:版本(CURRENT VERSIONS 标签页)/ OPN(商业件号)/ PSID(固件配置标识,须现场读)
- 1 个文件名读法:fw-ConnectX6-rel-20_42_1000-MCX654106A-HCA_Ax-...bin 把型号、版本、OPN、板版本、ROM 版本全部编码在内,下载后应逐段核对
- 1 个平台前提:NVIDIA 官方烧录指引中 mst start 标注为仅适用于 Linux,Windows 一栏为不适用。本篇流程以 Linux 为准
十一、第五步与第六步:烧录(flint)与加载(mlxfwreset)
What — 课程给出的烧录命令三要素
课程在烧录这一步明确指出需要两样东西:一是实际要烧录的 bin 文件,二是设备完整路径——后者正是第九节 mst status 的输出。课程随后把命令行拆成三段来解释:
- -d —— 指定设备
- -i —— 指定镜像
- 最后的 b 标志 —— 课程说"这个小但重要的东西",其他选项在 NVIDIA 固件工具文档中有说明
对照官方语法 flint [OPTIONS] <command> [parameters...],b 就是命令名——官方命令参数表里它写作 b[urn],表示可以写 b 也可以写完整的 burn。因此课程那句"这个小但重要的东西",实质上是整个命令行里唯一的动词,前面两个是参数。
11.1 加载新固件:为什么烧完之后还不能算完
课程在演示环节明确给出了第六步:因为需要复位 HCA,新的固件才会被加载;这一步使用 mlxfwreset 完成。课程描述的命令形态是"指定设备名 -d 与 reset 选项,然后输入 y 确认复位",并指出命令输出显示固件已成功加载。
官方文档给出的语法是 mlxfwreset -d <device> reset-[y],带 -y 表示非交互确认,与课程描述的"输入 y 确认"是同一个动作的两种形态。官方对这个工具的定位是:让用户无需重启机器即可在网卡/交换机上加载更新后的固件,它支持第五代(Group II)HCA 并允许平滑的固件升级。
把 flint 与 mlxfwreset 分成两个工具、两个步骤,不是工具设计上的人为割裂,而是因为它们操作的是两个不同的对象。理解这一点,就理解了为什么烧录成功不等于升级成功。
flint 操作的是 flash 里的镜像。它是设备上的一块非易失存储区,里面放着一份完整的固件二进制。写入这份二进制,与让芯片开始执行这份二进制,是两件事。前者是存储操作,后者是执行控制。
mlxfwreset 操作的是芯片的执行状态。它做的事情是让设备重新初始化、重新从 flash 里把固件读出来并开始运行。官方对它的语法支持给出了完整的参数集,其中包括 --level <0,3,4>(复位级别)、--type <0..2>(复位类型)、--sync <0,1,2>(复位同步)——这三个参数的存在本身就说明复位不是一个"重启"这样的原子动作,而是一个分级、分类型的操作,不同级别影响的范围不同(有的只重启驱动,有的会做 PCI 复位)。
这个区分有一个非常实际的诊断价值:它解释了"烧录成功但版本没变"这个经典现象。如果只执行 flint 不执行 mlxfwreset,那么 flash 里已经是新版本了,但正在运行的那份固件仍然是旧的。此时用 ibstat 查询,读到的是运行态的版本,因此看起来"没升级成功"。
更糟的情况是:此时如果直接重启机器,旧固件已经不在 flash 里了,设备会加载新固件——于是"重启一下就好了",但故障现象与原因被掩盖了,下次升级仍会踩同一个坑。官方文档在 mlxfwreset 的限制清单里还列了另一条相关的行为:在老固件上,一次成功 reset 之后再尝试查询或复位会报错,因为加载新固件的命令已经发送给固件。这条说明 reset 是一次性的、不可重复的——也就是说,如果不确定是否已经 reset 过,重复执行不是安全的探测手段。
官方给出的判据可以直接用来自检:flint 在烧录结束时如果显示了 To load new FW run mlxfwreset or reboot machine 这句提示,说明还需要一步加载动作;如果烧录结束时没有显示这条信息,那么加载新固件需要重启机器。这句话的有无,就是"接下来该做什么"的分水岭。
最后把两个步骤的副作用范围对照一下,这对变更窗口的规划很关键。flint 写入 flash 期间设备处于不可用状态(第五节讲的交替位置写入保证了此时旧镜像仍然完整,但当前这次升级尚未生效);mlxfwreset 会停止驱动、复位 PCI、重新启动驱动、重启 MST 服务——这意味着该端口在加载窗口内必然中断。公开文档中记录的一次实际 reset 输出把这几步逐行打印了出来:发送复位命令到固件、停止驱动、复位 PCI、启动驱动、重启 MST、固件加载成功。这六行就是加载动作的完整内容。
11.2 完整的七步流程与每步的产出
把前面各节的命令按执行顺序排一次,得到本篇的完整流程。课程在概述时给的是五步的骨架,展开为可执行动作后是七步:
HCA 固件升级的七个可执行步骤
步骤 1 确认型号与 PCI Device ID
┌──────────────────────────────────────────────────────────────┐
│ # lspci -d 15b3: (按厂商 ID 列全量) │
│ # lspci | grep -i mellanox (按关键字看型号描述) │
│ │
│ 产出:型号名(ConnectX-6) │
│ PCI Device ID(十六进制,后续要换算成十进制) │
└──────────────────────────┬───────────────────────────────────┘
▼
步骤 2 采集四项关键信息
┌──────────────────────────────────────────────────────────────┐
│ # ibv_devinfo │
│ │
│ 产出:hca_id → 多卡时区分哪一张 │
│ fw_ver → 升级前版本号(第三节的闸门 + 事后对照)│
│ vendor_part_id → 换算 mst 设备路径 │
│ board_id → PSID,下载中心下拉框用 │
└──────────────────────────┬───────────────────────────────────┘
▼
步骤 3 定位 MST 设备路径
┌──────────────────────────────────────────────────────────────┐
│ # mst status → 查是否启用 + 查设备完整路径(照抄) │
│ # mst start → 若未启用则启动(仅 Linux,通常需 root)│
│ │
│ 产出:/dev/mst/mt4123_pciconf0 ←─ dev_id = vendor_part_id │
└──────────────────────────┬───────────────────────────────────┘
▼
步骤 4 下载并解压固件镜像
┌──────────────────────────────────────────────────────────────┐
│ 下载中心:产品线(ConnectX-6) × 协议(InfiniBand) │
│ → CURRENT VERSIONS 标签页 │
│ → 选 版本 / OPN / PSID → 下载 .bin │
│ # unzip <包名>.zip (课程指定用命令行 unzip) │
│ │
│ 产出:<型号>-rel-<版本>--<板版本>-....bin │
└──────────────────────────┬───────────────────────────────────┘
▼
步骤 5 烧录(写 flash)
┌──────────────────────────────────────────────────────────────┐
│ # flint -d /dev/mst/mt4123_pciconf0 \ │
│ -i fw-ConnectX6-rel-20_33_1048-....bin \ │
│ b │
│ │
│ -d 设备(来自步骤 3) │
│ -i 镜像(来自步骤 4,注意是解压后的 .bin 不是 zip) │
│ b = burn,是命令行里唯一的动词 │
│ │
│ 结尾注意:是否出现 "To load new FW run mlxfwreset │
│ or reboot machine" 这句提示 │
└──────────────────────────┬───────────────────────────────────┘
▼
步骤 6 加载(让新固件开始运行)
┌──────────────────────────────────────────────────────────────┐
│ # mlxfwreset -d /dev/mst/mt4123_pciconf0 reset -y │
│ │
│ 内部:发送复位命令 → 停止驱动 → 复位 PCI → 启动驱动 │
│ → 重启 MST → 固件加载成功 │
│ 官方限制:不支持的 reset 级别/类型/同步会直接报错 │
│ 老固件上重复 reset 会报错(一次性) │
└──────────────────────────┬───────────────────────────────────┘
▼
步骤 7 验证(两条独立证据链,见第十二节)
┌──────────────────────────────────────────────────────────────┐
│ # flint -d /dev/mst/mt4123_pciconf0 query → 读 flash │
│ # ibstat → 读运行态 │
│ │
│ 判据:FW Version / Firmware version 是否等于步骤 4 的目标版本│
│ 对照:必须与步骤 2 记录的旧版本不同 │
└──────────────────────────────────────────────────────────────┘
五步骨架 → 七步可执行动作的对应:
课程步骤 1(确认 HCA 类型) → 本流程步骤 1
课程步骤 2(查询 HCA 详细信息) → 本流程步骤 2
课程步骤 3(去官网下载固件) → 本流程步骤 4
课程步骤 4(烧录镜像) → 本流程步骤 5
课程步骤 5(复位并验证) → 本流程步骤 6 + 步骤 7
课程在演示中单列的两件事 → 本流程步骤 3(mst)与解压动作
本节关键记忆:3 个要素 + 2 个工具 + 1 条判读 + 1 个副作用范围
- 3 个要素:-d 设备(来自 mst status)/ -i 镜像(解压后的 .bin,不是 zip)/ b = burn,命令行里唯一的动词
- 2 个工具:flint 写 flash,mlxfwreset -d <dev> reset -y 让新固件开始运行。官方定位是"无需重启机器即可加载更新后的固件"
- 1 条判读:flint 结尾若显示 "To load new FW run mlxfwreset or reboot machine",则还需加载;若未显示,则需重启机器
- 1 个副作用范围:reset 会停驱动、复位 PCI、起驱动、重启 MST,该端口在加载窗口内必然中断;老固件上重复 reset 会报错,不可当作探测手段
十二、第七步:验证——两条独立的证据链
What — 课程给出的验证方式
课程对验证这一步的描述是:在运行 ibstat 命令之前,要先复位固件并重启驱动;ibstat 会给出固件版本,用来与升级开始之前的版本做对比。演示环节进一步说明了操作:检查 mlx5_0 的固件版本确实是 20.33.1048,与预期的目标版本一致。
这个验证方式的正确性需要补一个前提:ibstat 读的是运行态,而 flint 的 query 读的是 flash 内容。这两者不是同一个东西——这正是第十一节那条因果链的延伸。本节把它们并成两条独立的证据链。
12.1 两条证据链的分工
| 证据链 | 命令 | 读的对象 | 能证明什么 | 不能证明什么 |
|---|---|---|---|---|
| ① 存储态 | flint -d <dev> query | flash 里的镜像内容 | 新固件确实写进去了;同时可核对 PSID、Image VSD / Device VSD 是否符合预期 | 不能证明芯片当前正在运行这份固件 |
| ② 运行态 | ibstat | 芯片当前执行状态 | 新固件已经生效并被加载;同时可看到端口的 State、Physical state、Base lid、SM lid 是否正常 | 不能单独证明 flash 里的内容正确 |
12.2 ibstat 输出中与本篇相关的字段
ibstat 的输出分"卡级字段"与"端口级字段"两层。公开文档中的实际输出样例(ConnectX-6 实例)如下,本节只标注与固件升级验证相关的字段:
[root]# ibstat
CA 'mlx5_0'
CA type: MT4123
Number of ports: 1
Firmware version: 20.31.1014 ← 本篇验证的主字段
Hardware version: 0
Node GUID: 0xe8ebd30300fd0788
System image GUID: 0xe8ebd30300fd0788
Port 1:
State: Active ← 升级后应回到 Active
Physical state: LinkUp
Rate: 200
Base lid: 33
LMC: 0
SM lid: 1
Capability mask: 0x2651e848
Port GUID: 0xe8ebd30300fd0788
Link layer: InfiniBand
卡级字段在本篇中的用途:
┌────────────────────┬──────────────────────────────────────────┐
│ CA type │ 型号代号(第九节的 MT4123) │
│ Firmware version │ ★ 验证主字段:与下载时的目标版本比对 │
│ Node GUID │ 设备身份,升级后应保持不变 │
│ System image GUID │ 系统映像身份,同上 │
└────────────────────┴──────────────────────────────────────────┘
端口级字段在本篇中的用途:
┌────────────────────┬──────────────────────────────────────────┐
│ State │ 升级后若异常回落,需重新排查固件 │
│ Physical state │ 端口层面的异常会指向固件缺陷(第三节第三条)│
│ Base lid / SM lid │ 本系列第八篇的判读口诀在这里继续适用 │
└────────────────────┴──────────────────────────────────────────┘
课程给的验证方式是 ibstat,这个方法是对的,但它成立有一个前提条件,而这个前提在现实运维中经常不成立。把这个前提讲清楚,就能解释为什么本篇主张两条证据链都要走。
先明确 ibstat 的验证能力边界。它读的是芯片当前执行状态。如果 Firmware version 变成了目标版本,那么运行态与存储态必然是一致的——因为芯片正在执行的固件只能来自 flash。因此单看 ibstat,在正向场景下是充分的:版本变了,就说明新固件既写进去了也加载了。
但反向场景下它不充分。考虑这几种情况:flash 写失败了(flint 返回非 0,但操作者没看返回值)——此时 flash 里是旧版本,ibstat 读到的也是旧版本,两条链一致地显示"没升成功",这种情况反而好判断。真正麻烦的是下面这一种:flash 写入成功,但加载了错误的一份——比如机器上存在 bank 切换、模块固件 bank 提交这类机制(flint 的选项表里就有 --run_module_image 与 --commit_module_image 两个与模块镜像 bank 相关的开关),此时"写入的那份"和"运行的那份"可能不是同一份。只跑 ibstat 会看到版本变了,从而认为升级成功,但 flash 里的实际状态从未被核对过。
因此两条链的分工可以这样表述:flint query 回答"该写的写了没有",ibstat 回答"该生效的生效了没有"。这两个问题在正常路径上同真同假,在异常路径上可以不同真。而它们的不同真,恰恰是最需要被发现的那些情况。
还有一个容易被忽略的附加价值:flint query 会同时返回 PSID。这意味着验证阶段可以顺手做一次 PSID 复核——确认升级前后 PSID 保持不变。这一点直接呼应第五节的那道闸门:PSID 的作用是"在升级固件版本时保留固件配置",因此一次成功的升级,PSID 必须保持不变。如果升级后 PSID 变了,那不是一次成功的升级,而是一次配置被替换的操作——此时即便 ibstat 显示版本正确,也应当追查原因。
把验证做成"前后对照表"是最不容易出错的形式。升级前记录三行(fw_ver、vendor_part_id、board_id),升级后重读同样三行,逐行比对:第一行应当改变(这是升级的目的),后两行应当不变(这是升级正确性的判据)。三行里只有第一行变了,是成功;三行全变了,是配置被覆盖;二三四行有一行变了,就说明某一步选错了对象。
验证不通过时的排查顺序。按本篇的因果链从下往上查,不要跳步:
- flint 的返回值是什么?是 0 / 1 / 7 中的哪一个?如果是 7,说明烧录根本没开始(用户提示时未选择烧录),此时查命令是否给了交互确认机会
- PSID 是否匹配?如果是 PSID 不匹配导致的拒绝,说明镜像选错了,不是设备坏了。回第十节重选 PSID
- flint query 读到的 FW Version 是什么?如果还是旧版本,说明写入没成功;如果已经是新版本但 ibstat 还是旧的,说明卡在加载步骤,回第十一节检查是否执行了 mlxfwreset 或是否需要重启
- ibstat 的版本对了,但端口状态不对?这时问题已经不在"升级"这个动作上,而在本系列第八篇讲的端口状态判读范围内——按物理状态与逻辑状态的组合定位
本节关键记忆:2 条证据链 + 3 行前后对照 + 4 级排查
- 2 条证据链:flint -d <dev> query 读 flash(证明写进去了),ibstat 读运行态(证明生效了)。两条都必须过
- 3 行前后对照:fw_ver 应改变;vendor_part_id 与 board_id 应保持不变。PSID 变了就说明配置被替换,不是成功升级
- 4 级排查:先看 flint 返回值(7 = 未开始烧录)→ 再看 PSID 是否匹配 → 再区分是"没写进去"还是"没加载" → 最后才回到端口状态排查
- 1 个关键字段:ibstat 的 Firmware version 是版本验证的主字段,CA type 是型号核对字段
十三、OEM 定制固件:为什么流程不同
What — 课程对 OEM 的定义与升级流程差异的说明
课程在这一节明确指出:如果使用的是 OEM 定制固件,HCA 固件升级的过程可能不同。课程随后给出了 OEM 的定义与差异来源:
- OEM(Original Equipment Manufacturer,原始设备制造商):制造并销售使用 NVIDIA 高速网络技术的硬件组件的公司
- OEM 的典型做法:把 NVIDIA 技术集成到自己的产品中,产品可以包括交换机、服务器和其他计算系统
- 型号差异:由系统 OEM 销售的 NVIDIA 产品,可能具有与其 NVIDIA 对应产品不同的型号(may have different model numbers compared to their NVIDIA equivalents)
- 获取方式的差异:因此,获取这些产品的固件发布可能需要不同的方法
- 课程给出的指引:访问 NVIDIA 的 OEM 固件下载页面,那里可以找到获取这些产品固件发布的链接
这几条把差异的来源讲清楚了:差异的根源是"型号不同",型号不同则 PSID 不同,PSID 不同则镜像不同、渠道不同、校验规则也可能不同。下面把这条推导链与官方文档对上。
13.1 从"型号不同"到"流程不同"的推导链
Why — 课程没有展开、但官方文档补齐了的三个环节
课程只说"流程可能不同",没有说不同在哪。MFT 官方文档的 PSID 分配章节补上了这条链上最关键的两个环节:
- 谁定义 PSID。官方文档的适用场景写得非常明确:在某些情况下,OEM 或板卡制造商可能希望使用 NVIDIA 未提供的特定固件配置。而在修改了 INI 文件中的新固件参数之后,用户应当为这个新配置分配一个唯一的 PSID。官方还给出了警告:修改固件参数务必谨慎;错误的固件参数设置可能导致被烧录设备行为未定义
- PSID 的所有权在 OEM。官方在分配流程里要求:使用你自己的厂商符号以保证 PSID 唯一性;如果你不知道自己的厂商符号,请联系你本地的 NVIDIA FAE。这直接推翻了"PSID 总是以 MT_ 开头"这个说法——那是 NVIDIA 自家板卡的厂商符号,OEM 板卡用的是 OEM 自己的符号
把这两点与第十节的下载中心对照,会得到一个完整的差异清单。下表左列是标准流程,右列是 OEM 板卡可能不同的环节,差异的原因写在最右列:
| 流程环节 | 标准流程(NVIDIA 自家板卡) | OEM 板卡的差异 | 差异的原因 |
|---|---|---|---|
| 型号确认 | 型号与 NVIDIA 产品线一一对应 | 型号可能不对应任何 NVIDIA 产品线 | 课程原文:OEM 销售的产品可能具有与其 NVIDIA 对应产品不同的型号 |
| PSID 归属 | 厂商符号为 MT_,由 NVIDIA 分配 | 厂商符号由 OEM 自定,PSID 由 OEM 分配 | 官方要求 使用自有厂商符号以保证唯一性 |
| 镜像来源 | NVIDIA 公开固件下载中心 | NVIDIA OEM 固件下载页面 | 课程原文:获取这些产品的固件发布可能需要不同的方法 |
| 镜像形态 | 标准 .bin 镜像 | 可能包含自定义的固件参数(INI 文件) | 官方流程第 1 步是编写新的固件配置文件(INI 格式),第 3 步才是设置 PSID |
| PSID 校验 | 下载中心的 PSID 与设备 PSID 一致 | 仍受同一条精确匹配规则约束 | 规则本身不变,变的是"匹配什么" |
最后一行是本节最值得强调的一点:PSID 精确匹配这条规则对 OEM 板卡同样成立。第五节说过,标准的 PSID 行为是"设备 PSID 与镜像 PSID 必须完全一致,或者使用 --allow_psid_change 覆盖"。这条规则与板卡是谁做的无关,它检查的是"这份固件配置是不是这块板该用的"。因此在 OEM 板卡上照常用 flint 烧录是安全的——只要镜像的 PSID 是对的。真正的风险不在命令,而在于拿错了镜像。
13.2 官方在 PSID 文档里给出的三条操作顺序
MFT 文档给出了"给定制固件分配新 PSID 并集成"的完整流程,这三条顺序本身就是一条对操作者的约束:
- 编写新的固件配置文件(.INI 格式)
- 按照规定的格式为它分配一个 PSID,并使用自己的厂商符号保证唯一性
- 在新固件配置文件中设置 PSID 参数
这三条流程的主体不是普通运维,而是 OEM 或板卡制造商。它的输入是一份 INI 格式的固件配置文件,输出是一个带自定义 PSID 的固件镜像。对于使用 OEM 板卡的运维工程师,正确的做法是向该 OEM 索取与其板卡匹配的固件,而不是自己走这条流程——课程把这条路径指向 NVIDIA 的 OEM 固件下载页面,说的正是这件事。
但这三条流程对本篇的价值在于它明确了 PSID 的语义边界。PSID 不是"随便起个名字",它是一个有明确分段定义、有唯一性责任归属、被烧录工具用作配置保留依据的结构化标识。理解了这一点,就理解了为什么第八节那五个字段段不能随意改动——每一段都有它的语义,改动任意一段都会改变这份镜像所代表的配置含义。
本节关键记忆:1 个定义 + 1 条推导链 + 5 个差异环节 + 1 条不变规则
- 1 个定义:OEM = 制造并销售使用 NVIDIA 高速网络技术之硬件组件的公司,产品可含交换机、服务器与其他计算系统
- 1 条推导链:型号不同 → PSID 不同 → 镜像不同 → 渠道不同 → 流程不同。课程原文:OEM 销售的产品可能具有与其 NVIDIA 对应产品不同的型号
- 5 个差异环节:型号确认 / PSID 归属(厂商符号由 OEM 自定)/ 镜像来源(OEM 下载页)/ 镜像形态(可能含自定义 INI 参数)/ PSID 校验对象
- 1 条不变规则:PSID 精确匹配对 OEM 板卡同样成立——它检查"这份配置是不是这块板该用的",与板卡厂商无关。真正的风险是拿错镜像,不是命令
十四、FAQ 高频问答(20 组)
本节围绕 HCA 固件升级的 20 个高频易错点展开,覆盖标识符辨析、工具职责、命令语义、安全机制、验证与 OEM 六类。答案中的工具名、命令行语法、参数语义、返回值定义、PSID 字段结构与下载中心导航结构,均引自文末「参考资料」列出的 NVIDIA MFT 官方文档。
- Q1. mlx5_0 能告诉我这是不是 ConnectX-6 卡吗?
不能。mlx5_0 是驱动族名加枚举序号,不携带型号信息。命名规则是"驱动族 mlx5 + 内核枚举序号 _0",由 PCI 设备的枚举顺序决定。公开文档中可以看到同一个 hca_id: mlx5_0 对应 vendor_part_id: 4119,另一台机器上同一个 mlx5_0 对应 vendor_part_id: 4099。查型号要用 ibstat 的 CA type(形如 MT4123)或 ibv_devinfo 的 vendor_part_id。
- Q2. mt4123 和 PSID 是一回事吗?课程把它们讲混了?
完全不是两个东西,课程转写在这里把它当成了同一个值。mt4123 里的 4123 是 PCI Device ID 的十进制形式,等于 ibv_devinfo 的 vendor_part_id,标识的是硬件;PSID 是 16 个 ASCII 字符(形如 MT_0000000223),标识的是固件配置。同一个 vendor_part_id 可以有不同 PSID,因为改固件参数集会换 PSID 而不换芯片。
- Q3. mlxfwmanager 和 mlxfwreset 有什么区别?
职责完全不同,这是本篇最高频的一处误听。mlxfwmanager 是固件更新与查询工具,它扫描系统上可用的 NVIDIA 设备(仅 MST PCI 设备)并执行固件更新,主要选项包括 -u/--update(更新固件)、-d(指定设备)、-i(指定镜像文件)、--query(查询)、--list-content(列出归档镜像内容)。mlxfwreset 是固件加载工具,它的作用是让用户无需重启机器即可在网卡/交换机上加载更新后的固件。烧录之后负责 reset 并加载的是后者。
- Q4. flint 的返回值 7 是什么意思?为什么不能只判断成功失败?
7 是一个既非成功也非失败的第三种状态:用户在提示时没有选择烧录新固件,因此烧录过程被中止。MFT 文档定义三个返回值:0 成功完成、1 发生错误、7 用户未选择烧录,过程被中止。只判断 $? -eq 0 的脚本能正确把它当失败;但只判断 $? -ne 1 的脚本会把它误判为成功。自动化脚本必须显式区分三个值。
- Q5. flint 命令末尾的 b 是什么?写成 burn 行不行?
两者完全等价。MFT 文档的命令参数表写作 b[urn],方括号表示缩写可选。b 是整个命令行里唯一的动词——-d 和 -i 都是参数。课程把它称作"小但重要的东西",实质就是指它是唯一的命令词。官方给出的完整形态是 flint -d <device> -i <fw-file> burn。
- Q6. PSID 到底由哪几段组成?为什么要定长 16 个字符?
五段共 16 个 ASCII 字符:厂商符号 3 + 板型符号 3 + 板版本符号 3 + 参数集编号 4 + 保留位 3。官方规定如果指定的 PSID 长度不足 16 个字符,剩余字符由烧录工具以二进制 0 填充。官方示例 MT_0030000001 的拆解是:MT_ 厂商符号、003 板型符号、000 板版本符号、0001 参数集编号。定长的作用是让"两个 PSID 是否完全一致"成为一个廉价的逐位比较,这正是烧录时精确匹配校验的实现基础。
- Q7. PSID 一定以 MT_ 开头吗?
不对,只有 NVIDIA 自家板卡如此。MT_ 是 NVIDIA 的厂商符号。MFT 文档在讲给定制固件分配 PSID 时明确要求:使用你自己的厂商符号以保证 PSID 唯一性;如果你不知道自己的厂商符号,请联系你本地的 NVIDIA FAE。因此 OEM 板卡的 PSID 前缀是 OEM 自己的符号,课程的"总是以 MT_ 开头"这个说法需要按厂商加以限定。
- Q8. 下载时页面上的 OPN 和 PSID 两个下拉框有什么区别?都要选吗?
都要选,二者收窄的是不同维度。OPN(Ordering Part Number,订购件号)是商业件号,决定"买的是哪一款"——官方示例中 ConnectX-7 Cluster 的 OPN 是 MCX750500B-0D00、Storage 的是 MCX755206AS-NEA,同一产品线因用途不同而 OPN 不同。PSID 是这块卡上固件配置的唯一标识,对应上例分别是 MT_0000000891 与 MT_0000000892,必须从本机 ibv_devinfo 的 board_id 现场读出,不能推断。官方文档给出的操作是:进 CURRENT VERSIONS 标签页 → 依次选版本、OPN、PSID → 点链接下载 .bin。
- Q9. /dev/mst/ 里的设备名怎么和 ibv_devinfo 对上号?
路径里的数字就是 vendor_part_id。格式是 /dev/mst/mt<dev_id>_pci{_cr0|conf0}。官方烧录示例中的 /dev/mst/mt4123_pciconf0,其 4123 与该卡 vendor_part_id: 4123 一致;Oracle 的示例文档中 vendor_part_id: 26428、flint 查询的 Device ID: 26428 与设备名 mt26428_pci_cr0 三处同数。而 lspci 输出里的十六进制 ID 是同一数字的另一种进制(4123 = 0x101b)。
- Q10. _cr0 和 _conf0 有什么区别?该选哪个?
两种后缀对应两条不同的硬件访问路径,选择原则是照抄 mst status 的输出,不要自己拼。mstflint 的 README 说明:设备可通过 lspci 显示的 PCI ID 或 IB 设备名访问,走 PCI Memory Mapping;也可以走 PCI 配置周期(/proc/bus/pci/<dev.fn>)。官方对配置周期访问的评价是更慢且不如内存访问安全,只在前两种方式都不工作时才使用。另外注意通常需要 root 权限,且 mst start 仅适用于 Linux。
- Q11. mst status 显示服务没启用,应该直接 mst start 吗?
应该,而且这是官方指引里的第一步。NVIDIA 固件升级指引把烧录流程的第一步列为 mst start,并注明此步骤仅适用于 Linux 操作系统(Windows 一栏标为不适用)。它的作用是在 /dev/mst/ 目录下创建代表 NVIDIA HCA 设备的特殊文件。要先确认的是 MFT 包本身是否已安装——装了 MLNX_OFED 通常已带 MFT,可先跑 ofed_info 确认驱动存在,缺失时需单独安装 MFT。
- Q12. 一台机器插了两块 HCA,怎么确保烧到的是对的那一块?
靠第三节那张前后对照表,而不是靠设备名。多卡机器上所有卡的 mlx5_N 序号都可能与你的预期不一致,因此必须逐卡采集 ibv_devinfo 的四项信息,并按 vendor_part_id 区分型号——只有 vendor_part_id 能唯一确定要烧的那一块(因为 hca_id 只是枚举序号)。然后用该 vendor_part_id 去 mst status 输出里定位对应的 /dev/mst/ 路径,作为 flint -d 的参数。
- Q13. flint 默认是容错烧录,那 -nofs 什么时候才该用?
本单元不应该用它。官方对 -dual_image 选项的说明给出了当前默认算法的准确描述:当前的默认容错烧录过程只烧写一份镜像,并写在交替的位置上;而 -dual_image 才是"烧写两份镜像",被标注为"以前的默认算法"。容错的收益是:写入过程中断电时,旧镜像所在扇区未被触碰,设备仍可启动旧版本。-nofs 的语义是"以非容错方式烧录",只应在已经确认设备身份、且明确需要该模式时才用。
- Q14. 烧录时提示 PSID 不匹配,是设备坏了吗?
不是设备坏了,是镜像选错了。标准行为是设备 PSID 与镜像 PSID 必须完全一致,或者使用 --allow_psid_change 标志覆盖这一要求。这条校验的作用正是防止把不属于这块板的固件配置刷进去。正确处理方式是回第十节按本机 board_id 重新选择镜像,而不是加 --allow_psid_change 强行绕过。注意这道闸门与容错烧录防的是不同事故:容错防"写到一半断电",PSID 校验防"刷错版本"。
- Q15. 为什么烧完立刻 ibstat 看到的还是旧版本?
因为烧录和加载是两个独立动作,你只做了第一个。flint 操作的是 flash 里的镜像存储,mlxfwreset 操作的是芯片的执行状态。写入二进制与让芯片开始执行这份二进制是两件事。此时 ibstat 读的是运行态,因此仍是旧版本。官方给出的判据是看 flint 烧录结尾是否显示 To load new FW run mlxfwreset or reboot machine:显示则还需加载,未显示则需重启机器。
- Q16. mlxfwreset 输出的 "reset level 3" 是什么意思?可以指定别的级别吗?
3 对应"驱动重启与 PCI 复位",语法只接受 0 / 3 / 4 三个值。官方语法是 mlxfwreset -d <device> reset-[y] [--level <0,3,4>] [--type <0..2>] [--sync <0,1,2>]。公开文档记录的一次实际执行输出是:停止驱动、复位 PCI、启动驱动、重启 MST、固件加载成功,其中显示的级别为 3: Driver restart and PCI reset。官方限制清单明确:执行一个由 query 命令显示为不支持的 reset 级别/类型/同步会产生错误——这是设备能力边界,不是可随意填的参数。
- Q17. mlxfwreset 失败后可以再执行一次吗?
在老固件上不可以,重复执行会报错。官方限制清单原文:在老固件上,一次成功 reset 之后再尝试查询或复位会产生错误,因为加载新固件的命令已经发送给固件。这说明 reset 是一次性动作、不可重复。因此不要把重复 reset 当作探测手段;需要确认状态时应改用查询类命令(mlxfwreset status / flint query / ibstat)。
- Q18. 只跑 ibstat 确认版本号变了,够不够?
正向场景够,但作为标准验证流程不够,应该跑两条证据链。flint -d <dev> query 读的是 flash 存储态,ibstat 读的是运行态。两者在正常路径上同真同假,但在异常路径上可以不同真——例如机器上存在模块固件 bank 机制(flint 选项表里的 --run_module_image / --commit_module_image)时,"写入的那份"与"运行的那份"可能不同。此外 flint query 还会返回 PSID,可用于确认升级前后 PSID 保持不变——PSID 变了说明配置被替换,不是成功升级。
- Q19. flint 除了烧录还能干什么?哪些功能我不要碰?
官方定义五项功能,本单元只用第一项与第三项。五项是:烧录固件镜像、烧录扩展 ROM 镜像(命令 brom/drom/rrom/qrom)、查询固件属性(q[uery] [full])、命令行执行多种 flash 操作、禁用/启用硬件寄存器访问(set_key / hw_access)。第四项的底层操作(e[rase] <addr>、rw/ww、rb/wb)是官方标注用于调试/生产的,本单元不要碰。另外硬件访问密钥丢失后无法用该工具恢复,官方给出的恢复途径是接 flash-not-present 跳线、以 flash recovery 模式启动、重烧固件、重设密钥。
- Q20. 用 OEM 定制固件的机器,升级流程到底哪里不同?命令还能用吗?
命令完全能用,差异在镜像获取与 PSID 归属上。差异链是:OEM 销售的产品可能具有与其 NVIDIA 对应产品不同的型号 → PSID 不同(厂商符号由 OEM 自定,官方要求用自有符号保证唯一性)→ 镜像不同 → 获取渠道不同(NVIDIA OEM 固件下载页面)。MFT 文档还给出了官方顺序:编写 .INI 格式的固件配置文件 → 分配带自有厂商符号的唯一 PSID → 在配置文件中设置 PSID 参数。但 flint 的 PSID 精确匹配规则对 OEM 板卡同样成立——它检查的是"这份配置是不是这块板该用的",与厂商无关。正确做法是向该 OEM 索取匹配其板卡的固件。
FAQ 总纲(口诀式速记)
- 3 个标识符:4123 = PCI Device ID(-d 用)/ MT4123 = 型号(下载页用)/ MT_0000000223 = PSID(镜像用)。稳定性依次递减
- 1 个最易错:mlx5_0 是枚举序号不是型号;mlxfwreset 才是加载工具,mlxfwmanager 是更新/查询工具
- 4 项采集:hca_id / fw_ver / vendor_part_id / board_id,少一项就有一段流程走不通
- 1 个 PSID 结构:厂商(3) + 板型(3) + 板版本(3) + 参数集(4) + 保留(3) = 16 字符,不足以 \0 补齐;不总是 MT_ 开头
- 1 个设备名格式:/dev/mst/mt<vendor_part_id>_pci{_cr0|conf0},照抄 mst status 输出;mst start 仅 Linux、通常需 root
- 2 层下载导航:产品线 × 协议 → CURRENT VERSIONS → 版本 / OPN / PSID 三个下拉框
- 3 个烧录要素:-d 设备 / -i 解压后的 .bin(不是 zip)/ b = burn,唯一动词
- 2 道安全闸门:容错烧录(单镜像交替位置,防断电)与 PSID 精确匹配(防刷错版本);-nofs 与 --allow_psid_change 本单元都不该用
- 3 个返回值:0 成功 / 1 错误 / 7 用户未选择烧录,过程被中止
- 1 个加载判据:flint 结尾显示 "To load new FW run mlxfwreset or reboot machine" 则需加载;未显示则需重启
- 2 条证据链:flint query 读 flash(写进去了) + ibstat 读运行态(生效了)
- 3 行前后对照:fw_ver 应变,vendor_part_id 与 board_id 应不变
- 1 个 reset 限制:--level 只接受 0 / 3 / 4;老固件上重复 reset 会报错,不可当探测手段
- 5 个 OEM 差异:型号 / PSID 归属 / 镜像来源 / 镜像形态 / 校验对象;但 PSID 精确匹配规则不变
十五、Roadmap 后续预告
本篇是 InfiniBand 专题的第十四篇。它的位置是:本系列第八篇《子网初始化:拓扑发现、LID 分配、路径计算与子网激活》讲清了 fabric 怎么从线缆变成能传数据的子网,第九篇《SM 监控与拓扑变化:选举、故障切换、扫描与重收敛》讲清了子网建立之后如何持续运行,本系列第十一篇《路由引擎:算法原理、选型对照与 OpenSM 配置验证》讲清了路径计算这一步内部用什么算法实现。本篇补上的是这条链路最前面的那一环——设备侧的固件本身是否处于可用状态。这四篇合起来覆盖了"设备就绪 → 拓扑发现 → 路径计算 → 子网激活 → 持续监控与重收敛"的完整链路。
接下来的方向,按由单卡固件向整机就绪度检查深入的顺序包括:
- 交换机固件升级:本篇全部命令面向 HCA。交换机侧的设备路径形态、升级前置条件与风险点都不同,尤其是升级过程对子网可用性的影响——这与升级单张 HCA 的影响范围完全不同
- OFED 驱动版本升级流程:本篇第三节把"OFED 与固件版本失配"列为第一触发条件,但没有展开 OFED 本身的升级步骤、mlnxinstall 类安装器的行为、以及 --fw-update-only 这类只升固件不升驱动的选项
- 固件签名与 secure boot 密钥体系:本篇提到 flint 查得出 Security Attributes 与 secure-fw 字样,但没有展开固件签名的验证流程、HMAC 签名命令与密钥管理
- 模块固件 bank 机制:本篇 FAQ Q18 提到 flint 有 --run_module_image 与 --commit_module_image 两个开关,但没有展开模块级固件 bank 的切换语义与提交时机——这正是"写入的那份"与"运行的那份"可能不一致的机制根源
- BlueField DPU 的固件升级:本篇的流程不适用于 DPU,DPU 的固件组成、升级方式与失败恢复路径都不同
- 批量升级的编排与失败回滚:本篇讲的是单机单卡流程。几百台机器的批量升级如何编排、如何定义部分失败的处置策略、如何在回滚时保证 GUID 等身份不被改动,是一个需要单独设计的工程问题
- 固件版本与子网性能的关联:固件版本对链路训练收敛时间、端口恢复时间、错误计数的影响,需要用 perfquery 与 ibqueryerrors 在固定拓扑上做前后对照测量——这类数字必须实测,不能推测
- OEM 板卡在真实交付中的固件管理:本篇第十三节讲了 OEM 固件的原则性差异,但没有覆盖 OEM 固件版本追溯、批量核对、以及与 NVIDIA 侧版本矩阵的对照方法
如果你在实践中遇到具体问题——例如 flint 返回 7 导致烧录没开始、PSID 匹配被拒、烧录成功但 ibstat 版本没变、升级后端口状态异常回落、多卡机器上烧错了目标——欢迎在评论区留言,我会挑出共性问题单独扩展一篇专题。

浙公网安备 33010602011771号