Linux 2.6 的 MMC Core

以下整理自Jollen笔记(非教学文件),许多地方未能清楚交待,这部份有请大家自行补齐了。本文分享给有志研究Linux MMC驱动程序实作(MMC Core)的朋友参考。以下分析基于Linux 2.6.17.7,更新版本的kernel加入了许多patch(例如Linux 2.6.19SDHC patch),这些更新内容不在讨论之列。

    续前一篇日记「Linux(open source)的 SD/MMC/SDIO支援现况概要」所提到的,目前的Linux SD/MMC/SDIO「严格来说」,只支持MMC记忆卡,如果是要插上SD记忆卡,使用上则会有诸多限制。

Linux驱动程序的角度来看,单就MMC的部份来分析的话,LinuxSD/MMC驱动程序层包含以下实作(Kconfig):

  • CONFIG_MMC
  • CONFIG_MMC_BLOCK

相关档案位于 drivers/mmc/ 目录,我们由 Makefile 来找到实作档案:

# Core                                                 

#                                                      

obj-$(CONFIG_MMC)               += mmc_core.o          

                                                       

#                                                       

# Media drivers                                        

#                                                      

obj-$(CONFIG_MMC_BLOCK)         += mmc_block.o         

                                                       

#                                                       

# Host drivers                                         

#                                                      

obj-$(CONFIG_MMC_ARMMMCI)       += mmci.o              

obj-$(CONFIG_MMC_PXA)           += pxamci.o            

obj-$(CONFIG_MMC_IMX)           += imxmmc.o            

obj-$(CONFIG_MMC_SDHCI)         += sdhci.o             

obj-$(CONFIG_MMC_WBSD)          += wbsd.o              

obj-$(CONFIG_MMC_AU1X)          += au1xmmc.o           

obj-$(CONFIG_MMC_OMAP)          += omap.o              

obj-$(CONFIG_MMC_AT91RM9200)    += at91_mci.o          

                                                       

mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o            

Host controller驱动程序的部份先不讨论,MMC Core API层的实作档案整理如下:

  1. drivers/mmc/mmc.c:主要的MMC commandprotocol实作。
  2. drivers/mmc/mmc_queue.c:I/O Request Queue的实作。
  3. drivers/mmc/mmc_sysfs.c:Linux 2.6kobjectsysfs实作。
  4. drivers/mmc/mmc_block.c:区块层架构实作,即interface to user-spacefile operation部份。

由此可知,MMC Core层包含以下原始程序代码:

  • drivers/mmc/mmc.c
  • drivers/mmc/mmc_queue.c
  • drivers/mmc/mmc_sysfs.c

区块层部份,mmc_block.c 以devfs的方式向kernel注册:

static struct mmc_driver mmc_driver = {

         .drv             = {

                 .name    = "mmcblk",

         },

         .probe           = mmc_blk_probe,

         .remove          = mmc_blk_remove,

         .suspend         = mmc_blk_suspend,

         .resume          = mmc_blk_resume,

};

 

static int __init mmc_blk_init(void)

{

         int res = -ENOMEM;

 

         res = register_blkdev(major, "mmc");

         if (res < 0) {

                 printk(KERN_WARNING "Unable to get major %d for MMC media: %d/n",

                        major, res);

                 goto out;

         }

         if (major == 0)

                 major = res;

 

         devfs_mk_dir("mmc");

         return mmc_register_driver(&mmc_driver);

 

 out:

         return res;

}

...

module_init(mmc_blk_init);

mmc_register_driver() MMC Core层注册,接着MMC Core再对 kobject做注册。学过Linux 2.6驱动程序的朋友都晓得,Core API层必须呼叫 driver_register() 向 kobject注册为 Driver;对于底层(machine-dependent)的host controller驱动程序而言,则必须向 kobject注册为 Platform Driver

由于 kobjectcallback fops的 probe method,所以 mmc_blk_probe() 函数就是MMC区块层的进入点(entry point)。所以,MMC区块层的一切动作就要由 mmc_blk_probe() 函数看起。Linux 2.6.17.7MMC区块层使用到大家所熟悉的 genhd.c 层。

至于Linux区块层驱动程序最重要的「初始化I/O request queue」动作,则是同样在 mmc_blk_probe()阶段呼叫到MMC Core层的 mmc_init_queue() 来完成。

