[TOC]

drivers/mmc/core/sd_ops.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int mmc_send_ext_addr(struct mmc_host *host, u32 addr)
{
struct mmc_command cmd = {
.opcode = SD_ADDR_EXT,
.arg = addr,
.flags = MMC_RSP_R1 | MMC_CMD_AC,
};

if (!mmc_card_ult_capacity(host->card))
return 0;

return mmc_wait_for_cmd(host, &cmd, 0);
}

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所带来的新挑战:

  1. 全新的物理接口:UHS-II卡在传统SD卡引脚的基础上增加了第二排引脚,用于低电压差分信号(LVDS),以实现数百MB/s的高速传输。内核需要新的逻辑来管理和切换到这个新接口。
  2. 复杂的初始化序列:与传统SD卡简单的命令响应初始化方式不同,UHS-II卡的发现和初始化需要一个独特的、基于特定信号模式的握手过程。
  3. 专用寄存器访问:UHS-II卡的功能、速度模式和配置信息存储在一组扩展功能寄存器中,访问这些寄存器需要一套特殊的命令序列。
  4. 信号训练(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卡时被调用。其工作流程如下:

  1. 发现(Discovery):在标准的SD卡初始化流程中(位于sd.c),当主机发送ACMD41后,UHS-II卡会通过保持CMDDAT0-3线路为高电平来发出一个特殊信号。MMC核心检测到这个信号后,会中止传统流程,转而调用sd_uhs2_start_discovery()函数。
  2. 握手与初始化:该函数会请求底层的主机控制器驱动执行UHS-II的物理层发现序列。这是一个精确的时序操作,成功后,卡和主机就建立了一个基本的LVDS通信链路。
  3. 读取扩展寄存器:一旦链路建立,sd_uhs2.c中的代码(如sd_uhs2_read_ext_regs)会使用UHS-II专用的命令来读取卡的扩展功能寄存器。这些寄存器描述了卡支持的速度模式、总线宽度(Lane数)、全双工/半双工能力等关键信息。
  4. 模式选择:驱动会比较主机和卡共同支持的最佳模式,并通过sd_uhs2_write_ext_regs将选择的模式(例如,FD156 - 全双工156MB/s)写入卡的寄存器中。
  5. 训练(Training):在正式切换到所选的高速模式之前,必须执行信号训练。sd_uhs2_execute_tuning()函数会请求主机控制器进入训练模式,硬件会发送特定的数据模式,并根据接收到的响应来调整内部的采样点,以确保数据能被无误地读取。
  6. 切换总线模式:训练成功后,驱动会最后一次配置主机控制器,使其正式进入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