以下整理自 Jollen 筆記(非教學文件),許多地方未能清楚交待,這部份有請大家自行補齊了。本文分享給有志研究 Linux MMC 驅動程式實作(MMC Core)的朋友參考。以下分析基於 Linux 2.6.17.7,更新版本的 kernel 加入了許多 patch(例如 Linux 2.6.19 的 SDHC patch),這些更新內容不在討論之列。
續前一篇日記「Linux(open source)的 SD/MMC/SDIO 支援現況概要」所提到的,目前的 Linux SD/MMC/SDIO 「嚴格來說」,只支援 MMC 記憶卡,如果是要插上 SD 記憶卡,使用上則會有諸多限制。
由 Linux 驅動程式的角度來看,單就 MMC 的部份來分析的話,Linux 的 SD/MMC 驅動程式層包含以下實作(Kconfig):
相關檔案位於 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 層的實作檔案整理如下:
由此可知,MMC Core 層包含以下原始程式碼:
區塊層部份,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。
由於 kobject 會 callback fops 的 probe method,所以 mmc_blk_probe() 函數就是 MMC 區塊層的進入點(entry point)。所以,MMC 區塊層的一切動作就要由 mmc_blk_probe() 函數看起。Linux 2.6.17.7 的 MMC 區塊層使用到大家所熟悉的 genhd.c 層。
至於 Linux 區塊層驅動程式最重要的「初始化 I/O request queue」動作,則是同樣在 mmc_blk_probe() 階段呼叫到 MMC Core 層的 mmc_init_queue() 來完成。
了解 Linux 的 MMC 整體架構後,便能開始深入研究「規格的實作」部份。
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw