Linux MMC驱动架构浅析

MMC驱动模型

Linux内核设计了MMC子系统,用于管理MMC/SD等设备,MMC/SD存储设备是一种典型的块设备。MMC子系统的框架结构如下图所示。

块设备(MMC_BLOCK)
块设备的相关驱动,即实现块设备的驱动程序,负责驱动MMC core抽象出来的虚拟的card设备,并对接内核其它的framework(例如块设备、TTY、wifi)等实现具体的功能。如MMC/SD卡设备驱动按照 linux块设备驱动程序的框架实现一个MMC/SD卡的块设备驱动,在 block.c 当中我们可以看到写一个块设备驱动程序时需要的 block_device_operations 结构体变量的定义,其中有 open/release/request 函数的实现,而 queue.c 则是对内核提供的请求队列的封装。

核心层(CORE)
整个MMC的核心层,这部分是不同协议和规范的实现,为MMC控制器(host)层和块设备(card)驱动层提供接口函数。核心层封装了 MMC/SD 卡的命令(CMD),例如存储卡的识别、设置、读写、识别、设置等命令。core.c 文件是由 sd.c 、 mmc.c 两个文件支撑的, core.c 把 MMC 卡、 SD 卡的共性抽象出来,它们的差别由 sd.c 和 sd_ops.c 、 mmc.c 和 mmc_ops.c 来完成。

控制器层(host)
主机端MMC控制器的驱动,主机控制器则是依赖于平台。针对不同芯片,实现控制器对应的驱动代码。例如中断函数注册,控制器寄存器初始化等等。然后它会向 核心(core)层注册一个主机( host ),用结构 mmc_host_ops 描述,这样核心层就可以拿着这个 host 来操作对应的卡控制器,对核心(core)层是不透明的。


MMC核心(CORE)
MMC协议是一个总线协议,因此包括Host controller、Bus、Card三类实体。相应的,MMC framework抽象出了host、bus、card三个软件实体,以便和硬件一一对应。

Host:负责驱动Host controller,提供诸如访问card的寄存器、检测card的插拔、读写card等操作方法。从设备模型的角度看,host会检测卡的插入,并向bus注册MMC card设备。

Bus:是MMC bus的虚拟抽象,以标准设备模型的方式,收纳MMC card(device)以及对应的MMC driver(driver);

Card:抽象具体的MMC卡,由对应的MMC driver驱动(从这个角度看,可以忽略MMC的技术细节,只需关心一个个具有特定功能的卡设备,如存储卡、WIFI卡、GPS卡等等)。


块设备层(MMC_BLOCK)
块设备针对不同客户端的设备驱动程序。如SD卡、T-flash卡、SDIO接口的GPS和wi-fi等设备驱动。

驱动模形数据结构

mmc_host:表示一个MMC控制器

mmc_card:MMC设备描述


mmc_driver:MMC操作函数

MMC 模块总线模型

mmc子系统涉及到三条总线:
platform_bus_type:
host设备被封装成platform_device注册到Linux驱动模型中,Host驱动相应的driver和device挂载在Linux内核内置的虚拟抽象总线platform_bus_type。两者的匹配采用名称匹配的方式,即driver和device两者的name一样则认为该device对应该driver
mmc_bus_type:
Card驱动相应的driver和device挂载在mmc自己创建的虚拟总线mmc_bus_type下,直接匹配。
sdio_bus_type:
Sdio驱动相应的driver和device挂载在mmc自己创建的虚拟总线sdio_bus_type下,ID匹配。

瑞芯微MMC总线、驱动、设备框图

瑞芯微MMC设备源码流程分析

瑞芯微MMC驱动源码分析

概述

从上面总线设备驱动之间的关系图以及流程图可知,设备启动时,首先调用subsys_initcall向linux系统注册了mmc_bus和sdio_bus两条总线,用来管理块设备和sdio接口类型的设备。接着调用module_init向系统注册了一条mmc_rpmb_bus总线、一个mmc块设备和MMC driver。最后调用module_platform_driver,把mmc controler注册到platform总线,同时扫描一次挂载到mmc控制器上的设备。

这里有几个重要的对象,即mmc_host、mmc_card、mmc driver。针对mmc controller,该子系统抽象为mmc_host,用于描述一个mmc 控制器;针对mmc、sd、tf卡等,该子系统抽象为mmc_card,用于描述卡信息;针对通信总线,抽象出mmc_bus;针对mmc、sd、tf,mmc子系统完成了统一的mmc driver,针对mmc总线规范以及SD规范,其已经详细的定义了一个存储卡的通信方式、通信命令,因此LINUXmmc子系统定义了mmc driver,用于和mmc、sd、tf等卡的通信,而不需要驱动开发人员来开发卡驱动。

