• Linux mmc framework1:软件架构


     [部分内容来自] http://www.wowotech.net/comm/mmc_framework_arch.html

    1. 前言

    eMMC基础技术1:MMC简介中MMC、SD、SDIO的介绍可知,这三种技术都是起源于MMC技术,有很多共性,因此Linux kernel统一使用MMC framework管理所有和这三种技术有关的设备。

    本文将基于eMMC基础技术1:MMC简介对MMC技术的介绍,学习Linux kernel MMC framework的软件架构。

    2. 软件架构

    Linux kernel的驱动框架有两个要点(尽管本站前面的文章已经多次强调,本文还是要再说明一下,因为这样的设计思想,说一千遍都不会烦):

    1)抽象硬件(硬件架构是什么样子,驱动框架就应该是什么样子)。

    2)向“客户”提供使用该硬件的API(之前我们提到最多的客户是“用户空间的Application”,不过也有其它“客户”,例如内核空间的其它driver、其它framework)。

    以本文的描述对象为例,MMC framework的软件架构如下面“图片1”所示:

    mmc_architecture

    图片1 Linux MMC framework软件架构

    MMC framework分别有“从左到右”和“从下到上”两种层次结构。

    1) 从左到右

    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卡等等)。

    2)从下到上

    MMC framework从下到上也有3个层次(老生常谈了):

    MMC core位于中间,是MMC framework的核心实现,负责抽象host、bus、card等软件实体,负责向底层提供统一、便利的编写Host controller driver的API;

    MMC host controller driver位于底层,基于MMC core提供的框架,驱动具体的硬件(MMC controller);

    MMC card driver位于最上面,负责驱动MMC core抽象出来的虚拟的card设备,并对接内核其它的framework(例如块设备、TTY、wireless等),实现具体的功能。

    3. 模块视图

    图 mmc子系统模块视图

    • card

    block_c:为每个mmc设备向block子系统注册为一个块设备,并实现块设备的ops。为每个块设备创建一个request queue, 通过add_disk将磁盘添加到系统中,block子系统就可以对mmc设备进行操作。实现了请求处理函数,同时启动线程来处理block层发下来的request请求

    queue_c:实现request queue的创建、销毁,创建request queue的处理线程

    • core

    core_c:是整个mmc子系统的核心,对上承接mmc子系统的block层,主要提取实现了requset相关的公有操作接口;对下承接具体的控制器,主要提取host ios相关的初始化配置接口,以及bus_type相关的操作, 同时为host提供了相关的接口。

    bus_c:定义mmc_bus_type 总线;

    sdio_bus.c:定义sdio_bus_type总线;

    mmc_c: 实现了mmc_bus_type的mmc_ops,规约了eMMC卡的初始化流程;

    sd_c: 实现了mmc_bus_type的mmc_sd_ops,规约了SD卡的初始化流程;

    sdio_c: 实现了mmc_bus_type的mmc_sdio_ops,规约了SDIO卡的初始化流程;

    mmc_ops.c:定义了eMMC卡相关的一系列操作接口,如go idle,设置电压,设置速率模式

    sd_ops_c: 定义了SD卡相关的一系列操作接口

    sdio_ops_c: 定义了SDIO卡相关的一系列操作接口

    host_c:是对控制器的共有操作进行抽象

    •  host

    xxx-mmc_c:host controller驱动

    4.领域视图

    图 mmc子系统领域视图

    mmc_queue <-> mmc_card  <-> mmc_host 具有一一对应的关系。

    mmc_host:           mmc core使用struct mmc_host来抽象mmc host controller

    mmc_card:          是对mmc device的抽象,由于定义了mmc_bus_type类型的总线,此处mmc_card是与mmc_bus_type配套

    mmc_blk_data:  为block的核心结构体,用于存放mmc block的一些数据,与mmc slot对应

    5. 关键流程

     

    图 mmc子系统总体流程

     

    文件名 文件路径
    main_c kernel/init/main_c
    setup_c arch/arm64/kernel/setup_c
    platform_c driver/of/platform_c
    device_c driver/of/device_c
    block_c drivers/mmc/card/block_c
    core_c drivers/mmc/card/core_c
    xxx_mmc_c driers/mmc/host/xxx_mmc_c
      表 关键流程中的文件及路径说明
    • 向platform bus注册xxx_mmc platform_device

    此处的main_c文件位于kernel/init/main_c,其中的start_kernel是kernel的入口函数,以arm64为例,通过如下的调用流程会调用到arm64_device_init

    start_kernel->

      setup_arch->

        unflatten_device_tree//将dts文件解析成设备树

      rest_init->

        do_initcalls->

          arm64_device_init

    arm64_device_init中会调用of_platform_populate来注册platform_device

    arm64_device_init->

           of_platform_populate->

                  of_platform_bus_create->

                         of_platform_device_create_pdata->

              device_add //此处会创建并注册xxx_mmc platform_device

    • subsys_initcall(mmc_init)注册总线

    mmc_init主要完成mmc bus, mmc host class以及sdio bus的创建

    • mmc_blk_init向mmc bus注册mmc_driver

    通过drivers/mmc/card/block_c中的module_init(mmc_blk_init),完成了mmc_driver向mmc bus的注册

    • 向platform bus注册xxx_mmc platform_driver

    通过drivers/mmc/host/xxx_mmc_c中module_init(owl_mmc_init)完成xxx_mmc platfrom driver向platform bus的注册;

    由于前述arm64_device_init的过程中会完成xxx_mmc platform device的注册,因此此处会触发xxx_mmc_probe的执行

    • 执行mmc_blk_probe

    xxx_mmc_probe的执行最终会触发mmc card的创建和注册,触发mmc_blk_probe的执行;

    xxx_mmc_probe会通过mmc_alloc_host并通过mmc_add_host初始化,最终通过mmc_detect_change完成mmc card的创建和注册,这样就会触发mmc_blk_probe的执行

    xxx_mmc_probe->

      mmc_alloc_host

      mmc_add_host->

        mmc_start_host->

    6.参考文档

    [1]http://www.wowotech.net/comm/mmc_framework_arch.html

     

  • 相关阅读:
    js字符串截取函数slice()、substring()、substr()
    js获取字符串最后一位方法
    支持xhr浏览器:超时设定、加载事件、进度事件
    深入理解ajax系列第一篇——XHR对象
    MySQL命令行操作
    nodejs中mysql用法
    大衍数列
    牌型种数
    加法变乘法
    三羊献瑞
  • 原文地址:https://www.cnblogs.com/smartjourneys/p/6713948.html
Copyright © 2020-2023  润新知