事先声明本文不用于任何商业行为,仅用于本人学习与记录。所有截图版权均属于《JESD220E-UFS3.1》
欢迎点赞、收藏、转发分享给朋友,禁止未经书面授权的复制、搬运、二次剪辑。
如有引用请注明出处。
标准规范仍然以《JESD220E-UFS3.1》为准
写在最前:往后个人见解部分均用实线框出来。
14 UFS Descriptors Flags And Attributes UFS 描述符、标志和属性
问1:为什么要分描述符,标志,属性 一个描述符不就完了吗?
本质上是因为这三类数据的访问方式、更新频率、数据大小完全不同,硬塞在一起会很难用。
为什么不能全放描述符里?
1. 访问效率差太多
假设你想读一下 RPMB 的写计数器值(4 字节):
- 全放描述符里 → 要读整个设备描述符(几十字节),就为了拿 4 个字节
- 用属性 → 直接读这一个属性,传 4 字节就够了
假设你想翻转一个写保护开关:
- 全放描述符里 → 要读整个描述符 → 改一个 bit → 整个写回去
- 用标志 → 直接发 "设置标志" 命令,一个字节搞定
2. 有些数据是动态变化的,不适合放描述符
| RPMB 写计数器值 | 每次写都 + 1,放描述符里要反复读整包 |
| 设备温度 | 实时变化,放描述符里每次都要传一大包 |
| bPurgeStatus | Purge 进行中 / 完成 / 失败,实时状态 |
| fDeviceInit | 初始化完成标志,主机要轮询 |
这些数据高频读取,如果放在大块描述符里,每次都要传几十字节,浪费带宽。
3. 修改粒度不同
- 描述符:是 "配置包",要整包读写。比如配置分区,一次写一整个配置描述符,设备才知道 "哦,你要这样分区"。
- 属性:是 "单个数值",可以单独改一个。比如写计数器是设备自己维护的,主机只能读。
- 标志:是 "开关",最简单,一个 bit 翻转就行。
举例:你不会把 "当前 CPU 温度" 写在硬件配置清单里吧?温度是实时读的。你也不会为了开个 WiFi 就把整个配置清单读出来改一个 bit 再写回去。
因此我们分描述符、标志、属性。
问2:那比如标志 属性 这些比较小的,我是放在哪里呢 放在 ram 上?如果放在 Flash 里 读取速度和描述符就没什么区别了。
标志和属性存在哪里?
我认为大部分放 RAM,需要掉电保留的才放 Flash。 如果都放 Flash,访问速度确实没本质区别,区别在于数据量大小和是否需要持久化。
为什么读属性感觉比读描述符快?
不是物理位置的区别,是数据量和处理逻辑的区别:
关键区别:
- 属性数据小(4 字节),设备固件从 RAM 寄存器里直接拿
- 描述符数据大(几十字节),可能存在 Flash 里,要经过 Flash 读取、ECC 校验
- 但即使描述符也缓存到 RAM 了,读描述符仍然要传几十字节,读属性只传 4 字节
- 协议层面的传输开销才是主要区别,不是物理存储速度
由于没有做过相关固件,以上问题等后续接触再及时更新,也欢迎大家指正,共同学习。
14.1 UFS Descriptors UFS 描述符
描述符是具有定义格式的数据结构。描述符通过 QUERY REQUEST UPIU 分组访问。描述符是独立可寻址的数据结构。描述符可以是独立的、每个设备唯一的,也可以以层次方式相互关联并链接到其他描述符,由顶层描述符中定义的参数链接。描述符大小从 2 字节到 255 字节不等。2 字节描述符是空描述符。所有描述符都有一个长度值作为第一个元素。该长度表示描述符的整个长度,包括长度字节。所有描述符都有一个类型标识作为第二个字节。如果描述符中的参数大小超过 1 字节,则包含 MSB 的字节存储在最低偏移处,包含 LSB 的字节存储在最高偏移处(即大端字节序)。描述符可以部分读,但起始点始终是偏移 00h。
描述符是描述设备某些信息的参数块或页面。例如,有设备描述符、配置描述符、单元描述符等。
一般来说,所有描述符都是可读的,有些可以写一次,其他的可能有写保护机制。
配置描述符是可写的,允许修改制造商设置的设备配置。
表 14.1 指定了描述符标识值。

