AIGC标识 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 配置项的读写

一、开篇必读:十组误听与一处需要收紧的表述

本节已在开头的 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 单独升级这个事实,并列出三种应当考虑升级的情形。这三条是本节的核心,逐条拆开讲:

  1. OFED 版本与固件版本失配(the OFED version and the firmware version are out of sync)
  2. 安装固件的过程中发现了问题(an issue was noticed during the installation of the firmware)
  3. 固件版本已损坏,或存在已被修复的缺陷(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 设备上。这个包里的工具有若干个,但本单元只使用其中三个,课程明确点了名并给出了分工:

  1. mst 服务 —— 在升级固件之前查询所需信息
  2. flint —— 把镜像烧录到设备上
  3. 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,并逐条列出它执行的五项功能。这五条是本节的第一手依据:

  1. 把二进制固件镜像烧录到连接到适配器或交换机设备的 flash 器件上
  2. 把扩展 ROM(Expansion ROM)镜像烧录到连接到适配器的 flash 器件上
  3. 查询固件属性(版本、GUID、UID、MAC、PSID 等)
  4. 支持从命令行对 flash 存储器执行多种操作(用于调试/生产)
  5. 禁用/启用对设备硬件寄存器的访问,并更改用于启用的密钥(此特性仅在被烧录的固件支持时有效)

逐条对照课程原话,会发现课程把第 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 三个值——这是设备能力的边界,不是可以随便填的参数。

安全视角 — 容错烧录与 PSID 校验:两道互相独立的闸门

把 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 — 型号不是标签,是后续三处选择的输入

把"确认型号"这一步的输出往后追,会发现它不是一个孤立的确认动作,而是三个分支条件的共同输入:

  1. 决定下载路径。NVIDIA 固件下载中心的主页面是一个按产品线 × 网络协议组织的二维表。课程描述的导航动作——"找到 HCA 类型和协议,本例是 ConnectX-6 与 InfiniBand VPI"——就是在这张表的两个维度上各选一格。选错产品线会走到没有对应固件的页面,选错协议会拿到 VPI 之外的、以太网侧的固件
  2. 决定设备 ID。型号后面跟着一串十六进制的 PCI Device ID,而这串 ID 的十进制形式正是 /dev/mst/ 设备路径里那个数字。第九节会给出完整的换算关系
  3. 决定"升级哪一块"。课程明确说本次升级的对象是两块卡中的 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 一定要"定长 + 分段 + 唯一厂商符号"

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 用官方示例解码一遍

结构视角 — PSID 字段结构与它在选镜像流程中的位置

把官方给的 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 — 课程给出的两条命令与它们各自的目的

课程在下载镜像之后、正式烧录之前,插入了两条命令,并明确说接下来这一段"非常重要":

  1. mst status —— 课程说明这条命令会检查 mst 是否已启用,以及 mst 设备的路径是什么
  2. 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、MT4123、MT_0000000223

一次固件升级的操作对象上挂着三个编号,它们在字面上高度相似,混淆的后果也最直接。把它们并排看,能把本篇前八节的知识一次性收拢。

标识符出现位置它标识的对象谁消费它混淆后的后果
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 — 课程给出的下载路径与镜像形态

课程对这一步的描述包含三个要点:

  1. 导航到 NVIDIA 固件下载站点,按 HCA 类型与协议查找。课程给的实例是 ConnectX-6 与 InfiniBand VPI;进入后会看到一个选择固件版本的界面
  2. 下载得到的镜像文件是一个 zip 包,需要解压后才能使用。课程明确说本例使用命令行上的 unzip 来解压文件以备使用
  3. 必须确保把正确的固件 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 一列)。

点击对应格子后进入该产品的固件下载中心矩阵页。官方文档对这一层的操作给出了明确的三个步骤:

  1. 选择 CURRENT VERSIONS 标签页
  2. 依次选择三个下拉框:版本(Version,当前版)、OPN(订购件号)、PSID
  3. 点击对应的固件链接下载 .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,这个方法是对的,但它成立有一个前提条件,而这个前提在现实运维中经常不成立。把这个前提讲清楚,就能解释为什么本篇主张两条证据链都要走。

先明确 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),升级后重读同样三行,逐行比对:第一行应当改变(这是升级的目的),后两行应当不变(这是升级正确性的判据)。三行里只有第一行变了,是成功;三行全变了,是配置被覆盖;二三四行有一行变了,就说明某一步选错了对象。

