第3章 物理层与MCTP传输 - 页码41
NVMe-MI 1 min read

第3章 物理层与MCTP传输 - 页码41

Blog Author

我们现在深入理解 NVMe-MI 中 消息完整性检查(Message Integrity Check, MIC)机制,特别是其在 CRC-32C 校验计算中的应用流程。以下为全面分解与总结,帮助你真正吃透这一机制。


📦 什么是 Message Integrity Check (MIC)?

MIC 是一个用于校验 NVMe-MI 消息是否完整可靠 的机制。在带外通信中尤为重要,它使用一种标准的 32-bit CRC(CRC-32C) 校验,保护传输的数据不被篡改或破坏。

注意: 仅在 IC 位为 1 的 NVMe-MI 消息中计算和携带 MIC(如带外传输)。在带内机制中,IC 恒为 0,因此不使用 MIC。


🧮 MIC 计算过程(发送方)

这是消息发送方(例如 Management Controller)计算 CRC 的完整过程:

步骤:

  1. 初始化 CRC 寄存器:
  2. 设置为 0xFFFFFFFF
  3. 相当于对消息体最低 32 位(Dword 0)求按位反转。

  4. 准备消息体:

  5. 将原始消息后面附加 4 字节(32 位)0x00000000 占位符,用于后续 MIC 填写。

  6. 构造 M(x) 多项式(消息多项式):

  7. 把整个消息看作比特流;
  8. 位反转:对每个字节中的位进行 bit 0 与 bit 7 对调(反射);
  9. 构成消息的多项式表示。

  10. 用生成多项式 1EDC6F41h 进行除法:

  11. 得到 32-bit 的 CRC 余数 R(x)

  12. 每字节反转(RefOut):

  13. R(x) 每个字节再次执行 bit 反转,得到 R′(x)

  14. 最终结果按位反转(XorOut):

  15. R′(x) 执行按位非运算,得出 R′′(x)

  16. 填入 MIC 字段:

  17. R′′(x) 写入消息末尾的 MIC 区域。

✅ CRC 校验示例图解(Figure 22)

M(x):为反射后的消息二进制流表示,按位排列
Byte 0  Byte 1 ... Byte Y-1
 ↓        ↓         ↓
bit 0     bit 0     bit 0
bit 1     bit 1     bit 1
...
bit 7     bit 7     bit 7

最终 MIC = Invert(RefOut(Divide(RefIn(M(x)), Poly)))


🧪 MIC 验证过程(接收方)

消息接收者如何验证 MIC 正确性:

  1. 保存接收到的 MIC 字段
  2. 清零 MIC 字段为 0h
  3. 初始化 CRC 寄存器为 0xFFFFFFFF
  4. 重新构造反射后的 M(x)
  5. 再次除以多项式,得到余数 R(x)
  6. 执行 RefOut(每字节反射)
  7. 执行 XorOut(按位非)→ 得到 R′′(x)
  8. 比较步骤 1 中的 MIC 与 R′′(x)

若一致,则说明该消息完整且未损坏。


🔢 CRC-32C 参数一览(Rocksoft Model)

参数
Name CRC-32C
Width 32 bits
Poly 0x1EDC6F41
Init 0xFFFFFFFF
RefIn True
RefOut True
XorOut 0xFFFFFFFF
Check 0xE3069283

这个参数组合与大多数硬件 CRC 引擎、Intel Slicing-by-8 算法兼容。


🔧 如果你想测试:

我可以为你提供:

  • Python 示例代码:使用 crc32cbinascii.crc32 模拟计算 MIC;
  • 结构化流程图:完整展现 MIC 计算/验证流程;
  • Appendix B 示例解析:帮你对照人工构造的 MIC 示例做校验。

你是否希望我编写一段 CRC32C 的 Python 代码,来 演示一个带 MIC 的 NVMe-MI 消息 CRC 校验计算?或者我们继续分析 §3.2 的 Out-of-Band 消息传输机制