深入浅出SSD 10:UFS介绍 📅 2026/8/5 12:03:07 10. UFS介绍10.1 UFS简介电脑有三大件——CPU、内存和硬盘。CPU用于计算和控制内存用于临时存储程序运行时所需的数据掉电后数据丢失而硬盘用于长久保存数据掉电后不丢失。我们每天使用的手机本质上就是一个移动的小型计算机同样有三大件——CPU/GPU、内存和存储设备。其中存储设备相当于电脑的硬盘用于长久保存手机上的数据比如视频、照片、音乐、操作系统等。UFSUniversal Flash Storage通用闪存存储有两层意思一层是指一种移动存储接口协议类似SATA、PCIe/NVMe另一层是指使用该协议的移动存储设备。后文出现UFS大家应该根据上下文理解具体为哪层含义。为什么说UFS是手机存储的未来无他快可以通过下表感受以下。UFS版本2.0/2.1/2.23.0/3.14.0单通道最大接口速率/(Mb/s)5836.811673.623347.2单向最大通道数222单向最大有效带宽(MB/s)108121634326注表中最大有效带宽不包括协议开销和8/10b编码开销这是一种二进制速率。UFS协议是JEDECwww.jedec.org组织指定的三星、海力士、铠侠等公司力捧。我们可以看到UFS协议一直在大踏步朝着更高更快的目标前进。UFS为什么能那么快1它在数据信号传输上使用的是差分串行传输。这是UFS快的基础。所有的高速传输总西安如SATA、SAS、PCIe等都是串行差分型号。串行可以使用更快的时钟时钟信息可以嵌在数据流中差分信号即用两根信号线上的电平差表示0或者1。与单端信号传输相比差分信号抗干扰能力强能提供更宽的带宽跑得更快。打个比方假设用两根信号线上电平差表示0和1差值大于0表示1差值小于0表示0。如果传输过程中存在干扰两根线上加了近乎同样大小的干扰电平两者相减差值几乎不变。但对单端信号传输来说就很容易受干扰比如0 ~ 1V表示01 ~ 3V表示1一个本来是0.8V的电压加入干扰变成1.5V相当于0变成1数据就出错了。因为具有抗干扰能力强的特性所以差分串行信号线可以用更快的速度进行数据传输从而提供更宽的带宽。UFS的前辈是eMMC。eMMC使用的是并行数据传输方式。并行最大的问题是速度上不去因为一旦时钟上去干扰就变大信号完整性无法保证。另外并口需要更多的数据传输线。2UFS和PCIe一样支持多通道数据传输目前一个方向上最多支持两个通道。多通道选项可以让UFS在成本、功耗和性能之间做取舍。3UFS采用全双工工作模式就是读写可以并行。它的前辈eMMC是半双工读写不能同时进行两个的对比如下图所示。UFS和eMMC工作模式对比要让UFS速度快底层硬件基础设施要跟上层数据传输协议的配合。就好比我们想要速度快除了需要一条又宽敞又平坦的高速公路还需要一辆可高速行驶的汽车。你如果仅有一辆拖拉机那么即使上了高速公路也跑不快。UFS上层协议怎样来充分发挥底层硬件速度快的优势呢UFS支持命令队列也就是主机可以同时发很多个命令然后UFS设备支持并行和乱序执行谁先完成谁先返回状态。这种命令处理方式称为异步命令处理。而它的前辈eMMC早期版本是不支持命令队列的命令一个一个执行或者一包一包每个包里面含有若干个命令执行前面命令没有执行完成后面的命令是不能发下去的。这种命令处理方式称为同步命令队列。我们来比较一下“全双工异步命令处理”和“半双工同步命令处理”两者命令处理方式的执行效率。1. 半双工同步如下图所示主机发了一个写命令W1给设备主机把数据写到设备。同步命令处理方式下命令是被串行处理的所以在发读命令R2之前必须等前一个写m命令W1处理完成。同样在发送写命令W3之前必须等命令R2处理完成。同步命令处理流程示例2. 全双工异步由于支持命令队列主机以下可以发若干个命令给设备如下图所示主机同发一个写命令W1和一个读命令R2给设备。设备可以并行处理这两个命令。由于协议支持全双工操作主机传输写命令W1的数据给设备的同时设备也可以把读命令R2的数据返回给主机。后面命令R3、R4、R5的处理方式与此类似。异步命令处理流程示例再形象一点我们以搬运货物为例来比较以下eMMC和UFS命令执行方式如下图所示。eMMC和UFS命令处理方式对比现在的手机应用非常丰富用户可能要一边看新闻一边听歌一边聊微信多线程操作。由于全双工和命令队列的存在UFS处理命令的效率大大提高给用户极好的体验。前面我们拿UFS和eMMC做了对比但什么是eMMCeMMCEmbedded MultiMedia Card和UFS一样也是JEDEC制定的一种移动存储协议。eMMC最新标准是2015年发布的eMMC5.1支持的最高速度是400MB/s。JEDEC已经有了UFS应该不会再发布新的eMMC标准。毕竟并行传输的eMMC受限于物理信号速度想要有质的飞跃是不现实的。UFS正在慢慢取代eMMC成为主流移动存储协议UFS最终取代eMMC也是必然。下图所示是eMMC和UFS的应用趋势变化。eMMC和UFS的应用趋势变化来源CFM闪存市场不过UFS一统天下的道路上还有一个拦路虎那就是NVMe。有人说NVMe不是SSD的协议标准吗没错不过现在苹果手机中的存储协议是PCIeNVMe而不是UFS。在短期内UFS和NVMe会分别在安卓和苹果手机中存在。长期来说UFS和NVMe是二分天下还是合二为一暂未可知。最终可能会两者并存UFS会借鉴NVMe的优点毕竟NVMe走在前面。给大家看看嵌入式UFS的实物图如下图所示。UFS设备实物图嵌入式UFS为BGA形态一般尺寸为11.5mm × 13mm × 1mm或0.8mm如大拇指的指甲盖大小。但麻雀虽小五脏俱全。UFS存储芯片内部如下图封装了UFS控制器和闪存阵列和SSD结构很相似。不过和SSD相比由于它的容量更小因此闪存Die比较少闪存的通道数也少。另外出于功耗和成本考虑UFS芯片一般是不带DRAM。UFS设备框架图10.2 UFS协议栈任何一种接口或者协议都是由一个完整的协议栈组成的UFS也不例外。UFS的协议栈如下图所示。UFS协议栈UFS定义了一个完整的协议栈从上到下依次为应用层、传输层、数据链路层和物理层。UFS所使用MIPIMobile Industry Proceor Interface移动产业处理器接口联盟的Unipro作为数据链路层使用MIPI的M-PHY作为物理层两者合起来称为UFS互连层UFS INterConnect Layer UIC。UFS主机比如手机、平板电脑等设备和UFS存储设备两侧都需要实现UFS协议栈。目前UFS主要使用的命令是简化的SCSI命令基于SBC和SPC这是由INCITS T10组织定义的。关于SCSI相关协议可以参看相应的协议规范。UFS协议栈的四层中有三层是别人的命令层是T10的数据链路层和物理层是MIPI的只有传输层是JEDEC自己的。UFS至今已经有多个版本本章都是基于UFS4.0之前的版本撰写的每个版本使用的Unipro和M-PHY版本也不尽相同如下表所示。UFS版本和对应的各层版本10.2.1 应用层应用层包括UFS命令集、设备管理器Device Manager和任务管理器Task Manager。应用层是整个协议栈的最高层所有的命令或者请求都来源于该层。它是最高统帅所有的战术和策略都是它制定的真正去冲锋陷阵的是将军和士兵应用层下面的各层。1. 命令集如前所述UFS主要使用简化的SCSI命令具体如下表所示。UFS使用的SCSI命令集2. 设备管理器顾名思义设备管理器用于管理UFS设备。设备管理器有两个功能一是处理设备级操作二是管理设备级配置。前者包括管理设备功耗、设置数据传输相关参数、使能/禁止设备后台操作Background Operation以及其他设备相关操作。后者通过维护和存储一系列描述符通过Query请求修改或获取设备的配置信息。如下图所示设备管理器既可以通过下层的传输层为自己服务通过UDM_SAP接口通过Query命令去处理设备级操作和修改获取设备配置信息也可以绕过传输层直接通过UIC提供的服务接口UIO_SAP去管理与控制互连层。设备管理器可以通过互连层提供的接口UIO_SAP使用一系列的原语Primitive直接控制并操作互连层。这些原语包括重启设备、重启互连层、让物理层进入和退出休眠模式Hibernate等。设备管理器通过UIO_SAP和UDM_SAP接口与互连层、传输层交互总之设备管理器既可以走常规渠道通过传输层以数据包UPIU的形式传输数据也可以走快速通道发送互连层能理解的命令以原语的形式管理和操作设备。3. 任务管理器任务管理器用于管理命令队列中的命令。比如任务管理可以发Abort命令中止之前发下去的命令。它也可以清空命令队列中的所有命令。任务管理器的具体功能如下表所示。任务管理器功能表当某个命令超时时系统可能发Abort命令把这个命令中止。10.2.2 传输层传输层为它上面的应用层服务。当传输层接收到应用层的命令或者请求后会生成UPIUUFS Protocol Information UnitUFS协议信息单元把命令块或者请求封装成固定格式的数据结构然后交由下层传到接收端的传输层。和命令相关的数据、状态、也有相应的UPIU。UPIU是主机和设备进行信息交换的基本数据单元上层命令或者数据都是通过此类数据包封装起来然后传输到接收端的。10.2.3 互连层互连层包括MIPI Unipro和M-PHY它们分别充当UF数据链路层和物理层的角色。数据链路层负责主机和设备的连接物理层负责传输实实在在的物理信号。Unipro其实不仅定义了数据链路层还是一个比较完整的协议栈如下图所示。Unipro协议栈传输层L4支持多设备之间的双向连接但UFS只支持CPort0网络层L3支持通过设备ID寻址多达128个设备但由于UFS是点到点传输所以不需要网络层数据链路层L2支持流控、CRC生成和校验、重传机制等UFS利用UniPro的数据链路层作为主机和设备之间的通信提供可靠的连接物理适配层L1.5对物理层做了抽象使UniPro适配不同的具体物理接口。物理层M-PHY使用8/10b编码、差分信号以串行的方式进行数据传输。数据传输分高速Hgh Speed和低速Low Speed两种模式每种模式下又有几种不同的速度档Gear。当线上没有数据传输时M-PHY会进入省电模式其中高速模式下对应的省电模式是STALL低速模式下对应的省电模式为SLEEP而最为省电的状态为HIBERNATE。这里以下图所示为例来解释一下M-PHY连接的一些术语。M-PHY通道示例LINE线路发送模块和相应接收模块之间点对点的互联信号线包括两根差分信号线。Lane通道单向、单信号、物理传输通道用于点A到点B的信息传输。由上图可以看到通道包括发送模块和其对应的接收模块以及它们之间的连接信号线Line。UFS在每个方向可以有2条Lane由于相反方向必须具有跟它同样多的Lane所以UFS事实上可以有4条Lane每个方向各2条。我们平时说UFS有2条Lane其实是指单方向的。SUB-LINK子链接由统一方向的所有Lane组成的连接。两个具有不同方向的子连接给UFS提供了双向数据传输功能。LINK连接由所有子连接组成的点A比如主机和点B比如设备之间的连接。下图所示是2通道的UFS主机和设备连接的示意图具体信号线如下表所示。主机和设备互连示意图UFS信号线应用层和传输层之间是CPort接口PA层物理适配层和PHY层使用的RMMI接口。10.3 UPIUUFS协议中数据包称为UPIU它是固定格式的数据结构用于传输应用层发来的命令或者请求以及跟它们关联的数据或者状态信息。UFS中的UPIU类似于SATA中的FIS和PCIe的TLP。UFS采用“客户-服务器”结构或者说从主从的命令结构UFS主机客户发送命令或者请求给UFS设备服务器UFS设备执行命令并返回命令状态Response。注意UFS所有的数据传输都是主机发起的设备不能主动发起数据的传输但跟PCIe是不同的PCIe设备可以主动向主机传输数据。一个命令或者请求的执行包含下面几个阶段如下图所示UFS命令执行过程包含的几个阶段图中所示几个阶段说明如下。命令阶段主机发起命令或请求给设备这是“因”。数据阶段传输跟数据关联的命令比如读写命令这个过程肯定会涉及数据的传输有些命令不涉及数据的传输就没有这个阶段。所以这个阶段并不是总存在跟具体命令和请求相关。响应阶段设备执行完命令必须给主机返回命令执行状态信息。这个是“果”是必不可少的。在PCIe中有Posted和Non-posted的TLP对于前者命令执行者无须返回命令执行状态给命令发起者对于后者命令执行者必须返回状态给命令发起者。对UFS来说它的命令总是Non-posted即设备必须返回命令状态给主机。无论是命令执行过程中的哪个阶段UFS主机和设备间都是通过UPIU进行信息交互的。UFS主机通过命令或者请求UPIU发命令请求给设备。UFS主机或者设备通过UPIU传输数据。UFS设备通过UPIU返回命令状态信息给主机。10.3.1 UPIU事务下面我们看看UFS中都有哪些UPIU事务。1. 命令或者请求UPIU应用层包括UFS命令、设备管理器和任务管理器3个模块传输层根据不同模块发来的命令或者请求分别产生不同类型的UPIU。UFS命令模块发送简化版本的SCSI命令当传输层收到命令请求后它会生成COMMAND UPIU把命令封装起来。应用层通过任务管理器来管理任务队列比如中止或查询命令队列中的命令。当传输层收到来自任务管理器的请求后它会生成TASK MANAGEMENT REQUEST UPIU把请求封装起来。UFS通过设备管理器来管理UFS设备比如设置、查询配置UFS设备。当传输层收到来自设备管理器发来的请求后它会生成QUERY REQUEST UPIU把请求封装起来。把命令请求类UPIU归总到下表中。命令请求类UPIU应用层模块对应的UPIU传输方向作用SCSI命令COMMAND UPIU主机到设备主机发送SCSI命令给设备任务管理器TASK MANAGEMENT REQUEST UPIU主机到设备主机管理命令队列中的命令比如中止或者查询设备命令队列中的命令设备管理器QUERY REQUEST UPIU主机到设备主机通过设备管理器查询、配置、管理设备2.数据传输相关UPIU当主机发送了类似读命令这样的与数据相关的命令给设备之后设备需要通过DATA IN UPIU向主机传输数据。当主机发送了类似写命令这样的与数据相关的命令给设备之后主机需要通过DATA OUT UPIU向设备传输数据。UFS主机在向设备写数据的时候会考虑设备这个时候能不能接收数据因为此时设备可能没有足够的内存空间接收主机数据它在向设备发了写命令之后不会立刻把数据传输给设备而是在那里等设备的反馈。当设备准备好接收数据并确定能接收多少数据时设备通过READY TO TRANSFER UPIURTT告知主机。当主机收到该RTT后才开始根据RTT的信息传输数据。RTT中包含该次传输多少数据的信息主机根据RTT提供的信息进行传输。所以主机只有在收到设备的RTT后才能发DATA OUT UPIU。注意读命令不需要这种机制。因为设备从闪存中获得数据后是设备控制数据的传输。对主机来说它在发读命令之前已经准备好足够的空间来接收数据所以不存在主机没有空间接收数据的情况。我们把数据传输类UPIU归总在下表中。数据传输类UPIU数据传呼相关的UPIU传输方向作用DATA IN UPIU设备到主机设备传输数据给主机DATA OUT UPIU主机到设备主机写数据到设备主机只有收到RTT后才能往设备写数据READY TO TRANSFER UPIU主机到设备同步处理写命令时设备告诉主机可以传输数据已经传多少数据3. 响应UPIU前面看到主机有3中请求——SCSI命令、任务管理器发出的任务管理请求Task Management Request以及设备管理器发出的查询请求Query Request。针对不同的命令或者请求设备在执行完相应的任务后分别返回对应的状态UPIU给主机。我们把命令响应类UPIU归总在下表中。命令响应类UPIU设备响应UPIU传输方向作用RESPONSE UPIU设备到主机设备返回命令执行状态TASK MANAGEMENT RESPONSE UPIU设备到主机设备返回任务管理请求执行状态QUERY RESPONSE UPIU设备到主机设备返回设备管理器的查询请求执行状态4. 其它UPIU除了以上常规的UPIU还有其它UPIU这里进行简单介绍。设备上电后主机检测是否与之连接此时会发NOP OUT UPIU给设备。这如同我们平时想看与某台电脑能否连接上会发一个ping命令。当设备收到NOP OUT UPIU后会返回NOP IN UPIU。主机收到该UPIU后确认与设备连接然后就可以进行后续操作了。最后一个UPIU就是REJECT UPIU。当设备收到一个无效的UPIU或者无法识别的UPIU时它会发REJECT UPIU拒绝无效的UPIU。我们把其它类UPIU归总到下表中其它类UPIU辅助UPIU传输方向作用NOP OUT UPIU主机到设备主机ping命令查询主机是否与设备相连NOP IN UPIU设备到主机设备响应NOP OUT UPIU主机收到该UPIU后确认主机与设备相连REJECT UPIU设备到主机设备收到无效的UPIU发送UPIU给主机5. 读写命令中UPIU交互的例子前面我们都是单独看每一个UPIU现在我们以读写命令为例看看它们是如何组合完成命令处理的。首先是一个“主机往设备读取96KB数据”的例子如下图所示。读命令处理过程中UPIU交互的例子首先主机发送读96KB数据的命令给设备然后设备执行命令并分3批把数据返回给主机最后返回命令执行状态给主机。下面是一个“主机往设备写64KB数据”的例子如下图所示。写命令处理过程中UPIU交互的例子主机发送写64KB数据的命令个设备然后在那里等设备响应。很快设备说你可以传24KB数据下来了于是主机写24KB数据给设备。接着设备又来说可以继续传32KB数据主机照做。最后设备通知可以把最后8KB数据也传过来主机于是写最后8KB数据。最后主机收到设备命令执行完成的响应。我们看到主机必须收到RTT后才能启动数据传输。10.3.2 UPIU格式上面我们介绍了UFS的各个UPIU事务下面我们具体看一下UPIU的内容。UPIU是有固定格式的数据包分析数据包格式有助于我们深入理解UPIU以及整个UFS协议。每个UPIU都有一个12Byte的Header再加上跟每个UPIU相关的域如下图所示。一个UPIU包括Header最小为32Byte最大为65600Byte。UPIU内容组成我们看通用的Header具体如下表所示。UPIU Header格式我们看看其中的一些域1Tranaction Type事务类型用啦标识该UPIU是前面介绍的12个UPIU事务中的哪一个。2Flags标识只对命令和其响应的UPIU有用指定命令的属性。Flags.R如果该位置起说明该命令需要设备向主机传输数据比如读命令。Flags.W如果该位置起说明该命令需要主机向设备传输数据比如写命令。Flags.CP表示命令的优先级。1为高优先级0表示没有优先级。注意该位只适用于简单命令具有Simple属性的命令。Flags.ATTR命令属性域。UFS命令有Simple、Ordered和Head of Queue属性具体如下。Flags.ATTR00h表示命令为Simple command就是一般的命令。设备收到这样的命令无效进行特别处理一般谁先到谁先执行。这是系统中最常见的命令属性。Flags.ATTR01h表示命令为Ordered command。设备收到这样的命令应该把该命令之前的命令都处理完才处理该命令后面的命令也必须等该命令处理完成后才能执行。Flags.ATTR10h表示是命令为Head of Queue Command。设备收到该命令后将其放到命令队列的头部立即执行。3LUNLogical Unit Number逻辑单元编号指定该UPIU的目标LU。UFS上层协议来自SCSI它继承了LU的概念即把物理存储空间划分成若干个逻辑空间每个逻辑空间都从LBA 0开始用LUN标识。主机在发命令中指定该命令发给哪个LU。4Task Tag任务标签UFS支持命令队列主机可以同时发送很多个命令给设备。为区分这些命令主机需要为每个命令贴上标签。跟这个命令相关的数据UPIU和状态UPIU都具有跟这个命令UPIU一样的标签。比如对读命令来说COMMAND UPIU、所有的DATA IN UPIU和RESPONSE UPIU都具有同一个标签。5Command Set Type命令集类型UFS预期有三类命令即简化的SCSI命令、UFS原生命令和用户自定义命令。目前UFS的命令都是从别人家SCSI借来的自己一个命令也没有制定。如果用户无自定义命令该域就是0SCSI命令。6Initiator ID身份编号UPIU发起者身份编号。手机系统中一般一个主机连接一个UFS设备所以主机ID一般为0.7Response响应设备告知主机命令是否执行成功。8Status状态设备返回的命令执行的状态。UFS有下表所示状态。状态码响应说明00hGOOD表明命令成功执行02hCHECK CONDITION此状态表示设备以完成命令但有错误或者需要其它操作来处理结果。出现此状态时将在响应UPIU中返回最后处理的命令的有效sense数据08hBUSY此状态表示逻辑单元忙。当逻辑单元无法接收命令时将返回此状态。主机稍后发送命令是标准的恢复操作。28hTASK SET FULL此状态表示由于缺少资源如任务队列已满或命令执行所需的内存暂时不可用逻辑单元无法处理命令9Query FunctionTask Manag Function查询和任务管理功能任务管理器包括中止任务、中止任务集、清除任务集、重置LU、查询任务、查询任务集等功能。设备管理器包括标准的查询读、用户自定义查询读、标准的查询写、用户自定义查询写等功能。10Device Information设备信息该域往往跟该命令无关属于设备夹带的私活。因为UFS主机和设备是主从关系如果UFS主机没有向设备发命令UFS设备是不能主动向主机报告设备状况的。如果UFS设备上有特殊事件发生它可以趁返回RESPONSE UPIU的时候把事件告诉主机。所以该域只对REPONSE UPIU有效。11Total EHS LengthEHS总长和Data Segment Length数据段总长这两部分见名知义很好理解。10.4 逻辑单元NVMe里面有命名空间的概念就是把SSD物理空间划分成若干个逻辑地址空间。UFS中也有这个特性。用户可以把UFS设备的物理存储空间分配成若干个独立的逻辑地址空间这就是“分区”的概念我们把这些独立的逻辑地址空间称为LULogical Unit。由前文可知在每个UPIU的Header中都有一个LUN域这就是标识与该UPIU关联的命令的目标逻辑单元。每个LUN的地址空间是独立的主机在发命令给设备的时候需通过UPIU Header的LUN域指定目标逻辑单元。每个LU都是独立的“独立”表现在以下几个方面。逻辑地址空间是独立的都是从LBA 0开始的。逻辑块大小可以不同可以为4KB8KB等。可以有不同的安全属性比如可以设置不同的写保护属性。每个LU可以有自己的命令队列。不同的LU可以存储不同的数据比如有的LU存储系统启动代码有的LU存储普通的应用数据有的LU存储用户特殊数据。最新的UFS协议中可以有最多32个普通LU和4个核心LU4个Well known LU即众所周知的LU如下图所示。UFS中支持的LU普通LU的逻辑块大小至少是4KB但PRMB LU逻辑块大小为256Byte。至于什么是RPMB LU下一节讲。普通LU是用来存储用户数据的这没必要展开。下面主要介绍4个核心LU。1Report LUNS LUReport LUNS LU主要用来代表设备向主机汇报设备LU清单。主机想知道设备LU的支持情况就需要发命令给该LU。UFS中有一个命令Report LUNS和该LU名字一样用来访问Report LUNS。2UFS Devcice LUUFS设备的法人。当UFS主机不针对某个具体LU而是对整个UFS发命令的时候UFS Devcice LU就成为该命令接收的对象比如格式化UFS设备FORMAT UNIT命令、切换UFS设备的功耗模式START STOP UNIT命令等时。3BOOT LU顾名思义就是用来存储启动代码的LU。不过BOOT LU本身是不存储启动代码的它只是一个虚拟的LU启动代码在物理上是存储在普通LU上的。有两个BOOT LU——BOOT LU A和BOOT LU B它们可以用来存储不同的启动代码比如一个新一个旧但在启动过程中只有一个是活跃的。32个普通LU中的任意一个都可以配成BOOT LU A或者BOOT LU B。主机启动时首先应该通过设备管理器发送查询请求给设备获取一个名为bBootLunEn的属性该属性标识当前活跃的BOOT LU如下表所示。如果bBootLunEn01说明BOOT LU A是活跃的因此主机会从与BOOT LU A对应的普通LU上读取启动代码完成系统的启动如果bBootLunEn02则表明BOOT LU B是活跃的。bBootLunEn属性表bBootLunEn描述00hBOOT LU A 禁止BOOT LU B 禁止01hBOOT LU A 使能BOOT LU B 禁止02hBOOT LU A 禁止BOOT LU B 使能其它保留值得一提的是BOOT LU不是必须有的。如果系统的启动代码不是存储在UFS设备上那么BOOT LU就不需要了因此bBootLunEn0.4RPMB LU在UFS里有这样一个LU主机往该LU写数据时UFS设备会校验数据的合法性只有特定的主机才能写入同时。主机在读取数据时也有对应校验机制保证主机读取到的数据是从该LU上读的数据而不是攻击者伪造的数据。这个LU就是RPMB LU。下一节会专门讲解RPMB。4个核心LU分工明确分别执行不同的任务。下面对它们能接收的命令进行总结如下表所示。核心LU能接收命令列表核心LUW-LUNUPIU头中的LUN域命令名称Report LUNS01h81hINQUIRY、REQUET SENE、TEST UNIT READY、REPORT LUNSUFS Device50hD0hINQUIRY、REQUET SENE、TEST UNIT READY、START STOP UNIT、FORMAT UNITBOOT30hB0hINQUIRY、REQUET SENE、TEST UNIT READY、READ(6)、READ(10)、READ(16)RPMB44hC4hINQUIRY、REQUET SENE、TEST UNIT READY、SECURITY、PROTOCOL IN、SECURITY PROTOCOL OUT需要注意的是写BOOT LU和RPMB LU时不支持缓存操作也就是说数据必须写到闪存以后这条写命令才算完成。而写一般LU大多都是支持缓存操作的即主机数据写到设备的内部缓存设备就会将命令完成状态返给主机。10.5 RPMBUFS主机通过认证authenticated的方式访问RPMB LU。图10-19展示了RPMB数据写的过程。主机和设备写RPMB数据流程对上图所示流程说明如下。1UFS主机和UFS设备共享密钥该密钥在UFS设备出厂时就保存在UFS设备。2UFS主机在发送主机数据给UFS设备前会用该密钥和哈希算法生成消息认证码Message Authentication CodeMAC。3UFS主机把主机数据连同MAC一起发给UFS设备。4UFS设备把收到的主机数据和共享密钥在本地重新计算并生成MAC然后把计算出的MAC和收到的MAC做对比如果一致则认证成功写入到闪存否则拒绝该笔数据的写入。UFS使用HMACHash-based Message Authentication Code基于Hash的消息认证SHA-256算法生成消息认证码。HMAC运算利用Hash算法以一个密钥和一个消息为输入生成一个消息摘要作为输出。关于HMAC具体算法可参考https://en.wikipediia.org/wiki/HMAC。消息认证码本质是Hash值。Hash的一个特点是即使只改变原数据中的1位两者的Hash值也是截然不同的。如果恶意攻击者在数据传输过程中篡改了用户数据那么UFS设备根据收到的数据和接收到的MAC不一致认证通不过数据就不会写入UFS设备。上述前提是共享密钥不能被恶意攻击者获取否则恶意攻击者完全可以模拟主机行为用自己的恶意数据和共享密钥生成MAC然后把恶意数据和与其对应的MAC发送给UFS设备。UFS设备胡认证成功恶意数据被写入。所以请保管好你的密码。但是恶意攻击者是狡猾的即使他没有办法获得你的密钥他还是有办法对你进行攻击的。比如恶意攻击者可能监听到UFS主机和UFS设备之间某次数据传输得到“用户数据MAC”然后他就可以重复发送该“用户数据MAC”给UFS设备由于“用户数据MAC”是合法的所以认证会通过UFS设备就会接收该数据并写到闪存。这就是重放攻击——Replay Attack示意图如下图。重放攻击的概念RPMBReplay Protection Memory Block重放保护存储块的名字暗示了RPMB是能抵御重放攻击的。那么RPMB是怎么对付重放攻击的呢UFS维护了一个写计数Write Counter它的初始值为0。UFS设备每次成功处理完一个RPMB写命令写计数加1.主机在往设备写入数据前获得该计数。然后把用户数据和该计数一起做MAC计算。这样即使恶意攻击者窃听到某次合法的“用户数据MAC”再往设备写入时由于写计数发生变化它无法生成写计数改变之后的MAC值因此就无法一直重复往设备写入某次合法的“用户数据MAC”。下面回到UFS RPMB协议上来。UFS中RPMB LU最小逻辑空间为128KB最大为16MB。它的逻辑块大小为256Byte普通LU逻辑块大小一般为4KB。应用层不是通过普通的读写命令去读/写RPMB上的数据而是通过SERURITY PROTOCOL OUT/IN命令来访问RPMB的。下表给出了普通LU和RPMB LU的对比。RPMB LU和普通LU对比表对比项逻辑空间大小逻辑块大小访问命令安全性存储数据类型RPMB LU128KB ~ 16MB256ByteSecurity Protocol OUT/IN数据认证防篡改的重要数据普通 LU无限制一般为4KBRead/Write无普通用户数据UFS主机在访问设备RPMB时可通过下表所示不同消息类型完成不同功能。RPMB消息类型列表请求Request响应Response说明认证密钥写请求认证密钥写响应用于写认证密钥写计数读请求写计数读响应用于读取写计数认证数据写请求认证数据写响应用于写认证数据认证数据读请求认证数据读响应用于读取认证数据操作结果读请求无读取操作结果安全写保护配置块写请求安全写保护配置块写响应用于写安全写保护配置块安全写保护配置块读请求安全写保护配置块读响应用于读安全写保护配置块每条消息包含一条或者若干条消息数据帧。消息数据帧大小是512Byte具体如下图所示。从下图中我们可看到认证密钥key是32B。UFS使用SHA-256计算MAC也就是说任意长度的数据产生的MAC值总是256位即MAC大小为32Byte。逻辑块大小为256Byte。写计数Write Counter大小为4字节当该值涨到0xFFFF FFFF时它就会保持不动不会继续增长了。AddresRPMB的逻辑地址同LBA大小为2字节最多表示65536个逻辑块每个逻辑块大小为256Byte因此RPMB逻辑空间最大为16MB。Block Count逻辑块数即指定读写多少个逻辑块。ResultRPMB操作结果状态。RPMB消息数据帧格式下面以“主机写认证数据”为例来帮助大家理解上面的消息。主机命令层通过SECURTY PROTOCOL OUT命令把用户数据和对应的MAC发送给设备然后通过SECURTY PROTOCOL OUT请求获取前面数据的写结果最后通过SECURTY PROTOCOL IN读取写结果。写结果中包含写的写计数这样下次主机就可以利用新的写计数计算MAC了·。注意只有本次写认证数据成功设备擦灰递增该计数。下图所示为写RPMB的流程。写RPMB数据的流程从上图中我们可以看到和普通数据读写相比RPMB数据读写过程非常繁琐比如读写一次需要发若干条命令主机和设备交互太多。另外数据传输效率也不高512Byte的数据帧真正有效的数据只有256Byte其它都是元数据。基于此UFS4.0提出了Advanced RPMB采用4KB的数据块提升了RPMB访问效率简化了读写访问流程。UFS4.0规范已发布自行参考。RPMB提供了认证访问方式和抵御重放攻击的机制保证了存储在RPMB LU上的数据的安全。因此用户可以把一些敏感和重要的信息写在RPMB上。在实际应用中它通常用于存储一些有防止非法篡改需求的数据例如手机上指纹支付相关的公钥、序列号等敏感信息。10.6 UFS低功耗简介UFS作为移动存储设备对功耗要求很高尤其是对低功耗的要求因为移动存储设备大多数时候都处于空闲状态。本节将简单介绍一下UFS设备的低功耗管理。前面提到UFS协议采用MIPI的M-PHY作为物理层和UniPro作为数据链路层。M-PHY有高速模式High Speed ModeHS-MODE和低速模式Low Speed Mode LS-MODE。其中高速模式下M-PHY有2种状态——HS-BURST和STALL其中HS-BURST表示高速数据传输状态STALL表示没有数据传输时链路所处的一种省电状态。低速模式下M-PHY有3种状态——LINE-CFG、SLEEP和PWM-BURST。其中PWM-BURST表示低速数据传输状态SLEEP表示没有数据传输时链路所处的一种省电状态。当链路上没有数据传输时M-PHY会自动无需主机或者设备上层干预切换到STALL或者SLEEP状态以达到省电的目的。HS-BURST和STALL、PWM-BURST和SLEEP之间的状态切换时间为纳秒级别。除此之外M-PHY还有一种更加省电的状态——HIBERN8Hbernate休眠状态。UFS主机和UFS设备不可能一直交互数据总有闲下来的时候。和STALL和SLEEP状态不同的是进入HIBERN8状态需要主机的干预当UFS主机一段时间没有访问UFS设备时它会发命令让彼此主机和设备的链路进入休眠状态即HIBERN8状态。那UFS主机如何通知M-PHY切换到休眠状态呢前面提到设备管理器可以略过传输层直接管理与控制互连层UIC即UniPro和M-PHY。如下图所示主机设备管理器可以通过原语直接与UFS互连层通信。除了图中所示的重启互连层/设备的原语外UFS还包括让UIC进入和退出休眠状态的原语——DME_HIBERNATE_EXIT退出休眠状态。当设备收到主机发来的Hibernate进入命令时它就明白在一段时间内主机不会访问设备因此在这段时间内UFS设备可以进入低功耗模式比如把当前UFS设备的软硬件上下文保存到闪存然后切断设备绝大多数模块的电源以达到省电的目的当UFS设备收到Hibernate退出命令时UFS重新给这些模块上电并把软硬件上下文加载回到控制器内存继续运行。注意UFS设备进入低功耗的时候不是切换对所有模块的供电否则设备就没有办法接收到HIbernate退出命令而是切断主要模块的供电比如闪存模块的供电以及UFS控制器绝大多数模块的供电。为做到这一点这就要求控制器采用Power Domain的设计即控制器主要模块处于不同的Power Domain中它们的供电是独立的关闭某个模块的供电不会影响到其它模块的供电。以下图所示为例某个控制器有3个Power Domain不用纠结每个Power Domain里具体的模块是什么当UFS设备进入低功耗的时候它把耗电大户Power Domain3比如CPU、RAM、LDPC模块等的供电切断是否切断Power Domain2的供电是可选的保持Power Domain 1不断电用于响应主机发来的Hibernate退出命令。Power Domain的概念前面提到UFS设备进入低功耗状态的时候需要把设备软硬件上下文保存到闪存退出的时候再把它们加载回来。相关数据表明在典型手机应用中一个UFS设备每天接收的Hibernate命令有几十万甚至上百万个如果每次进入低功耗的时候都要写闪存会加速闪存磨损从而影响UFS设备寿命。另外与访问内存相比访问闪存是比较耗时的操作如果把上下文保存到闪存会影响Hibernate进入和退出的延时这一方面会影响系统功耗UFS设备如果能快点进入低功耗状态南那么整个移动设备也可以尽快进入低功耗状态另一方面会影响用户体验。UFS设备低功耗处理追求的是“快进快出”小于1ms的低功耗退出延时也是业界追求的目标。为此现在的控制器一般都提供比较大的保持内存Retention RAM如上图 Power Domain 2中所示它可以在比较低的功耗保持数据。UFS设备进入低功耗的时候上下文数据可以保存在保持内存从而减少或者避免对闪存的访问这对UFS设备寿命和用户体验来说都是一个好选择。10.7 WriteBooster10.8 HPB