了解LinuxMMC整体架构后,便能开始深入研究「规格的实作」部份。

 

 

=================================================================================================

=================================================================================================

 Linux(open source)的 SD/MMC/SDIO 支援現況概要

 

 

SDSecure Digital)与MMCMultimedia Card

SD是一种flash memory card的标准,也就是一般常见的SD记忆卡,而MMC则是较早的一种记忆卡标准,目前已经被SD标准所取代。在维基百科上有相当详细的SD/MMC规格说明:[http://zh.wikipedia.org/wiki/Secure_Digital]

SDIOSecure Digital I/O

SDIO是目前我们比较关心的技术,SDIO故名思义,就是SDI/O接口(interface)的意思,不过这样解释可能还有点抽像。更具体的说明,SD本来是记忆卡的标准,但是现在也可以把SD拿来插上一些外围接口使用,这样的技术便是SDIO

所以SDIO本身是一种相当单纯的技术,透过SDI/O接脚来连接外部外围,并且透过SD上的I/O数据接位与这些外围传输数据,而且SD协会会员也推出很完整的SDIO stack驱动程序,使得SDIO外围(我们称为SDIO卡)的开发与应用变得相当热门。

现在已经有非常多的手机或是手持装置都支持SDIO的功能(SD标准原本就是针对mobile device而制定),而且许多SDIO外围也都被开发出来,让手机外接外围更加容易,并且开发上更有弹性(不需要内建外围)。目前常见的SDIO外围(SDIO卡)有:

  • Wi-Fi card(无线网络卡)
  • CMOS sensor card(照相模块)
  • GPS card
  • GSM/GPRS modem card
  • Bluetooth card
  • Radio/TV card(很好玩)

SDIO的应用将是未来嵌入式系统最重要的接口技术之一,并且也会取代目前GPIO式的SPI接口。

SD/SDIO的传输模式

SD传输模式有以下3种:

  • SPI moderequired
  • 1-bit mode
  • 4-bit mode

SDIO同样也支持以上3种传输模式。依据SD标准,所有的SD(记忆卡)与SDIO(外围)都必须支持SPI mode,因此SPI mode是「required」。此外,早期的MMC卡(使用SPI传输)也能接到SD插糟(SD slot),并且使用SPI mode1-bit mode来读取。

SDMMC Mode

SD也能读取MMC内存,虽然MMC标准上提到,MMC内存不见得要支持SPI mode(但是一定要支持1-bit mode),但是市面上能看到的MMC卡其实都有支持SPI mode。因此,我们可以把SD设定成SPI mode的传输方式来读取MMC记忆卡。

SDMMC Mode就是用来读取MMC卡的一种传输模式。不过,SDMMC Mode虽然也是使用SPI mode,但其物理特性仍是有差异的:

  • MMCSPI mode最大传输速率为20 Mbit/s
  • SDSPI mode最大传输速率为25 Mbit/s

为避免混淆,有时也用SPI/MMC modeSPI/SD mode的写法来做清楚区别。

LinuxSD/MMC驱动程序

Linux 2.6.17正式加入SD/MMC驱动程序,「官方版」的release当然只能在ARM平台上使用,若不讨论host controller的支持,目前的Linux SD/MMC/SDIO支持状况(Core API)如下(Open source compatible for SD/MMC/SDIO):

1.支援MMCOpen source的实作即是SD-MMC的驱动程序。

2. Core API「可以做到」支持SD/SPI mode only,因为有办法做到支持SPI mode,当然1-bit mode也「可以想办法」做出来。将1-bit mode扩充至4-bit mode,网络上虽然有人做,不过会有版权问题。

3. SDIO目前只看到Atheros Wi-Fi card的支持(可在sourceforge上找到,已正式释出source code)。

4.完整的SD stack是要付钱的,请特别注意,SD Card Association product license agreement并「不」允许open source的驱动程序实作。所以也不用再问,为什么没有open sourceSD驱动程序了;Linux是无罪的!

请特别留意的是,以上所述是「官方」的正式支持,并不包含玩家所分享的各种patch

=================================================================================================

=================================================================================================

=================================================================================================

=================================================================================================