UFS 驱动调试指南
S100芯片内置 UFS Host 控制器,硬件最高支持 UFS3.1协议,软件接口最高支持3.0,支持 HS-G4速率 模式,支持2路数据通道。本文档介绍 UFS 驱动的开发、配置和调试方法。
UFS 硬件架构
S100 UFS 控制器特性
S100芯片内置 UFS Host 控制器,支持以下特性:
| 特性 | 说明 |
|---|---|
| UFS 协议版本 | 支持 UFS 2.0 / 2.1 / 3.0 / 3.1 |
| UniPro 版本 | 支持 UniPro 1.61 / 1.8 |
| M-PHY 版本 | 支持 M-PHY 3.0 |
| 速率模式 | HS-G4(11.6Gbps/通道) |
| 数据通道 | 2路数据通道 |
| 功能支持 | 数据高速读写、安全存储 |
硬件模块组成
UFS 子系统由以下几个部分组成:
-
UFS Host Controller (UFSHC) - 主机控制器
- 支持 UFS 3.0协议
- 支持 HS-G4速率(11.6Gbps/通道)
- 支持2路数据通道
- 内置 SCSI 命令队列管理
-
MPHY - 物理层接口
- 支持 Rate A 和 Rate B 两种速率模式
- 支持发射端均衡器(Tx Equalization)配置
- 支持自动校准功能
-
系统寄存器控制
- 时钟门控控制
- 复位控制
- AXI 缓存配置
软件架构
┌─────────────────────────────────────────────────────────────┐
│ 应用层 │
├─────────────────────────────────────────────────────────────┤
│ 文件系统层 │
├─────────────────────────────────────────────────────────────┤
│ 块设备层 │
├─────────────────────────────────── ──────────────────────────┤
│ SCSI子系统 │
├─────────────────────────────────────────────────────────────┤
│ UFS核心层 (ufshcd) │
│ ┌───────────┬───────────┬───────────┬──────────────────┐ │
│ │ UTP传输层 │ UIC控制层 │ DME管理层 │ 电源管理层 │ │
│ └───────────┴───────────┴───────────┴──────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Host Controller层 │
│ ┌──────────────────────────────┐ │
│ │ Hobot UFS HSI层 │ │
│ │ (ufs-hobot.c/ufs-hobot-hsi.c)│ │
│ └──────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ MPHY物理层 │
└─────────────────────────────────────────────────────────────┘
代码路径
# Hobot UFS驱动文件
hobot-drivers/ufs/ufs-hobot.c # 主驱动文件
hobot-drivers/ufs/ufs-hobot.h # 头文件
hobot-drivers/ufs/ufs-hobot-hsi.c # HSI层实现
hobot-drivers/ufs/ufs-hobot-hsi.h # HSI层头文件
hobot-drivers/ufs/Kconfig # 内核配置选项
hobot-drivers/ufs/Makefile # 编译配置
# Linux内核UFS核心代码
drivers/ufs/core/ufshcd.c # UFS核心层
drivers/ufs/core/ufshcd.h # UFS核心头文件
drivers/ufs/host/ufshcd-pltfrm.c # 平台驱动层
# 设备树配置
kernel-dts/drobot-s100-soc.dtsi # S100 SoC配置
内核配置
配置选项说明
编辑内核配置文件 hobot-drivers/configs/drobot_s100_defconfig:
# UFS核心支持
CONFIG_SCSI_UFSHCD=y # 使能UFS Host Controller驱动
CONFIG_SCSI_UFSHCD_PLATFORM=y # 平台驱动支持
# Hobot UFS驱动
CONFIG_SCSI_UFS_HOBOT=y # Hobot UFS Host控制器驱动
CONFIG_SCSI_UFS_HOBOT_OCS_POLL=n # OCS轮询模式(调试用)
# SCSI和块设备支持
CONFIG_SCSI=y # SCSI子系统
CONFIG_BLK_DEV_SD=y # SCSI磁盘支持
# 电源管理
CONFIG_PM=y # 电源管理支持
CONFIG_PM_RUNTIME=y # 运行时电源管理
使用 mk_kernel 配置
# 打开menuconfig配置界面
./mk_kernel.sh menuconfig
# 搜索UFS相关配置
# 在menuconfig界面中输入 / 进行搜索,输入 "UFS"
U-Boot 下使用 UFS
U-Boot 下 UFS 运行在 HS-GEAR4模式,支持在 U-Boot console 下使用标准 SCSI 命令访问 UFS 设备。
常用 SCSI 命令
| 命令 | 说明 | 示例 |
|---|---|---|
scsi info | 查看所有可用的 UFS 设备信息 | scsi info |
scsi device [dev] | 切换选中的 UFS 设备 | scsi device 0 |
scsi part [dev] | 查看 UFS 设备分区信息 | scsi part 0 |
scsi read addr blk# cnt | 从 UFS 读取数据到内存 | scsi read 0x80000000 0x1000 0x100 |
scsi write addr blk# cnt | 将内存数据写入 UFS | scsi write 0x80000000 0x1000 0x100 |
U-Boot 下 ext4文件系统操作
# 查看ext4分区内容
ext4ls scsi 0:17
# 从ext4分区加载文件到内存
ext4load scsi 0:17 0x80000000 /boot/Image
# 将内存数据写入ext4分区
ext4write scsi 0:17 0x80000000 /newfile 0x10000
DTS 设备节点配置
S100 SoC 配置 (drobot-s100-soc.dtsi)
ufs: ufs@0x39410000 {
power-domains = <&scmi_smc_pd PD_IDX_LSPERI_TOP>;
status = "okay";
compatible = "drobot,s100-ufshc";
reg = <0 0x39410000 0 0x10000>, /* UFS控制器寄存器 */
<0x0 0x39010000 0x0 0x1000>, /* UFS系统寄存器 */
<0x0 0x39000000 0x0 0x1000>; /* UFS时钟寄存器 */
interrupt-parent = <&gic>;
interrupts = <0 PERISYS_UFSHC_S_INTR PERISYS_UFSHC_S_INTR_TRIG_TYPE>;
ref-clk-freq = <26000000>; /* 参考时钟频率26MHz */
lanes-per-direction = <2>; /* 2路数据通道 */
pinctrl-names = "default";
pinctrl-0 = <&peri_ufs>; /* 引脚配置 */
/* 从eFuse获取MPHY校准值 */
ufstrim_flag_reg_pa = <0xCDF704C>; /* 校准标志寄存器地址 */
ufstrim_reg_pa = <0xCDF7014>; /* 校准值寄存器地址 */
/* 发射端均衡器配置 */
tx_eq_main_pre_post = <35 0 0>; /* main=35, pre=0, post=0 */
};
DTS 参数说明
| 参数 | 说明 | 示例值 |
|---|---|---|
compatible | 驱动匹配字符串 | "drobot,s100-ufshc" |
reg | 寄存器地址范围 | 控制器/系统/时钟寄存器 |
interrupts | 中断配置 | GIC SPI 中断 |
ref-clk-freq | 参考时钟频率 | 26000000 (26MHz) |
lanes-per-direction | 每方向数据通道数 | 2 |
ufstrim_flag_reg_pa | 校准标志寄存器物理地址 | 0xCDF704C |
ufstrim_reg_pa | 校准值寄存器物理地址 | 0xCDF7014 |
tx_eq_main_pre_post | 发射均衡器参数 | <main pre post> |
调试方法
1. 检查 UFS 设备识别
# 查看UFS设备是否被正确识别
ls /dev/sda*
# 应显示 /dev/sda 和分区(如 /dev/sda1, /dev/sda2)
# 查看块设备信息
lsblk
# 显示UFS磁盘及其分区
# 查看SCSI设备
cat /proc/scsi/scsi
# 应显示UFS设备信息
2. 查看 UFS 驱动加载状态
# 查看驱动是否加载
lsmod | grep ufs
# 应显示 ufs_hobot 模块
# 查看内核日志中的UFS相关信息
dmesg | grep -i ufs
# 查看UFS控制器状态
cat /sys/class/scsi_host/host*/proc_name
# 应显示 "ufshcd"
3. 文件系统操作
格式化 UFS 分区
# 将UFS分区格式化为ext4格式(例如分区17)注意:会清空所有数据:
mkfs.ext4 /dev/sda17
挂载 UFS 分区
# 挂载UFS分区到指定目录
mkdir -p /userdata
mount -t ext4 /dev/sda17 /userdata
# 查看挂载情况
mount | grep sda
文件系统异常处理
当文件系统损坏导致无法挂载时,可通过以下方式处理:
# 使用fsck工具检测和修复ext4文件系统
fsck.ext4 -f /dev/sda17
# 当fsck无法修复时,可考虑格式化(注意:会清空所有数据)
mkfs.ext4 /dev/sda17
4. 使用 ufs-utils 工具
# 查看UFS设备属性
ufs-utils -p /dev/sda info
# 查看UFS健康状态
ufs-utils -p /dev/sda health
# 查看UFS配置描述符
ufs-utils -p /dev/sda desc
5. UFS 可靠性评估(寿命分析)
由于各个厂商的 UFS 擦写均衡算法不同,UFS 的寿命与具体型号相关,需要根据具体的 UFS 设备数据手册来判断寿命。
查看 UFS 健康状态
Linux 系统每次启动后会自动更新 UFS 设备下的健康状态节点:
# 查看UFS保留块状态
cat /sys/devices/platform/soc/*ufs/health_descriptor/eol_info
# 返回值:0x1表示保留块状态正常
# 查看UFS寿命估计值A
cat /sys/devices/platform/soc/*ufs/health_descriptor/life_time_estimation_a
# 返回值范围0x1-0xA表示寿命正常
# 查看UFS寿命估计值B
cat /sys/devices/platform/soc/*ufs/health_descriptor/life_time_estimation_b
# 返回值范围0x1-0xA表示寿命正常