Kernel 5.10 SD卡专属探测、上电与注册流程分析 (Detect -> Power Up -> Add)

总体控制流:Host 中断 -> 扫描频率 -> SD专属协议握手 -> 加网注册

第一阶段:探测流 (Detect Phase)

  1. 热插拔触发 (mmc_rescan) : 大部分 SD 卡槽带有 Card Detect (CD) 引脚。当物理插入动作发生时,底层主机控制器(如 sdhci)产生中断,唤醒系统工作队列 host->detect 执行 mmc_rescan 函数。
  2. 安全初始环境准备 : 在 mmc_rescan 中,主机控制器会首先给 SD 卡加电并以较低的频率启动轮询。因为所有的 SD 卡在刚插入时强制要求以规范定义的低速进入。它调用 mmc_rescan_try_freq(host, freq),通常以 400KHz 开始盲探。
  3. SD专属协议试探 (mmc_attach_sd) : 在 mmc_rescan_try_freq 内部:
    • 先发送 CMD0 (GO_IDLE_STATE) 让所有卡软复位。
    • 跳过 SDIO 探测(如果 CMD5 无响应)。
    • SD 卡的关键试探 :紧接着发送 CMD8 (SEND_IF_COND) 测试电压兼容性(识别 SD 2.0+ 标志)。
    • 身份最终确认 :由探测转入实质依附过程,调用 mmc_attach_sd(host)

第二阶段:上电协商与初始化 (Power Up & Init Phase)

在 SD 卡的体系中,上电不再是一次性的拉高电平就结束了,而是涉及到复杂的 UHS-I 超高速卡 1.8V 降压切换以及调谐(Tuning)。这是 Kernel 5.10 中 SD 驱动最精华的部分。

  1. 操作条件查询与初始供电 (mmc_send_app_op_cond / mmc_power_up) : 在 mmc_attach_sd 起始阶段,系统发送 CMD55 + ACMD41 (APP_SEND_OP_COND) 命令不断轮询。这不仅仅是检测,同时也在查询卡的可用电压窗口(OCR,Operation Conditions Register)。 只要卡在这个环节宣告 Ready,主机就会依据返回的 OCR 锁定工作电压,通过 mmc_power_up(host, ocr) 调用底层的寄存器(set_ios)把芯片对应的 VDD 管脚真正上电稳定。

  2. 核心状态机拉升 (mmc_sd_init_card): 由于电压稳了,系统真正开始解析 SD 卡,进行一系列经典的协议流动作:

    • CMD2 (ALL_SEND_CID):获取这小板子的出厂身份码,比如闪迪还是金士顿、生产年月。
    • CMD3 (SEND_RELATIVE_ADDR):SD卡与 eMMC 不同,系统会要求 SD 卡自己汇报一个相对地址 (RCA)。之后所有通信基于此地址进行。
    • CMD9 (SEND_CSD):获取卡的核心特征,最主要的是算出这卡到底有多少 GB 容量。
    • CMD7 (SELECT_CARD):拿着刚才得到的 RCA 地址,正式选中这张卡。至此,SD 卡从"待机态(Standby)"完全进入了"传输态(Transfer State)"。
    • CMD8 (APP_SEND_SCR):读取配置寄存器,获知卡支持的特性配置。
  3. UHS-I 电压切换与调谐 (Voltage Switch & Tuning): 如果是高速 SD 卡(如 U1, U3 规格):

    • 主机通过 CMD11 (VOLTAGE_SWITCH) 提示卡。
    • 随即底层控制器把 VCCQ 引脚由 3.3V "热切换" 降维至 1.8V(这是保证高频运转不发热不失真的硬件门槛)。
    • 若进入 SDR50 / SDR104 高速模式,还会调用 mmc_execute_tuning() 连续发送特制波形来测算当前温度和电路阻抗下的最佳时钟采样延时点。

第三阶段:注册投轨向 Linux 报到 (Add Card Phase)

当所有的初始化和降压提速动作跑完后,代码流返回到了最上层的业务归口。

  1. 实体建立 (mmc_add_card) : 执行 err = mmc_add_card(host->card);。在 core/bus.c 中,把前面各种繁杂步骤获得的信息(CID,容量,速率,只读状态等)打包,以此为蓝本作为一个 struct device 实体注入到庞大的 Linux 设备树字典中。
  2. 通报 Block 层 : 随着 device_add 的内部广播,一直监视着 MMC 总线的虚拟块设备驱动 block.c 闻风而动。
  3. 暴露存储空间 (mmc_blk_probe) : 由于前面的协商结果毫无瑕疵,块驱动终于放心地执行 alloc_disk() 并创建 /dev/mmcblkX。 紧接着内核的通用分区代码会自动去读这张卡的第 0 扇区(也就是 MBR / GPT 所在处),识别到 FAT32/ext4 等文件系统布局并抛出如 /dev/mmcblkXp1 等设备接口,最终 udev 层面可借此自动挂载您的 SD 卡卷标至 /mnt/media 内。

关键代码追踪锚点总结

如果在 Kernel 5.10 排查 SD 卡挂载失败的问题,可以顺着以下锚点顺藤摸瓜:

  1. 卡槽没反应 :查中断触发、GPIO配置、或 host.cmmc_rescan 延时队列是否被屏蔽。
  2. 提示超时或电压不匹配 -EINVAL :在 mmc_attach_sd()ACMD41 阶段出问题了,重点看核心板的供电引脚实际电压输出能力与设备树描述是否一致(即 Regulator 稳压器设错了)。
  3. -EILSEQ (信号调谐失败) 或者降速警告 :重点看 mmc_sd_init_card() 中段的电压切换 CMD11 和之后的 mmc_execute_tuning() 过程。
  4. 出现写保护 / 不能读 :查看 slot-gpio.c 中对卡槽旁边的物理 WP (Write Protect) 小拨钮管脚映射。
相关推荐
ShineWinsu2 小时前
对于Linux:动静态库的制作与原理的解析—下
linux·运维·服务器·进程·链接·虚拟地址空间·
RH2312113 小时前
2026.4.16Linux 管道
java·linux·服务器
charlie1145141913 小时前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
handler013 小时前
Linux: 基本指令知识点(2)
linux·服务器·c语言·c++·笔记·学习
liuyukuan3 小时前
如何在win11上打开 WSL2(Windows 的 Linux 子系统)?
linux·windows
橙子也要努力变强4 小时前
Linux信号机制
linux·服务器·网络
shughui4 小时前
FinalShell / Xshell 完整教程(下载+安装+使用,2026最新版)
linux·fiddler·xshell·xftp·finalshell·远程连接工具
程序猿编码4 小时前
给你的网络流量穿件“隐形衣“:手把手教你用对称加密打造透明安全隧道
linux·开发语言·网络·安全·linux内核
pengyi8710154 小时前
私网IP映射公网基础原理,搭配代理IP远程访问入门
linux·服务器·网络
深圳市九鼎创展科技5 小时前
MT8883 vs RK3588 开发板全面对比:选型与场景落地指南
大数据·linux·人工智能·嵌入式硬件·ubuntu