验证不通过时的排查顺序。按本篇的因果链从下往上查,不要跳步:

  1. flint 的返回值是什么?是 0 / 1 / 7 中的哪一个?如果是 7,说明烧录根本没开始(用户提示时未选择烧录),此时查命令是否给了交互确认机会
  2. PSID 是否匹配?如果是 PSID 不匹配导致的拒绝,说明镜像选错了,不是设备坏了。回第十节重选 PSID
  3. flint query 读到的 FW Version 是什么?如果还是旧版本,说明写入没成功;如果已经是新版本但 ibstat 还是旧的,说明卡在加载步骤,回第十一节检查是否执行了 mlxfwreset 或是否需要重启
  4. 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 分配章节补上了这条链上最关键的两个环节:

  1. 谁定义 PSID。官方文档的适用场景写得非常明确:在某些情况下,OEM 或板卡制造商可能希望使用 NVIDIA 未提供的特定固件配置。而在修改了 INI 文件中的新固件参数之后,用户应当为这个新配置分配一个唯一的 PSID。官方还给出了警告:修改固件参数务必谨慎;错误的固件参数设置可能导致被烧录设备行为未定义
  2. 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 并集成"的完整流程,这三条顺序本身就是一条对操作者的约束:

  1. 编写新的固件配置文件(.INI 格式)
  2. 按照规定的格式为它分配一个 PSID,并使用自己的厂商符号保证唯一性
  3. 在新固件配置文件中设置 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 官方文档。

  1. 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。

  2. Q2. mt4123 和 PSID 是一回事吗?课程把它们讲混了?

    完全不是两个东西,课程转写在这里把它当成了同一个值。mt4123 里的 4123 是 PCI Device ID 的十进制形式,等于 ibv_devinfo 的 vendor_part_id,标识的是硬件;PSID 是 16 个 ASCII 字符(形如 MT_0000000223),标识的是固件配置。同一个 vendor_part_id 可以有不同 PSID,因为改固件参数集会换 PSID 而不换芯片。

  3. Q3. mlxfwmanager 和 mlxfwreset 有什么区别?

    职责完全不同,这是本篇最高频的一处误听。mlxfwmanager 是固件更新与查询工具,它扫描系统上可用的 NVIDIA 设备(仅 MST PCI 设备)并执行固件更新,主要选项包括 -u/--update(更新固件)、-d(指定设备)、-i(指定镜像文件)、--query(查询)、--list-content(列出归档镜像内容)。mlxfwreset 是固件加载工具,它的作用是让用户无需重启机器即可在网卡/交换机上加载更新后的固件。烧录之后负责 reset 并加载的是后者。

  4. Q4. flint 的返回值 7 是什么意思?为什么不能只判断成功失败?

    7 是一个既非成功也非失败的第三种状态:用户在提示时没有选择烧录新固件,因此烧录过程被中止。MFT 文档定义三个返回值:0 成功完成、1 发生错误、7 用户未选择烧录,过程被中止。只判断 $? -eq 0 的脚本能正确把它当失败;但只判断 $? -ne 1 的脚本会把它误判为成功。自动化脚本必须显式区分三个值。

  5. Q5. flint 命令末尾的 b 是什么?写成 burn 行不行?

    两者完全等价。MFT 文档的命令参数表写作 b[urn],方括号表示缩写可选。b 是整个命令行里唯一的动词——-d 和 -i 都是参数。课程把它称作"小但重要的东西",实质就是指它是唯一的命令词。官方给出的完整形态是 flint -d <device> -i <fw-file> burn。

  6. Q6. PSID 到底由哪几段组成?为什么要定长 16 个字符?

    五段共 16 个 ASCII 字符:厂商符号 3 + 板型符号 3 + 板版本符号 3 + 参数集编号 4 + 保留位 3。官方规定如果指定的 PSID 长度不足 16 个字符,剩余字符由烧录工具以二进制 0 填充。官方示例 MT_0030000001 的拆解是:MT_ 厂商符号、003 板型符号、000 板版本符号、0001 参数集编号。定长的作用是让"两个 PSID 是否完全一致"成为一个廉价的逐位比较,这正是烧录时精确匹配校验的实现基础。

  7. Q7. PSID 一定以 MT_ 开头吗?

    不对,只有 NVIDIA 自家板卡如此。MT_ 是 NVIDIA 的厂商符号。MFT 文档在讲给定制固件分配 PSID 时明确要求:使用你自己的厂商符号以保证 PSID 唯一性;如果你不知道自己的厂商符号,请联系你本地的 NVIDIA FAE。因此 OEM 板卡的 PSID 前缀是 OEM 自己的符号,课程的"总是以 MT_ 开头"这个说法需要按厂商加以限定。

  8. 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。

  9. 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)。

  10. Q10. _cr0 和 _conf0 有什么区别?该选哪个?

    两种后缀对应两条不同的硬件访问路径,选择原则是照抄 mst status 的输出,不要自己拼。mstflint 的 README 说明:设备可通过 lspci 显示的 PCI ID 或 IB 设备名访问,走 PCI Memory Mapping;也可以走 PCI 配置周期(/proc/bus/pci/<dev.fn>)。官方对配置周期访问的评价是更慢且不如内存访问安全,只在前两种方式都不工作时才使用。另外注意通常需要 root 权限,且 mst start 仅适用于 Linux。

  11. Q11. mst status 显示服务没启用,应该直接 mst start 吗?

    应该,而且这是官方指引里的第一步。NVIDIA 固件升级指引把烧录流程的第一步列为 mst start,并注明此步骤仅适用于 Linux 操作系统(Windows 一栏标为不适用)。它的作用是在 /dev/mst/ 目录下创建代表 NVIDIA HCA 设备的特殊文件。要先确认的是 MFT 包本身是否已安装——装了 MLNX_OFED 通常已带 MFT,可先跑 ofed_info 确认驱动存在,缺失时需单独安装 MFT。

  12. Q12. 一台机器插了两块 HCA,怎么确保烧到的是对的那一块?

    靠第三节那张前后对照表,而不是靠设备名。多卡机器上所有卡的 mlx5_N 序号都可能与你的预期不一致,因此必须逐卡采集 ibv_devinfo 的四项信息,并按 vendor_part_id 区分型号——只有 vendor_part_id 能唯一确定要烧的那一块(因为 hca_id 只是枚举序号)。然后用该 vendor_part_id 去 mst status 输出里定位对应的 /dev/mst/ 路径,作为 flint -d 的参数。

  13. Q13. flint 默认是容错烧录,那 -nofs 什么时候才该用?

    本单元不应该用它。官方对 -dual_image 选项的说明给出了当前默认算法的准确描述:当前的默认容错烧录过程只烧写一份镜像,并写在交替的位置上;而 -dual_image 才是"烧写两份镜像",被标注为"以前的默认算法"。容错的收益是:写入过程中断电时,旧镜像所在扇区未被触碰,设备仍可启动旧版本。-nofs 的语义是"以非容错方式烧录",只应在已经确认设备身份、且明确需要该模式时才用。

  14. Q14. 烧录时提示 PSID 不匹配,是设备坏了吗?

    不是设备坏了,是镜像选错了。标准行为是设备 PSID 与镜像 PSID 必须完全一致,或者使用 --allow_psid_change 标志覆盖这一要求。这条校验的作用正是防止把不属于这块板的固件配置刷进去。正确处理方式是回第十节按本机 board_id 重新选择镜像,而不是加 --allow_psid_change 强行绕过。注意这道闸门与容错烧录防的是不同事故:容错防"写到一半断电",PSID 校验防"刷错版本"。

  15. Q15. 为什么烧完立刻 ibstat 看到的还是旧版本?

    因为烧录和加载是两个独立动作,你只做了第一个。flint 操作的是 flash 里的镜像存储,mlxfwreset 操作的是芯片的执行状态。写入二进制与让芯片开始执行这份二进制是两件事。此时 ibstat 读的是运行态,因此仍是旧版本。官方给出的判据是看 flint 烧录结尾是否显示 To load new FW run mlxfwreset or reboot machine:显示则还需加载,未显示则需重启机器。

  16. 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 级别/类型/同步会产生错误——这是设备能力边界,不是可随意填的参数。

  17. Q17. mlxfwreset 失败后可以再执行一次吗?

    在老固件上不可以,重复执行会报错。官方限制清单原文:在老固件上,一次成功 reset 之后再尝试查询或复位会产生错误,因为加载新固件的命令已经发送给固件。这说明 reset 是一次性动作、不可重复。因此不要把重复 reset 当作探测手段;需要确认状态时应改用查询类命令(mlxfwreset status / flint query / ibstat)。

  18. Q18. 只跑 ibstat 确认版本号变了,够不够?

    正向场景够,但作为标准验证流程不够,应该跑两条证据链。flint -d <dev> query 读的是 flash 存储态,ibstat 读的是运行态。两者在正常路径上同真同假,但在异常路径上可以不同真——例如机器上存在模块固件 bank 机制(flint 选项表里的 --run_module_image / --commit_module_image)时,"写入的那份"与"运行的那份"可能不同。此外 flint query 还会返回 PSID,可用于确认升级前后 PSID 保持不变——PSID 变了说明配置被替换,不是成功升级。

  19. 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 模式启动、重烧固件、重设密钥。

  20. 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 版本没变、升级后端口状态异常回落、多卡机器上烧错了目标——欢迎在评论区留言,我会挑出共性问题单独扩展一篇专题。


posted @ 2026-10-05 22:14  左扬  阅读(4)  评论(0)    收藏  举报