Linux 驱动开发:MMC/SD 驱动模型

关键词:Linux 驱动、MMC、SD 卡、mmc_host、mmc_card、block 子系统、嵌入式系统


在嵌入式开发中,SD 卡和 eMMC 存储器是常见的非易失性存储设备。Linux 对这类设备提供了完整的驱动框架,本文将深入解析 Linux 下 MMC/SD 驱动模型的架构,并结合实际应用举例说明如何定制化适配与调试。

一、MMC/SD 驱动模型概览

1.1 整体架构

Linux 内核中,MMC/SD 驱动主要由以下三个部分组成:

  • 主机控制器驱动(Host Controller Driver)
    提供底层寄存器访问和传输能力。对应结构体为 struct mmc_host

  • 核心层(Core Layer)
    提供协议解析、卡识别、命令封装等逻辑。对应核心文件为 mmc_core.c

  • 卡设备驱动(Card Driver)
    针对具体卡类型(如 SD、eMMC、SDIO)进行处理。主要结构体为 struct mmc_card

[ 上层 VFS ]
     |
[ block 层 ]
     |
[ mmc_blk.ko ]
     |
[ mmc core ]
     |
[ sdhci, dw_mmc, ... host 驱动 ]
     |
[ SoC 寄存器操作 ]

二、核心结构体分析

2.1 mmc_host

该结构体代表一个控制器(控制器可能挂多个卡槽)。注册函数为:

struct mmc_host *mmc_alloc_host(int extra, struct device *dev);

关键字段:

  • ops: 指向主机操作函数集,如 request(), set_ios() 等。
  • caps: 描述主机能力(是否支持高电压、DMA、HS400 等)。
  • f_min / f_max: 支持的最小/最大时钟频率。

2.2 mmc_card

代表一张卡(SD、eMMC、SDIO):

  • type: 卡的类型(MMC_TYPE_SD, MMC_TYPE_MMC 等)
  • ocr: 卡支持的电压范围
  • cid/csd/ext_csd: 卡寄存器信息
  • host: 所属的 mmc_host

识别过程由 mmc_rescan() 实现,会自动执行卡初始化协议流程。

2.3 mmc_driver

卡设备驱动使用:

static struct mmc_driver my_driver = {
    .drv = {
        .name = "my_sd_driver",
    },
    .probe = my_mmc_probe,
    .remove = my_mmc_remove,
};

通常配合 mmc_register_driver() 注册。

三、常用主机控制器驱动

3.1 sdhci(标准主机控制器接口)

用于符合 SD Host Controller 规范的控制器,支持通用的寄存器访问方法:

  • 驱动文件:drivers/mmc/host/sdhci.c
  • 常见平台:高通、NXP、TI 等
  • 平台设备名:sdhci-msm, sdhci-tegra, sdhci-pci

3.2 dw_mmc(DesignWare 控制器)

用于 Synopsys 的 IP,常见于 Rockchip、Samsung:

  • 驱动文件:drivers/mmc/host/dw_mmc.c

四、实际平台适配案例:定制 eMMC 支持

4.1 设备树配置(以高通 QRB5165 平台为例)

&sdhc_1 {
    status = "okay";
    mmc-hs400-1_8v;
    bus-width = <8>;
    non-removable;
    cap-mmc-highspeed;
};

关键属性说明:

  • non-removable: eMMC 固连,非热插拔
  • bus-width: 总线宽度,eMMC 一般为 8bit
  • mmc-hs400-1_8v: 表示支持 HS400 模式

4.2 调试流程

# 查看设备是否挂载成功
ls /dev/mmcblk*

# 查看卡信息
cat /sys/class/mmc_host/mmc0/mmc0:0001/name
cat /sys/class/mmc_host/mmc0/mmc0:0001/ext_csd

# 查看主机控制器属性
cat /sys/class/mmc_host/mmc0/clock
cat /sys/class/mmc_host/mmc0/caps

五、自定义卡设备驱动(比如 SDIO Wi-Fi)

5.1 编写驱动

static const struct sdio_device_id my_wifi_ids[] = {
    { SDIO_DEVICE(0x02DF, 0x9123) },
    { /* sentinel */ }
};

static struct sdio_driver my_wifi_driver = {
    .name       = "my_wifi",
    .id_table   = my_wifi_ids,
    .probe      = my_wifi_probe,
    .remove     = my_wifi_remove,
};

5.2 注册驱动

module_sdio_driver(my_wifi_driver);

六、常见问题与调试建议

问题可能原因解决建议
/dev/mmcblk0 不出现没有识别到卡检查设备树配置与电压时序
频繁超时/CRC 错误电源不稳,线缆质量差检查 PMIC、电源轨
读写速度慢时钟未配置、未启用 DMA开启高速模式,调大 f_max
文件系统损坏热插拔、突然掉电选择合适的文件系统,如 ext4 + journaling

七、结语

MMC/SD 驱动是 Linux 存储子系统中的重要组成,理解其框架有助于快速定位问题与平台适配。无论是使用标准控制器如 SDHCI,还是开发 SDIO 设备驱动,只要掌握了 mmc_hostmmc_card 的核心机制,配合内核日志和 sysfs 接口调试,将事半功倍。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值