从上面的图中看到,在mmc总线模型中只注册了一个mmc driver,该驱动适配所有的mmc card。一个mmc host与一个mmc card绑定。Mmc card属于热插拔的设备,而mmc card的创建主要由mmc host负责探测与创建,mmc host根据卡在位检测引脚,当检测到mmc card的存在后,即创建mmc card,同时注册至mmc bus上,并完成与mmc driver的绑定操作。
因mmc_card一般均是存储设备,因此针对该设备的访问即需要借助LINUX内核的块设备模型,因此mmc子系统也必须要实现块设备驱动,借助该块设备驱动模型,将mmc card与vfs完成了关联,即可通过系统调用借助VFS模型实现对块设备的读写访问操作。

sdio总线驱动模型和mmc类型,结构体上的区别为其driver类型为sdio_driver,并增加了sdio_func结构体变量(该结构体包含了该sdio设备相关的厂商id、设备id,同时包含了mmc_card),与mmc总线驱动模型的区别为:因sdio主要突出接口概念,其设备端可以连接wifi、gps等设备,因此其外设备驱动需要由驱动工程师自己实现,sdio驱动模块不提供对应的驱动。

MMC bus的定义及其接口分析

MMC bus数据结构


mmc_dev_groups : 定义了dev_attrs属性,针对所有注册到mmc bus上的设备,均会创建mmc_dev_attrs中定义的属性文件
mmc_bus_match :match接口用于实现mmc card与mmc driver的匹配检测,(始终返回1)
mmc_bus_uevent :uevent接口主要用于添加该mmc bus的uevent参数(在调用device_add时,会调用kobject_uevent向应用层发送设备添加相关的事件(通过netlink 发送和 call_usermodehelper机制(向/proc/sys/kernel/hotplug中写入usermodehelper机制调用的应用层程序)),而kobject_uevent会调用该device所属bus和class的uevent接口,添加需要发送到应用的event参数);

mmc_bus_probe :probe接口主要用于mmc card与mmc driver匹配成功后,调用该mmc bus的probe接口实现探测操作

mmc_bus_pm_ops :pm是电源管理相关的接口
mmc_dev_attrs:该属性为所有注册至该总线上的设备所默认创建的,其定义如下,主要提供只读的设备属性,该属性用于提供mmc card的类型,在具体的mmc card目录下(sysfs),会创建type的文件,该文件只读,读取该文件可以获取mmc card的类型,目前支持的类型包括mmc、sd、sdio、sd combo。

mmc_bus_match:该接口主要用于mmc card、mmc driver的匹配检测, mmc bus的mmc driver由mmc 子系统实现,且针对mmc/sd/emmc等存储卡设备,其均与mmc子系统实现的mmc driver匹配,因此此处的mmc_bus_match并没有进行匹配检测,直接返回1,表示mmc 子系统实现的mmc driver可匹配所有注册至mmc bus上的mmc card。
mmc_bus_probe/mmc_bus_remove:这两个接口均直接调用mmc 子系统注册的mmc driver的probe/remove接口,实现简单。

mmc_bus_uevent:该接口主要是提供mmc bus添加的event env,该接口主要提供“MMC_TYPE”、“MMC_NAME”、“MODALIAS”这三个env。若应用层的udev、mdev需要关注mmc card的这三个env,则可以添加对应这三个env的规则即可。
因mmc driver仅有一个,因此针对mmc bus而言其match函数直接返回1,而不需要像spi/i2c总线的match接口那样对设备和驱动进行匹配检测;

因一个mmc控制器仅与一个mmc card关联,且mmc子系统提供了mmc rescan接口,可以实现对mmc host下的mmc card进行扫描并进行mmc card的创建、与mmc host的绑定以及注册至mmc总线上;因此不需要像上述2中所述的i2c/spi那样,将所有已注册的控制器设备链接在一起方便查找从而实现i2c/spi设备的注册与绑定;
因mmc/emmc协议规范已经规定了访问mmc card的命令格式以及相应的寄存器定义,所有mmc/sd/tf/emmc设备均需要遵守,因此mmc子系统针对访问mmc card的命令抽象出统一的接口,包括设备状态设置、卡使能去使能、sleep/awake、poweroff notify、cid/rca/dsr/csd寄存器读写、通过mmc switch命令实现与extend csd寄存器的读写等接口

