Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1357334
  • 博文数量: 281
  • 博客积分: 8800
  • 博客等级: 中将
  • 技术积分: 3346
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-17 22:31
文章分类

全部博文(281)

文章存档

2013年(1)

2012年(18)

2011年(16)

2010年(44)

2009年(86)

2008年(41)

2007年(10)

2006年(65)

我的朋友

分类: LINUX

2009-04-08 21:16:03

發表於January 20, 2007 12:06 AM 发表于January 20, 2007 12:06 AM

以下整理自Jollen 筆記(非教學文件),許多地方未能清楚交待,這部份有請大家自行補齊了。以下整理自Jollen笔记(非教学文件),许多地方未能清楚交待,这部份有请大家自行补齐了。 本文分享給有志研究Linux MMC驅動程式實作(MMC Core)的朋友參考。本文分享给有志研究Linux MMC驱动程式实作(MMC Core)的朋友参考。 以下分析基於Linux 2.6.17.7,更新版本的kernel 加入了許多patch(例如Linux 2.6.19 的SDHC patch ),這些更新內容不在討論之列。以下分析基于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(open source)的SD/MMC/SDIO支援现况概要 」所提到的,目前的Linux SD/MMC/SDIO 「严格来说」,只支援MMC记忆卡,如果是要插上SD记忆卡,使用上则会有诸多限制。

由Linux 驅動程式的角度來看,單就MMC 的部份來分析的話,Linux 的SD/MMC 驅動程式層包含以下實作( Kconfig ):由Linux驱动程式的角度来看,单就MMC的部份来分析的话,Linux的SD/MMC驱动程式层包含以下实作( Kconfig ):

  • CONFIG_MMC CONFIG_MMC
  • CONFIG_MMC_BLOCK CONFIG_MMC_BLOCK

相關檔案位於drivers/mmc/目錄,我們由Makefile來找到實作檔案:相关档案位于drivers/mmc/目录,我们由Makefile来找到实作档案:

 # #                                                        
 # Core # Core                                                   
 # #                                                        
 obj-$(CONFIG_MMC)               += mmc_core.o obj-$(CONFIG_MMC) += mmc_core.o         
                                                        
 # #                                                        
 # Media drivers # Media drivers                                          
 # #                                                        
 obj-$(CONFIG_MMC_BLOCK)         += mmc_block.o obj-$(CONFIG_MMC_BLOCK) += mmc_block.o        
                                                        
 # #                                                        
 # Host drivers # Host drivers                                           
 # #                                                        
 obj-$(CONFIG_MMC_ARMMMCI)       += mmci.o obj-$(CONFIG_MMC_ARMMMCI) += mmci.o                
 obj-$(CONFIG_MMC_PXA)           += pxamci.o obj-$(CONFIG_MMC_PXA) += pxamci.o              
 obj-$(CONFIG_MMC_IMX)           += imxmmc.o obj-$(CONFIG_MMC_IMX) += imxmmc.o              
 obj-$(CONFIG_MMC_SDHCI)         += sdhci.o obj-$(CONFIG_MMC_SDHCI) += sdhci.o               
 obj-$(CONFIG_MMC_WBSD)          += wbsd.o obj-$(CONFIG_MMC_WBSD) += wbsd.o                
 obj-$(CONFIG_MMC_AU1X)          += au1xmmc.o obj-$(CONFIG_MMC_AU1X) += au1xmmc.o             
 obj-$(CONFIG_MMC_OMAP)          += omap.o obj-$(CONFIG_MMC_OMAP) += omap.o                
 obj-$(CONFIG_MMC_AT91RM9200)    += at91_mci.o obj-$(CONFIG_MMC_AT91RM9200) += at91_mci.o            
                                                        
 mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o            

