2、UFS基础:UFS协议简介、物理层、链路层、传输层、命令集与描述符
UFS(Universal Flash Storage)并不是“更快的eMMC”,而是一套带有多层协议栈、支持全双工通信和命令队列的存储子系统。驱动适配的第一步,不是急着写寄存器,而是把UFS的分层模型、命令流转路径和描述符体系建立成一张清晰的心智地图。只有理解了“命令从主机到NAND颗粒之间经过了什么”,后续的初始化、电源管理、错误恢复才有落脚点。
一、UFS协议栈的分层结构
UFS采用类似网络协议的分层设计,自上而下分为应用层、传输层、链路层和物理层。应用层对应UFS命令集与描述符,负责表达“读什么、写什么、配置什么”;传输层负责将命令、数据和响应封装为UPIU(UFS Protocol Information Unit);链路层负责MIPI UniPro的链路管理、流量控制和错误检测;物理层则是MIPI M-PHY,负责电气信号、速率档位和功耗状态。
这种分层带来的直接好处是:驱动工程师可以按层定位问题。命令超时可能是传输层的UPIU响应问题,链路训练失败属于UniPro层,而信号完整性、眼图闭合则属于M-PHY层。分层不清,排障就会变成“盲猜寄存器”。
二、物理层与链路层:先“通”再“快”
物理层决定UFS能跑多快。M-PHY支持HS-G1到HS-G5,速率逐代翻倍,同时支持PWM低速模式用于初始化。每条Lane是差分信号,常见配置为1条或2条Lane。驱动在初始化阶段通常先以低速PWM建立通信,再协商进入HS模式。
链路层由UniPro负责,核心任务是建立可靠的Lane连接。它要完成链路启动、Lane对齐、能力协商、流量控制和CRC校验。如果链路层没有完成初始化,传输层的UPIU根本无法发出。因此,驱动日志中若出现“link startup failed”或“lane alignment timeout”,应优先检查M-PHY供电、参考时钟、复位时序和Lane映射,而不是怀疑命令集。
三、传输层与命令集:UPIU是核心载体
传输层把上层请求封装成UPIU。一次典型的读操作包含:主机发送命令UPIU,设备返回数据IN UPIU,最后返回响应UPIU。写操作则是命令UPIU、数据OUT UPIU、响应UPIU。UFS支持命令队列,多个命令可以并行排队,这也是它比eMMC更适合高并发场景的原因。
UFS命令集主要基于SCSI命令集,常见命令包括READ(10)、WRITE(10)、INQUIRY、TEST UNIT READY、REQUEST SENSE等。除此之外,UFS还定义了查询请求,用于读写描述符、属性和标志。驱动适配中,查询请求往往比SCSI命令更早出现,因为设备枚举和配置依赖描述符读取。
典型读命令流程:
1. 主机写入UTP Transfer Request
2. 传输层生成 Command UPIU
3. UniPro封装并发送到设备
4. 设备返回 Data IN UPIU
5. 设备返回 Response UPIU
6. 主机检查状态并释放请求
四、描述符、属性与标志:设备的“身份证”
UFS设备通过描述符向主机描述自身能力。设备描述符包含厂商、型号、版本;单元描述符描述逻辑单元;几何描述符描述容量和块大小;配置描述符描述可配置项。属性是可读写的全局参数,如当前电源模式、最大速率;标志则是布尔状态,如设备初始化完成、链路可用。
| 类别 | 典型对象 | 作用 | 驱动关注点 |
|---|---|---|---|
| 描述符 | Device / Unit / Geometry | 描述设备身份与逻辑单元能力 | 枚举、容量识别、LUN配置 |
| 属性 | CurrentPowerMode、MaxDataRate | 可读写的运行参数 | 电源管理、速率切换 |
| 标志 | DeviceInit、LinkAvailable | 反映设备当前状态 | 初始化判断、错误恢复 |
| 命令 | READ(10)、WRITE(10)、INQUIRY | 执行数据读写与查询 | 块层请求下发、超时处理 |
五、案例与常见误区
某项目在UFS初始化时反复失败,日志显示“query request timeout”。最初怀疑是命令集实现错误,后来发现设备描述符读取阶段链路尚未稳定,UniPro在Lane对齐后需要等待一段时间才能承载查询请求。调整复位和延时后问题消失。这说明:描述符读取失败不一定是描述符本身的问题,可能是链路层还没准备好。
另一个常见误区是把UFS当成eMMC来调。eMMC是半双工、单命令队列,而UFS是全双工、多命令队列,且带有独立的物理层和链路层状态机。如果驱动仍然按eMMC的“发命令—等响应”串行模型设计,就无法发挥UFS的并发能力,甚至会在队列深度增加时出现状态错乱。
理解UFS的分层协议、UPIU流转和描述符体系,是后续驱动初始化、电源管理、性能调优和错误恢复的基础。把这张分层地图建立起来,再去看寄存器手册和厂商代码,就不会迷失在细节里。