描述符有以上那么多种,14章也会对每种描述符进行简介,这里我不知道能不能类比eMMC的ECSD,CSD,CID,OCR等寄存器,感觉是类似的东西,用于表示设备的状态,可以配置的模式,操作条件,厂商ID等等,感觉应该是同类型的东西。本文只自己进行学习,不会通篇翻译,因为本人理解也不是很深,只能边看边学,后续持续更新。
| 设备描述符 | 只读 | 反映硬件能力,不能改 |
| 配置描述符 | 可写 | 用户要配分区大小、LU 数量、内存类型 |
| 单元描述符 | 只读 | 配置描述符写入后由设备自动生成 |
| 互连描述符 | 只读 | 反映 M-PHY/UniPro 硬件能力 |
| 几何描述符 | 只读 | 反映 NAND 物理容量、块大小等硬件信息 |
| 电源描述符 | 只读 | 反映电流、电压等硬件参数 |
| 设备健康描述符 | 只读 | 反映寿命、温度等运行状态 |
| OEM_ID 字符串 | 可写 | OEM 厂可以写自己的标识字符串 |
| 其他字符串 | 只读 | 厂商名 / 产品名是出厂定死的 |
字符串描述符(String Descriptor,IDN=05h)用来存储人可读的 Unicode 字符串,让主机 / 用户能看到设备的文字信息。
| STRING DEV ID | 设备 ID 字符串 | "UFS Card" |
| STRING MANU | 厂商名称 | "Samsung"、"Micron"、"Hynix" |
| STRING PROD | 产品名称 | "UFS 3.1 128GB" |
| STRING REV | 产品版本 | "V1.0" |
| STRING DATE | 生产日期 | "2024/01/15" |
| STRING-U | 每个 LU 的字符串 | 分区标签等 |
为什么配置描述符可写?
- 同一颗 UFS 芯片,不同手机厂商要的分区方案不一样
- 有的要分 8 个 LU,有的要分 4 个
- 有的要大 RPMB,有的要小 RPMB
- 所以出厂后 OEM 可以通过写配置描述符来定制分区
为什么 OEM_ID 字符串可写?
- UFS 芯片是存储颗粒厂(三星 / 美光)生产的
- 但手机厂商买来后,希望设备里显示自己的品牌
- 所以留一个 OEM_ID 字符串让手机厂写入
- 其他字符串(存储颗粒厂名字)就不改了
简单总结:
- 只读描述符 = 硬件本来就是这样,改不了
- 配置描述符 = 分区方案让 OEM 自己定
- OEM_ID 字符串 = 贴牌用的,让整机厂写自己的名字
14.1.1 Descriptor Types描述符类型
描述符按表 14.1 分类。有些描述符是单一实体,如设备描述符。其他描述符可以有多个副本,取决于定义的数量,如 UNIT 描述符。见图 14.1。
14.1.2 Descriptor Indexing描述符索引
每种描述符类型都有一个关联的索引号。索引值从零开始,每实例化一个额外的描述符就加一。例如,第一个也是唯一一个设备描述符的索引为 0。第一个字符串描述符的索引值为 0。第 N 个字符串描述符的索引值为 N-1。
14.1.3 Accessing Descriptors and Device Configuration访问描述符和设备配置
描述符通过请求描述符 IDN 和描述符 INDEX 来访问。例如,要请求第五个单元描述符,请求应引用 TYPE UNIT(数值 = 2)和 INDEX 4。

