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.c 的 mmc_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) 小拨钮管脚映射。
相关推荐
律宏阔10 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔10 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴10 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千10 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei3710 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei3710 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei3710 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
GeW10 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux
GeW10 小时前
工业场景中的Linux与数据库选型:高端化转型的技术底座
linux
yunwei3711 小时前
eBPF 开发者教程: 简单的 XDP 负载均衡器
linux·后端·性能优化