Linux SD卡驱动开发(六) —— SD卡启动过程总体分析

本文详细解析Linux内核启动时SD卡的初始化过程,从mmc_init开始,涉及mmc、sd总线注册, mmc_blk_init初始化块设备,通过发送CMD命令检测卡状态,区分SD与MMC卡,直至卡设备成功加入系统并启动块设备驱动。
摘要由CSDN通过智能技术生成

一、工作流程

mmc驱动主要文件包括

drivers/mmc/card/block.c
drivers/mmc/card/queue.c
drivers/mmc/core/core.c
drivers/mmc/core/host.c
drivers/mmc/core/

内核启动时,首先执行core/core.c的mmc_init,注册mmc、sd总线,以及一个host class设备。接着执行card/block.c中,申请一个块设备

二、数据结构:

这里涉及三种总线

1. platform bus //MMC host controller 作为一种 platform device, 它是需要注册到 platform bus上 的  
driver/base/platform.c  
struct bus_type platform_bus_type = {  
    .name        = "platform",  
    .dev_attrs    = platform_dev_attrs,  
    .match        = platform_match,  
    .uevent        = platform_uevent,  
    .pm        = &platform_dev_pm_ops,  
};  
  
2. mmc bus type  //在mmc_init()中被创建的.通过调用 mmc_register_bus() 来注册 MMC 总线  
drivers\mmc\core\bus.c  
static struct bus_type mmc_bus_type = {  
    .name        = "mmc",  
    .dev_attrs    = mmc_dev_attrs,  
    .match        = mmc_bus_match,  
    .uevent        = mmc_bus_uevent,  
    .probe        = mmc_bus_probe,  
    .remove        = mmc_bus_remove,  
    .shutdown        = mmc_bus_shutdown,  
    .pm        = &mmc_bus_pm_ops,  
};  
  
3. sdio bus type    //在mmc_init()中被创建的.通过调用sdio_register_bus() 来注册 SDIO 总线  
drivers\mmc\core\sdio_bus.c  
static struct bus_type sdio_bus_type = {  
    .name        = "sdio",  
    .dev_attrs    = sdio_dev_attrs,  
    .match        = sdio_bus_match,  
    .uevent        = sdio_bus_uevent,  
    .probe        = sdio_bus_probe,  
    .remove        = sdio_bus_remove,  
    .pm        = SDIO_PM_OPS_PTR,  
};  
     其中mmc总线操作相关函数,由于mmc卡支持多种总数据线,如SPI、SDIO、8LineMMC而不同的总线的操作控制方式不尽相同,所以通过此结构与相应的总线回调函数相关联。
//总线操作结构
struct mmc_bus_ops {
    void (*remove)(struct mmc_host *);
    void (*detect)(struct mmc_host *);
    int (*sysfs_add)(struct mmc_host *, struct mmc_card *card);
    void (*sysfs_remove)(struct mmc_host *, struct mmc_card *card);
    void (*suspend)(struct mmc_host *);
    void (*resume)(struct mmc_host *);
};
//  mmc卡的总线操作 core/mmc.c
static const struct mmc_bus_ops mmc_ops = {
    .remove = mmc_remove,
    .detect = mmc_detect,
    .sysfs_add = mmc_sysfs_add,
    .sysfs_remove = mmc_sysfs_remove,
    .suspend = mmc_suspend,
    .resume = mmc_resume,
};
// sd卡的总线操作 core/sd.c
static const struct mmc_bus_ops mmc_sd_ops = {
    .remove = mmc_sd_remove,
    .detect = mmc_sd_detect,
    .sysfs_add = mmc_sd_sysfs_add,
    .sysfs_remove = mmc_sd_sysfs_remove,
    .suspend = mmc_sd_suspend,
    .resume = mmc_sd_resume,
};
// sdio的总线操作 core/sdio.c
static const struct mmc_bus_ops mmc_sdio_ops = {
    .remove = mmc_sdio_remove,
    .detect = mmc_sdio_detect,
};

关于总线操作的函数:

.detect,驱动程序经常需要调用此函数去检测mmc卡的状态,具体实现是发送CMD13命令,并读回响应,如果响应错误,则依次调用.remove、detach_bus来移除卡及释放总线。


三、总体架构

1、kernel启动时,先后执行mmc_init()及mmc_blk_init(),以对mmc设备及mmc块模块进行初始化

mmc/core/core.c  
static int __init mmc_init(void)  
    workqueue = alloc_ordered_workqueue("kmmcd", 0);//建立了一个工作队列w
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值