所有描述符都是只读的,除了配置描述符和 OEM_ID 字符串描述符:
- 配置描述符:当 bConfigDescrLock 属性值等于 00h 时,可读可写
- OEM_ID 字符串描述符:可读可写
特别是,配置描述符允许修改制造商设置的设备配置。配置描述符中的参数设置用于计算和填充设备描述符和单元描述符中的参数字段 —— 这是设备的内部操作。
如果 bConfigDescrLock 属性等于零,主机可以多次写配置描述符。
支持 8 个逻辑单元的设备只有一个配置描述符,而支持 32 个逻辑单元的设备有四个配置描述符。主机应只写与要配置的逻辑单元相关的配置描述符,并避免发送写描述符查询请求到不需要更改的配置描述符。
配置描述符中的 bConfDescContinue 参数指示写描述符序列的结束。特别是:
- 如果 bConfDescContinue 设为一,当前查询请求之后还会有另一个查询请求,设备不应启动内部操作来实现新配置。
- 如果 bConfDescContinue 设为零,当前查询请求是最后一个,设备应启动内部操作来实现新配置。
例如,要配置 LU 0、LU 1、LU 2、LU 18 和 LU 20,可以发送以下写描述符查询请求:
bConfDescContinue 设为零的写描述符查询请求的延迟会明显大于 bConfDescContinue 设为一的查询请求。如果 bConfDescContinue = 00h,则设备应在配置过程完成后才发送 QUERY RESPONSE UPIU。
如果 bConfDescContinue = 0h,则 QUERY RESPONSE UPIU 中的 QUERY RESPONSE 字段应仅在以下情况下设为 "成功":
- 设备描述符和单元描述符中的参数已成功更新
- 逻辑单元配置已成功完成
- 逻辑单元已就绪可操作(读、写等)
如果查询请求失败,应可以通过发送新的写描述符查询请求序列来重复配置过程。
设备在更新配置时可能无法正确处理 SCSI 命令,因此主机不应发送 SCSI 命令。
主机可以多次发送相同索引的配置描述符(例如,配置描述符 INDEX=0 时 bConfDescContinue=01h)。在 bConfDescContinue 设为零之前收到的配置描述符的最后值应被视为有效配置。
如果发生掉电时 bConfDescContinue 为 01h,则所有配置描述符值应重置为之前成功的配置值;如果没有之前成功的配置,则全部重置为默认值,按 UFS 规范。
设备配置完成后,bConfigDescrLock 的设置会永久锁定设备配置。某些设备在系统设置或开发期间可以多次配置。多设备配置相关的细节和限制是厂商特定的,超出本标准范围。
注意: 本版本标准不要求掉电来完成设备配置。
14.1.3.1 Read Descriptor读描述符
主机向设备发送带 READ DESCRIPTOR 操作码的查询请求操作。主机构建 QUERY REQUEST UPIU,在 UPIU 中放置 READ DESCRIPTOR 操作码,设置所需字段中的相应值,然后将该 UPIU 发送到目标设备。
收到 QUERY REQUEST UPIU 后,设备解码 READ DESCRIPTOR 操作码字段,并根据 DESCRIPTOR IDN 字段、INDEX 字段和 SELECTOR 字段检索描述符。当设备准备好向主机返回数据时,设备构建 QUERY RESPONSE UPIU,设置相应字段,并将整个检索到的描述符放在 QUERY RESPONSE UPIU 的单个数据段区域中。
传输完 QUERY RESPONSE UPIU 后,设备认为查询请求操作完成。
收到 QUERY RESPONSE UPIU 后,主机从数据段区域检索请求的描述符,解码 UPIU 中的状态和其他字段,并采取适当的完成操作。收到 QUERY RESPONSE UPIU 后,主机认为查询请求操作完成。

14.1.3.2 Write Descriptor写描述符
主机向设备发送带 WRITE DESCRIPTOR 操作码的查询请求操作。主机构建 QUERY REQUEST UPIU,在 UPIU 中放置 WRITE DESCRIPTOR 操作码,设置所需字段中的相应值,然后将该 UPIU 发送到目标设备。带 WRITE DESCRIPTOR 操作码的 QUERY REQUEST UPIU 还将包含一个数据段,其中包含主机要发送给设备的描述符数据。
收到 QUERY REQUEST UPIU 后,设备解码 WRITE DESCRIPTOR 操作码字段,并访问由 DESCRIPTOR IDN 字段、INDEX 字段和 SELECTOR 字段指示的描述符。设备从 UPIU 的数据段中提取描述符数据,内部覆盖寻址的描述符。设备完成此过程后,将通过向主机返回带响应码的 QUERY RESPONSE UPIU 来通知主机此操作成功或失败。
传输完 QUERY RESPONSE UPIU 后,设备认为操作完成。
收到 QUERY RESPONSE UPIU 后,主机解码 RESPONSE 字段和 UPIU 中的其他字段,并采取适当的完成操作。收到 QUERY RESPONSE UPIU 后,主机认为操作完成。