续待......

Linux MMC驱动架构浅析相关推荐

  1. Linux MMC 驱动子系统详解

    Linxu MMC 驱动子系统 文章目录 Linxu MMC 驱动子系统 硬件关联 目录说明 mmc子系统的逻辑架构 设备-总线-驱动模型 一.MMC驱动抽象模型 二.SDIO驱动抽象模型 三.MMC ...

  2. Linux网络驱动架构

    转载来自:https://blog.csdn.net/zhoudengqing/article/details/47406821 转 Linux网络驱动架构 2015年08月10日 22:54:39 ...

  3. USB 驱动架构浅析

    USB 驱动架构浅析 之前一直概念模糊,最近简单总结了一下 1.USB简介 USB,即Universal Serial Bus(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和 ...

  4. linux 音频架构绕过,linux音频驱动架构

    1.linux音频驱动架构分为3部分组成:硬件无关层(核心层ALSA).板级音频数字接口层驱动(McASP.McBSP等).外部codes驱动 sound/soc/davinci/ti81xx-etv ...

  5. linux I2C驱动架构解析

    I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一条串行数据线:SDA,一条是时钟线SCL ,使用SCL,SDA这两根信号线就实现了设备之间的数据交互,它方便了工程师的布线. ...

  6. linux网络驱动架构,Linux网络体系架构和网卡驱动设计

    Linux网络体系架构 1.Linux的协议栈层次 2.Linux的网络子系统架构 Linux的协议栈层次 Linux的优点之一在于它丰富而稳定的网络协议栈.其范围从协议无关层(例如通用socket层 ...

  7. linux驱动架构变化,Linux网卡驱动架构分析

    一.网卡驱动架构 由上到下层次依次为:应用程序→系统调用接口→协议无关接口→网络协议栈→设备无关接口→设备驱动. 二.重要数据结构 1.Linux内核中每一个网卡由一个net_device结构来描述. ...

  8. linux ALSA 驱动架构

    一.kernel Audio驱动架构主流有两大类,一类是SOC Machine架构,另一类是simple-card架构. MTK.QCom主要采用machine架构,rockchip采用simple ...

  9. linux mmc驱动

    插曲: 因为使用的平台是telechips的tcc803x,其芯片用户手册描述寄存器都是四字节寻址的,但是在代码驱动中用的很可能是单字节寻址,咋一看,有可能有的地址在芯片手册上没有或者感觉写错了,其实 ...

最新文章

  1. 基础编程题之奇数位(偶数位)都是奇数(偶数)
  2. Vue | 实现页面跳转刷新,在Vue页面中调用其他页面的方法
  3. 批处理 安卓一键打包脚本快速解析
  4. 基于redis的悲观锁
  5. linux连接FreeBSD虚拟机的mysql
  6. Kafka系列之-Kafka Protocol实例分析
  7. mysql之主从复制
  8. Ibatis -- 一次执行多条SQL
  9. 吉大计算机学院周柚,周柚
  10. Oracle数据库中查看所有表和字段以及表注释.字段注释
  11. 用python对excel进行图表操作
  12. 关于ob函数的使用和应用场景
  13. php mysql 简单聊天室_PHP实现最简单的聊天室应用
  14. 微信公众平台开通业务域名
  15. 解决win10每次重启后桌面图标排列混乱的问题。
  16. 到底有几个鸿蒙OS? 谈谈我眼里的鸿蒙操作系统
  17. 目标跟踪: 卫星捕获
  18. rfc-3227中文翻译
  19. Paddle-NEAT——飞桨进化神经网络组件
  20. java io importnews_java(JSP)读写文件操作

热门文章

  1. 热烈祝贺GFC东南亚区块链技术峰会圆满成功
  2. Scala系列-5、scala中的泛型、actor、akka
  3. cmd shutdown命令:关机,重启,休眠
  4. (三)Alian 的 Spring Cloud Eureka Server(服务注册中心)
  5. 单位阶跃函数,δ函数, gamma函数
  6. 北京大学计算机硕博连读5年,关于2019年北京大学硕博连读研究生选拔工作的通知...
  7. android点击事件透传,点击事件透传机制
  8. android vr播放器 躺着,Android使用得图SDK开发VR播放器
  9. 推荐系统之YoutubeDNN代码详解
  10. size mismatch for fc.weight: copying a param with shape torch.Size([1000, 2048]) from checkpoint, th