Host controller 驅動程式的部份先不討論,MMC Core API 層的實作檔案整理如下: Host controller驱动程式的部份先不讨论,MMC Core API层的实作档案整理如下:

  1. drivers/mmc/mmc.c :主要的MMC command 與protocol 實作。 drivers/mmc/mmc.c :主要的MMC command与protocol实作。
  2. drivers/mmc/mmc_queue.c :I/O Request Queue 的實作。 drivers/mmc/mmc_queue.c :I/O Request Queue的实作。
  3. drivers/mmc/mmc_sysfs.c :Linux 2.6 的kobjectsysfs實作。 drivers/mmc/mmc_sysfs.c :Linux 2.6的kobjectsysfs实作。
  4. drivers/mmc/mmc_block.c :區塊層架構實作,即interface to user-space 的file operation 部份。 drivers/mmc/mmc_block.c :区块层架构实作,即interface to user-space的file operation部份。

由此可知,MMC Core 層包含以下原始程式碼:由此可知,MMC Core层包含以下原始程式码:

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

區塊層部份, mmc_block.c以devfs 的方式向kernel 註冊:区块层部份, mmc_block.c以devfs的方式向kernel注册:

 static struct mmc_driver mmc_driver  = { static struct mmc_driver mmc_driver = { 
	 .drv  = { .drv = { 
		 .name = "mmcblk", .name = "mmcblk", 
	 }, }, 
	 .probe  = mmc_blk_probe, .probe = mmc_blk_probe, 
	 .remove  = mmc_blk_remove, .remove = mmc_blk_remove, 
	 .suspend  = mmc_blk_suspend, .suspend = mmc_blk_suspend, 
	 .resume  = mmc_blk_resume, .resume = mmc_blk_resume, 
 }; }; 

 static int __init mmc_blk_init(void) static int __init mmc_blk_init(void) 
 { { 
	 int res = -ENOMEM; int res = -ENOMEM; 

	 res = register_blkdev(major, "mmc"); res = register_blkdev(major, "mmc"); 
	 if (res < 0) { if (res < 0) { 
		 printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n", printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n", 
		        major, res); major, res); 
		 goto out; goto out; 
	 } } 
	 if (major == 0) if (major == 0) 
		 major = res; major = res; 

	 devfs_mk_dir("mmc"); devfs_mk_dir("mmc"); 
	 return mmc_register_driver(&mmc_driver); return mmc_register_driver(&mmc_driver); 

  out: out: 
	 return res; return res; 
 } } 
 ... ... 
 module_init(mmc_blk_init); module_init(mmc_blk_init); 

mmc_register_driver()向MMC Core 層註冊,接著MMC Core 再對kobject做註冊。 mmc_register_driver()向MMC Core层注册,接着MMC Core再对kobject做注册。 學過Linux 2.6 驅動程式的朋友都曉得,Core API 層必須呼叫driver_register()kobject註冊為Driver ;對於底層(machine-dependent)的host controller 驅動程式而言,則必須向kobject註冊為Platform Driver学过Linux 2.6驱动程式的朋友都晓得,Core API层必须呼叫driver_register()kobject注册为Driver ;对于底层(machine-dependent)的host controller驱动程式而言,则必须向kobject注册为Platform Driver

由於kobject會callback fopsprobe method,所以mmc_blk_probe()函數就是MMC 區塊層的進入點(entry point)。由于kobject会callback fopsprobe method,所以mmc_blk_probe()函数就是MMC区块层的进入点(entry point)。 所以,MMC 區塊層的一切動作就要由mmc_blk_probe()函數看起。所以,MMC区块层的一切动作就要由mmc_blk_probe()函数看起。 Linux 2.6.17.7 的MMC 區塊層使用到大家所熟悉的genhd.c層。 Linux 2.6.17.7的MMC区块层使用到大家所熟悉的genhd.c层。

至於Linux 區塊層驅動程式最重要的「初始化I/O request queue」動作,則是同樣在mmc_blk_probe()階段呼叫到MMC Core 層的mmc_init_queue()來完成。至于Linux区块层驱动程式最重要的「初始化I/O request queue」动作,则是同样在mmc_blk_probe()阶段呼叫到MMC Core层的mmc_init_queue()来完成。

了解Linux 的MMC 整體架構後,便能開始深入研究「規格的實作」部份。了解Linux的MMC整体架构后,便能开始深入研究「规格的实作」部份。

阅读(703) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~