14.1.4 Descriptor Definitions描述符定义
14.1.4.1 Generic Descriptor Format通用描述符格式
所有描述符的格式都以一个头部开始,头部包含描述符的长度和标识特定描述符类型的类型值。长度值包括头部的长度和任何附加数据。

对于单元描述符,格式包括要寻址的单元的指示。

14.1.4.2 Device Descriptor设备描述符
这是主描述符,应该是第一个检索的描述符,因为它指定了设备类和子类、用于访问此设备的协议(命令集),以及包含的最大逻辑单元数。设备描述符是只读的,其某些参数可以通过写配置描述符中的相应参数来更改。
在 QUERY REQUEST UPIU 中,设备描述符通过以下设置寻址:DESCRIPTOR IDN = 00h,INDEX = 00h,SELECTOR = 00h。
a) wManufacturerID
此参数包含设备制造商的标识信息。制造商 ID 由 JEDEC 标准制造商识别码 [JEP106] 定义。wManufacturerID 由两个字段组成:制造商 ID 码和 Bank Index。

b) Bank Index
此字段包含包含制造商识别码的库的索引值。Bank Index 值应等于 [JEP106] 中指定的制造商识别码之前的连续字段数量。
c) Manufacturer ID Code
JEDEC 标准制造商识别码 [JEP106] 中定义的制造商识别码。
14.1.4.3 Configuration Descriptor配置描述符
制造商设置的设备配置可以通过写配置描述符来修改。特别是,配置描述符允许配置设备描述符、RPMB 单元描述符和单元描述符中包含的参数。如果 bConfigDescrLock 属性值等于 00h,则配置描述符可写。如果 bConfigDescrLock 属性值为 01h,则配置描述符被锁定,写请求应失败。
最多有四个配置描述符。
第一个配置描述符:在 QUERY REQUEST UPIU 中设置 DESCRIPTOR IDN = 01h,INDEX = 00h,SELECTOR = 00h 寻址,用于更改设备描述符、RPMB 单元描述符和前八个单元描述符(LU 0 到 LU 7)中的可配置参数。
第二个配置描述符:设置 DESCRIPTOR IDN = 01h,INDEX = 01h,SELECTOR = 00h,用于更改接下来八个单元描述符(LU 8 到 LU 15)的可配置参数。
第三个配置描述符:设置 DESCRIPTOR IDN = 01h,INDEX = 02h,SELECTOR = 00h,用于更改接下来八个单元描述符(LU 16 到 LU 23)的可配置参数。
第四个配置描述符:设置 DESCRIPTOR IDN = 01h,INDEX = 03h,SELECTOR = 00h,用于更改最后八个单元描述符(LU 24 到 LU 31)的可配置参数。
14.2 Flags标志
标志是单个布尔值,表示 TRUE 或 FALSE、'0' 或 '1'、ON 或 OFF 类型的值。
标志可以被清除 / 复位、设置、切换或读取。标志用于使能或禁用设备内的特定功能、模式或状态。
每个标志都定义了读访问属性(只读或只写)和写访问属性(只读、只写、持久等)。表 14.24 描述了标志支持的访问属性。

14.3 Attributes属性
属性是表示特定范围数值的参数,可以写或读。例如,最大 Data In 数据包大小就是一个属性。属性大小可以是 1 位到 32 位。
同类型的属性可以组织成数组,每个元素通过索引标识。例如,对于逻辑单元特定的参数,LUN 用作索引。
每个属性都定义了读访问属性(只读或只写)和写访问属性(只读、只写一次、持久等)。表 14.26 描述了属性支持的访问属性。

网硕互联帮助中心





评论前必须登录!
注册