1. Linux MMC子系统概述
在嵌入式Linux开发中,MMC(MultiMedia Card)子系统负责管理各类存储卡设备的驱动和协议栈。作为Linux内核中块设备驱动的重要组成部分,MMC子系统涵盖了SD卡、eMMC、SDIO等设备的完整支持链。我曾在多个嵌入式项目中处理过MMC驱动问题,发现这个看似简单的子系统实际暗藏不少玄机。
MMC子系统的代码主要位于drivers/mmc目录下,采用典型的分层架构设计:
- 核心层(core/)提供协议栈和框架接口
- 主机控制器驱动(host/)处理硬件相关操作
- 卡驱动(card/)实现设备识别和初始化
实际开发中最常遇到的坑是:不同厂商的eMMC芯片在初始化时序上的微妙差异,这往往导致同一驱动在不同硬件平台表现迥异。
2. MMC子系统代码走读
2.1 核心数据结构解析
在mmc/core/core.c中,几个关键数据结构构成了子系统的基础:
c复制struct mmc_host { // 描述主机控制器
struct device *parent;
const struct mmc_host_ops *ops;
unsigned int f_min, f_max; // 工作频率范围
u32 ocr_avail; // 支持的电压范围
// ...其他关键字段
};
struct mmc_card { // 描述卡设备
struct mmc_host *host;
unsigned int type; // MMC_TYPE_SD/MMC_TYPE_SDIO等
u32 ocr; // 操作条件寄存器
// ...设备特性字段
};
这些结构体通过mmc_alloc_host()和mmc_add_host()等API进行初始化和注册。我在调试Rockchip平台的eMMC时,曾因未正确设置host->caps导致DDR模式无法启用,这个教训值得分享:
- 检查芯片手册确认支持DDR模式
- 在host驱动中设置MMC_CAP_DDR
- 通过示波器验证时钟信号质量
2.2 设备枚举流程详解
MMC设备的探测过程堪称精妙:
- 主机控制器驱动注册(如
