熟悉NVMe的朋友知道,NVMe里面有namespace的概念,就是把SSD物理空间划分成若干个逻辑地址空间。在UFS的世界里,它也有这个特性。UFS设备的物理存储空间可以有若干个独立的逻辑地址空间,我们把逻辑地址空间叫做LU,即Logical Unit,俗称“撸”。前面看到,在每个UPIU的Header中,有个LUN(Logical Unit Number)的域,就是标识该UPIU关联的命令或者请求的目标逻辑单元。每个LU的地址空间是独立的,主机在发命令或者请求给设备的时候,须通过LUN指定目标逻辑单元。
如上图所示,UFS设备有若干个LU,每个LU接收主机发过来的命令或者请求,这些命令或者请求可来自应用层的SCSI模块、设备管理器或者任务管理器。每个LU都是独立的,“独立”表现在下面几个方面:
逻辑地址空间是独立的,都是从LBA 0开始;
逻辑块大小可以不同,可以为4KB,..;
可以有不同的安全属性,比如可以设置不同的写保护属性;
每个LU可以有自己的命令队列;
不同的LU可以存储不同的数据,比如有的LU存储系统启动代码,有的LU存储普通的应用数据,有的LU存储用户特殊数据...
。。。
UFS2.1中可以有最多32个普通LU和“四大名撸”(四个Well known LU,众所周知的LU)。
普通LU的逻辑块大小至少是4KB,但RPMB LU逻辑块大小为256B。至于什么是RPMB LU,后面再讲。
普通LU我觉得没有什么好讲的,就是分别用来存储用户数据的。我们主要来讲讲“四大名撸”。
Report LUNS LU
Report LUNS主要用来代表设备向主机汇报设备LU清单。主机想知道设备LU的支持情况,就需要发命令或者请求给该LU。UFS其中有个命令“Report LUNS” (和该LU名字一样)用来访问Report LUNS。
UFS Device LU
UFS设备的法人。当UFS主机不针对某个具体LU,而是对整个UFS设备发命令的时候,UFS Device LU就成为该命令接收的对象,比如格式化UFS设备(FORMAT UNIT命令)、切换UFS设备的功耗模式(START STOP UNIT命令)等等。
BOOT LU
顾名思义,就是用来存储启动代码的LU。不过,BOOT LU本身是不存储启动代码的,它只是个虚拟的LU,启动代码物理上是存储在普通LU上的。
有两个Boot LU,LU A和LU B,可以用来存储不同启动代码(比如一个新,一个旧),但在启动过程中,只有一个是活跃的(Active)的。32个普通LU中的任意一个可以配成Boot LU A或者Boot LU B。
举例说明:
在上例中,LU 1 充当Boot LU A,LU 4 充当Boot LU B。由于有两份启动代码,分别保存在LU 1和LU 4,那启动的时候读取哪一份呢?
主机启动时,首先应该通过设备管理器,发送Query 请求给设备,获取一个叫做“bBootLunEn ”的属性,该属性标识当前活跃(Active)的Boot LU。
在上例中,bBootLunEn = 01,说明Boot LU A是当前活跃的Boot LU,因此主机会从LU 1上读取启动代码完成系统的启动。
值得一提的是,Boot LU不是必须的。如果系统的启动代码不是存储在UFS设备上,那么Boot LU就不需要,因此bBootLunEn = 0。
RPMB LU
在UFS里,有这么一个LU,主机往该LU写数据时,UFS设备会校验数据的合法性,只有特定的主机才能写入;同时,主机在读取数据时,也提供了校验机制,保证了主机读取到的数据是从该LU上读的数据,而不是攻击者伪造的数据。这个LU就是RPMB LU。
关于RPMB,后面有专门章节介绍,这里不多说。
“四大名撸” 每个LU分工明确,分别执行不同的任务。下面把 “四大名撸” 能接收的命令列一下:
他们能接收一些通用的命令(如上图绿色命令),还有只有该LU能执行的命令(如红色命令),具体命令可查看Spec。
需要注意的是,写Boot LU和RPMB LU时,它是不支持cache操作的,就是说,数据必须写到闪存中以后,这笔写命令才算完成。而对一般LU的写,一般都是cache操作的,即主机数据到设备的内部buffer,设备就会回命令完成状态给主机.
全部0条评论
快来发表一下你的评论吧 !