[TOC]
drivers/mmc/core/sd_ops.c
1 | int mmc_send_ext_addr(struct mmc_host *host, u32 addr) |
drivers/mmc/core/sd_uhs2.c SD UHS-II总线管理(SD UHS-II Bus Management) 实现UHS-II卡初始化与信号调整
历史与背景
这项技术是为了解决什么特定问题而诞生的?
这项技术是为了支持 SD UHS-II(Ultra High Speed II) 存储卡标准而诞生的。随着专业相机(4K/8K视频录制、RAW格式高速连拍)和高性能计算设备对存储速度要求的不断提升,传统的SD/UHS-I总线(最高104 MB/s)已成为严重的性能瓶颈。UHS-II标准的出现旨在解决此问题,它引入了一套全新的物理接口和协议,以实现更高的数据传输速率。
drivers/mmc/core/sd_uhs2.c 文件中的代码专门用于解决支持UHS-II所带来的新挑战:
- 全新的物理接口:UHS-II卡在传统SD卡引脚的基础上增加了第二排引脚,用于低电压差分信号(LVDS),以实现数百MB/s的高速传输。内核需要新的逻辑来管理和切换到这个新接口。
- 复杂的初始化序列:与传统SD卡简单的命令响应初始化方式不同,UHS-II卡的发现和初始化需要一个独特的、基于特定信号模式的握手过程。
- 专用寄存器访问:UHS-II卡的功能、速度模式和配置信息存储在一组扩展功能寄存器中,访问这些寄存器需要一套特殊的命令序列。
- 信号训练(Training):在如此高的频率下工作,为了保证信号的完整性和可靠的数据传输,主机控制器必须在切换到高速模式之前执行一个“训练”或“调谐(Tuning)”过程,以校准时钟和数据信号的相位。
它的发展经历了哪些重要的里程碑或版本迭代?
UHS-II标准本身是SD卡协会发布的一个重大技术飞跃。在Linux内核中,对其支持是逐步演进的:
- 初期:内核的MMC/SD子系统只能将UHS-II卡识别为普通的UHS-I或更低速的卡,并以降级模式运行。
- 引入专有逻辑:为了支持UHS-II的原生高速模式,社区将与UHS-II相关的、高度专业化的代码从通用的SD卡处理逻辑(
sd.c)中分离出来,创建了sd_uhs2.c。这一步是关键的里程碑,它实现了UHS-II卡的发现、握手和初始化流程。 - 完善与优化:后续的版本迭代主要集中在修复特定主机控制器或UHS-II卡上的兼容性问题,优化训练序列的可靠性,以及添加对UHS-III等更新标准的支持(如果它们共享相似的机制)。
目前该技术的社区活跃度和主流应用情况如何?
sd_uhs2.c是Linux内核MMC子系统中的一个核心且稳定的部分,由该子系统的维护者持续维护。这项技术是任何需要支持UHS-II高速读写的现代Linux系统的必备功能。
- 主流应用:广泛应用于带有高性能SD读卡器的高端笔记本电脑、USB外置读卡器、以及需要高速数据采集的嵌入式系统(例如,专业无人机、高端便携式录音设备等)。
核心原理与设计
它的核心工作原理是什么?
sd_uhs2.c中的代码并不在内核启动时独立运行,而是在通用的SD卡初始化流程中,当检测到可能是UHS-II卡时被调用。其工作流程如下:
- 发现(Discovery):在标准的SD卡初始化流程中(位于
sd.c),当主机发送ACMD41后,UHS-II卡会通过保持CMD和DAT0-3线路为高电平来发出一个特殊信号。MMC核心检测到这个信号后,会中止传统流程,转而调用sd_uhs2_start_discovery()函数。 - 握手与初始化:该函数会请求底层的主机控制器驱动执行UHS-II的物理层发现序列。这是一个精确的时序操作,成功后,卡和主机就建立了一个基本的LVDS通信链路。
- 读取扩展寄存器:一旦链路建立,
sd_uhs2.c中的代码(如sd_uhs2_read_ext_regs)会使用UHS-II专用的命令来读取卡的扩展功能寄存器。这些寄存器描述了卡支持的速度模式、总线宽度(Lane数)、全双工/半双工能力等关键信息。 - 模式选择:驱动会比较主机和卡共同支持的最佳模式,并通过
sd_uhs2_write_ext_regs将选择的模式(例如,FD156 - 全双工156MB/s)写入卡的寄存器中。 - 训练(Training):在正式切换到所选的高速模式之前,必须执行信号训练。
sd_uhs2_execute_tuning()函数会请求主机控制器进入训练模式,硬件会发送特定的数据模式,并根据接收到的响应来调整内部的采样点,以确保数据能被无误地读取。 - 切换总线模式:训练成功后,驱动会最后一次配置主机控制器,使其正式进入UHS-II LVDS模式进行数据传输。至此,
sd_uhs2.c的任务完成,后续的数据传输由MMC核心和主机控制器驱动接管。
它的主要优势体现在哪些方面?
- 极致性能:解锁了UHS-II卡的全部性能潜力,使数据传输速率从UHS-I的约100MB/s提升至300MB/s甚至更高。
- 模块化设计:将复杂的UHS-II专用逻辑封装在一个独立的文件中,避免了对通用SD/MMC代码的侵入,使得代码结构更清晰,更易于维护。
- 遵循标准:严格按照SD卡协会发布的官方规范实现,保证了与标准UHS-II卡和主机的兼容性。
它存在哪些已知的劣势、局限性或在特定场景下的不适用性?
- 高度依赖主机驱动:
sd_uhs2.c本身只实现了协议层的逻辑。所有关键操作(如发现序列、训练)最终都必须由底层的主机控制器驱动程序来实现。如果主机驱动没有实现UHS-II所需的回调函数,或者实现有误,那么UHS-II模式将无法启用。 - 调试困难:UHS-II的初始化过程涉及物理层的精确信号时序,一旦出现问题(如训练失败),很难单纯通过软件日志来判断是卡的问题、主机的问题,还是电路板信号完整性的问题。
- 物理层敏感:由于工作频率极高,UHS-II对PCB板的布线质量和信号完整性要求非常苛刻,硬件设计上的瑕疵很容易导致软件层面上的功能不稳定。
使用场景
在哪些具体的业务或技术场景下,它是首选解决方案?
这是支持UHS-II原生速度的唯一标准解决方案。
- 专业媒体工作站:用于为摄影师、摄像师和视频剪辑师提供服务的Linux工作站或笔记本电脑,需要快速地从UHS-II卡中导入大量的RAW照片和高码率视频素材。
- 高性能外置读卡器:基于Linux的嵌入式系统(例如,一个通过USB-C连接的高速多功能读卡器)需要使用此驱动来支持UHS-II卡。
- 数据记录设备:在科学研究或工业监控领域,需要将高速传感器数据实时写入可移动存储介质的设备。
是否有不推荐使用该技术的场景?为什么?
不存在不推荐使用该技术的场景,只有硬件不支持的场景。如果一个系统的硬件(主机控制器和卡槽)支持UHS-II,那么启用sd_uhs2.c中的逻辑是发挥硬件性能的必要条件。如果硬件不支持,那么这部分代码自然不会被执行,系统会自动回退到UHS-I或更旧的模式。
对比分析
请将其 与 其他相似技术 进行详细对比。
最直接的对比对象是传统的SD/UHS-I协议,其逻辑主要实现在drivers/mmc/core/sd.c中。
| 特性 | SD UHS-II (sd_uhs2.c驱动) |
传统 SD / UHS-I (sd.c驱动) |
|---|---|---|
| 物理接口 | 两排引脚,使用低电压差分信号(LVDS)进行高速传输。 | 单排引脚,使用单端CMOS信号。 |
| 初始化方式 | 复杂的物理层握手和发现序列,访问专用的UHS-II寄存器。 | 基于命令-响应的协议,访问标准的SD卡寄存器(CSD, CID等)。 |
| 总线模式 | 全双工或半双工,使用1或2对差分信号线(Lane)。 | 仅半双工,使用1位或4位数据线。 |
| 信号训练 | 强制要求,在进入高速模式前必须执行复杂的训练序列。 | 对SDR104等高速模式推荐执行,但过程相对简单(使用CMD19)。 |
| 理论最高速率 | FD312模式下可达312 MB/s。 | SDR104模式下最高104 MB/s。 |
| 实现复杂性 | 高。协议层和物理层的交互非常紧密,对主机驱动要求高。 | 中等。是经过多年发展的成熟技术,逻辑相对直接。 |
| 向后兼容性 | 完全兼容。UHS-II卡和主机可以无缝回退到UHS-I或更低模式运行。 | N/A |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 wdfk-prog的个人博客!
评论








