当前位置:首页 >> 信息与通信 >>

嵌入式linux SD卡驱动学习之我理解


嵌入式 linux SD 卡驱动学习之我理解

目录
一 开发板上的 SD 硬件资源 .........................................................................................................3 1 开发板 SD 资源 ..............

.....................................................................................................3 2 电路图 ..................................................................................................................................3 3 ARM 芯片管脚分配..............................................................................................................4 二开发板上的 SD 软件资源 ...........................................................................................................6 三 学习软件相关的内容 ................................................................................................................6 1 内核中 SD 相关代码路径 ...................................................................................................6 2 MMC/SD 设备驱动在 Linux 中的结构层次 .......................................................................6 3 SD 协议概要及命令 .............................................................................................................7 3.1 总线接口 ...................................................................................................................7 3.2 SD 协议命令 ..............................................................................................................8 3.3 请求处理流程 ........................................................................................................10 4 MMC/SD 卡设备驱动程序分析.........................................................................................12 4.1 host 数据结构体 ...................................................................................................12 struct s3cmci_host {.........................................................................................12 struct mmc_host {...............................................................................................14 struct s3c24xx_mci_pdata {.............................................................................17 4.2 host 驱动函数 .......................................................................................................17 4.2.1 驱动注册,注销函数...................................................................................17 4.2.2 platform_driver 接口函数.........................................................................17 4.2.3 探针函数.......................................................................................................18 4.3 mmc 接口操作 .........................................................................................................19 4.3.1 mmc_host_ops 接口函数结构 ......................................................................19 4.3.2 其他接口函数.............................................................................................20 4.4 SD 卡移植方法 .......................................................................................................21

第 2 页 共 20 页 Create by binmn 2011-4-29

一 开发板上的 SD 硬件资源
1 开发板 SD 资源
文件《01- Tiny6410 硬件手册-20110322.pdf》

2 电路图
文件《Tiny6410SDK-1103-底板原理图.pdf》

第 3 页 共 20 页 Create by binmn 2011-4-29

3 ARM 芯片管脚分配
《Tiny6410-1107.pdf》中芯片 S3C6410 上对应的引脚为

第 4 页 共 20 页 Create by binmn 2011-4-29

从上面可以看到,SD 功能的引脚分配在 PORT G 上,所以可以在《S3C6410X.pdf》查到 相关的设置::page324<GPG~> page952<SD fuction>

第 5 页 共 20 页 Create by binmn 2011-4-29

二开发板上的 SD 软件资源
Linux 系统资源中的驱动程序提供: - SD 卡驱动,可支持高速 SD 卡, 最大容量可达 32G(源代码)

三 学习软件相关的内容
1 内核中 SD 相关代码路径
linux-2.6.38.2\include\linux\ Fs.h 文件系统代码 linux-2.6.38.2\include\linux\ Blkdev.h Genhd.h 块设备代码 linux-2.6.38.2\include\linux\mmc linux-2.6.38.2\drivers\mmc 卡的协议命令,SD 寄存器数据的结构等 SD 卡驱动代码,包含 card,core, host 三个文件夹

linux-2.6.38.2\include\linux\ platform_device.h 平台设备代码, \linux-2.6.38.2\arch\arm\mach-s3c2440\Mach-smdk2440.c 具体芯片的平台设置 \linux-2.6.38.2\arch\arm\plat-s3c24xx\Devs.c \linux-2.6.38.2\arch\arm\plat-s3c24xx\include\plat\Mci.h

2 MMC/SD 设备驱动在 Linux 中的结构层次
在 Linux 中 MMC/SD 卡 的 记 忆 体 都 当 作 块 设 备 。 MMC/SD 设 备 驱 动 代 码 在 linux-2.6.38.2\drivers\mmc 分别有 card、core 和 host 三个文件夹, card 层就是要把操作的数据以块设备的处理方式写到记忆体上或从记忆体上读取; core 层则是将数据以何种格式,何种方式在 MMC/SD 主机控制器与 MMC/SD 卡的记 忆体(即块设备)之间进行传递,这种格式、方式被称之为规范或协议, host 层下的代码就是你要动手实现的具体 MMC/SD 设备驱动了,包括 RAM 芯片中的 SDI 控制器(支持对 MMC/SD 卡的控制,俗称 MMC/SD 主机控制器)和 SDI 控制器
第 6 页 共 20 页 Create by binmn 2011-4-29

与 MMC/SD 卡的硬件接口电路。 那么,card、core 和 host 这三层的关系,我们用一幅图来进行描述,图如下:

从这幅图中的关系可以看出,整个 MMC/SD 模块中最重要的部分是 Core 核心层,他提供 了一系列的接口函数,对上提供了将主机驱动注册到系统,给应用程序提供设备访问接口,对下 提供了对主机控制器控制的方法及块设备请求的支持。 对于主机控制器的操作就是对相关寄存器 进行读写,而对于 MMC/SD 设备的请求处理则比较复杂。

3 SD 协议概要及命令
3.1 总线接口 按照 SD 卡的协议的描述可分为 2 种总线的接口 SD BUS 物理层定义: D0-D3 数据传送 CMD 进行 CMD 和 Respons CLK 大家最熟悉的 HOST 时钟信号线了 VDD VSS 电源和地 SPI BUS 一般用 SPI 协议的接口来做 物理层定义: CLK HOST 时钟信号线了 DATAIN HOST-àSD Card 数据信号线 DATAOUT SD Card àHOST 数据信号线
第 7 页 共 20 页 Create by binmn 2011-4-29

3.2 SD 协议命令 关于 SD 协议的具体操作,在规范中有详细的说明,请参考《SD Memory Card Specifications V1..0》,命令总共可分为 9 类,以下是周立功开发板资料中的一部分 SD 命令宏定义代码:
/******************************** Class0 : 基本命令集Basic command set **************************/ /* 复位SD 卡Reset cards to idle state */ #define CMD0 0 #define CMD0_R R1 /* 读OCR寄存器,不适用于SD卡Read the OCR (MMC mode, do not use for SD cards) */ #define CMD1 1 #define CMD1_R R1 /* 读CSD寄存器Card sends the CSD */ #define CMD9 9 #define CMD9_R R1 /* 读CID寄存器Card sends CID */ #define CMD10 10 #define CMD10_R R1 /* 停止读多块时的数据传输Stop a multiple block (stream) read/write operation */ #define CMD12 12 #define CMD12_R R1B /* 读Card_Status 寄存器Get the addressed card's status register */ #define CMD13 13 #define CMD13_R R2 /***************************** Class2:块读命令集Block read commands **************************/ /* 设置块的长度Set the block length */ #define CMD16 16 #define CMD16_R R1 /* 读单块Read a single block */ #define CMD17 17 #define CMD17_R R1 /* 读多块,直至主机发送CMD12为止Read multiple blocks until a CMD12 */ #define CMD18 18 #define CMD18_R R1 /***************************** Class4:块写命令集Block write commands *************************/ /* 写单块Write a block of the size selected with CMD16 */ #define CMD24 24 #define CMD24_R R1 /* 写多块Multiple block write until a CMD12 */ #define CMD25 25 #define CMD25_R R1 /* 写CSD寄存器Program the programmable bits of the CSD */ 第 8 页 共 20 页 Create by binmn 2011-4-29

#define CMD27 27 #define CMD27_R R1 /*****************************Class6:写保护Write protection *****************************/ /* 设置写保护块的地址Set the write protection bit of the addressed group */ #define CMD28 28 #define CMD28_R R1B /* 擦除写保护块的地址Clear the write protection bit of the addressed group */ #define CMD29 29 #define CMD29_R R1B /* Ask the card for the status of the write protection bits */ #define CMD30 30 #define CMD30_R R1 /***************************** Class5:擦除命令Erase commands *******************************/ /* 设置擦除块的起始地址(只用于SD卡) Set the address of the first write block to be erased(only for SD) */ #define CMD32 32 #define CMD32_R R1 /* 设置擦除块的终止地址(只用于SD卡) Set the address of the last write block to be erased(only for SD) */ #define CMD33 33 #define CMD33_R R1 /* 设置擦除块的起始地址(只用于MMC卡) Set the address of the first write block to be erased(only for MMC) */ #define CMD35 35 #define CMD35_R R1 /* 设置擦除块的终止地址(只用于MMC卡) Set the address of the last write block to be erased(only for MMC) */ #define CMD36 36 #define CMD36_R R1 /* 擦除所选择的块Erase the selected write blocks */ #define CMD38 38 #define CMD38_R R1B /***************************** class7:锁卡命令Lock Card commands ***************************/ /* 设置/复位密码或上锁/解锁卡Set/reset the password or lock/unlock the card */ #define CMD42 42 #define CMD42_R R1B /* Commands from 42 to 54, not defined here */ /***************************** 应用命令Application-specific commands ****************/ /* 通知该卡下个命令是条特殊命令,而不是标准命令 Flag that the next command is application-specific */ #define CMD55 55 #define CMD55_R R1 /* 应用命令的通用I/O General purpose I/O for application-specific commands */ #define CMD56 56 第 9 页 共 20 页 Create by binmn 2011-4-29

#define CMD56_R R1 /* 读OCR寄存器 Read the OCR (SPI mode only) (电源配置寄存器)*/ #define CMD58 58 #define CMD58_R R3 /* CRC使能或禁止CRC Turn CRC on or off */ #define CMD59 59 #define CMD59_R R1 /***************************** 应用命令Application-specific commands ***************/ /* 获取SD Status寄存器Get the SD card's status */ #define ACMD13 13 #define ACMD13_R R2 /* 得到已写入卡中的块的个数Get the number of written write blocks (Minus errors ) */ #define ACMD22 22 #define ACMD22_R R1 /* 在写之前,设置预先擦除的块的个数Set the number of write blocks to be pre-erased before writing */ #define ACMD23 23 #define ACMD23_R R1 /* 启动此卡的初始化过程Activates the card’s initialization process */ #define ACMD41 41 #define ACMD41_R R1 /* 连接/断开CD/DATA[3]引脚上的上拉电阻Connect or disconnect the 50kOhm internal pull-up on CD/DAT[3] */ #define ACMD42 42 #define ACMD42_R R1 /* 读取SCR寄存器Get the SD configuration register */ #define ACMD51 51 #define ACMD51_R R1

而 Linux 内核中 SD 协议命令定义在 linux-2.6.38.2\include\linux\mmc\Mmc.h 3.3 请求处理流程

第 10 页 共 20 页 Create by binmn 2011-4-29

命令、数据发送流程如下图:

第 11 页 共 20 页 Create by binmn 2011-4-29

其中, 黑色粗线部分为命令发送或者数据发送都要经过的流程, 橙色方框部分判断所有类型的请 求是否完成。

4 MMC/SD 卡设备驱动程序分析
在 SD linux-2.6.38.2\drivers\mmc 驱动代码中包含 card、 core 和 host 三部分, card (区块层) 与 core(核心层)是 linux 系统封装好了部分,我们不需要修改,host(主控 制器层) 中提供与各芯片构架相关的文件, 我们使用的是 S3C6410, 所以 S3cmci.h S3cmci.c 才是 SD 驱动开发移植的重点 4.1 host 数据结构体
linux-2.6.38.2\drivers\mmc\host\ S3cmci.h 定义了 struct s3cmci_host,用于存储与 芯片类型 SD 的所有数据信息。
struct s3cmci_host { struct platform_device *pdev; struct s3c24xx_mci_pdata *pdata; struct mmc_host struct resource struct clk void __iomem int int int unsigned long irq; irq_cd; dma; clk_rate; 第 12 页 共 20 页 Create by binmn 2011-4-29 *mmc; *mem; *clk; *base;

unsigned long unsigned long u8 int unsigned unsigned int int bool bool bool int

clk_div; real_rate; prescaler; is2440; sdiimsk; sdidata; dodma; dmatogo; irq_disabled; irq_enabled; irq_state; sdio_irqen;

struct mmc_request *mrq; int spinlock_t cmd_is_stop; complete_lock; complete_what;

enum s3cmci_waitfor int u32 u32 u32 u32

dma_complete; pio_sgptr; pio_bytes; pio_count; *pio_ptr;

#define XFER_NONE 0 #define XFER_READ 1 #define XFER_WRITE 2 u32 int char char char unsigned int pio_active; bus_width; dbgmsg_cmd[301]; dbgmsg_dat[301]; *status; ccnt, dcnt; pio_tasklet;

struct tasklet_struct #ifdef CONFIG_DEBUG_FS struct dentry struct dentry

*debug_root; *debug_state; 第 13 页 共 20 页 Create by binmn 2011-4-29

struct dentry #endif #ifdef CONFIG_CPU_FREQ

*debug_regs;

struct notifier_block #endif };

freq_transition;

其中 struct mmc_host (linux-2.6.38.2\include\linux\mmc\Host.h) 用于与 core 层的命令请求,数据
传输等信息。 struct mmc_host { struct device struct device int unsigned int unsigned int unsigned int u32 u32 u32 u32 *parent; class_dev; index; f_min; f_max; f_init; ocr_avail; ocr_avail_sdio; ocr_avail_mmc; /* SDIO-specific OCR */ /* MMC-specific OCR */ ocr_avail_sd; /* SD-specific OCR */ pm_notify; 0x00000080 0x00000100 0x00000200 0x00000400 0x00000800 0x00001000 0x00002000 0x00004000 0x00008000 0x00010000 0x00020000 0x00040000 0x00080000 0x00100000 0x00200000 0x00400000 0x00800000 caps; /* VDD voltage 1.65 - 1.95 */ /* VDD voltage 2.0 ~ 2.1 */ /* VDD voltage 2.1 ~ 2.2 */ /* VDD voltage 2.2 ~ 2.3 */ /* VDD voltage 2.3 ~ 2.4 */ /* VDD voltage 2.4 ~ 2.5 */ /* VDD voltage 2.5 ~ 2.6 */ /* VDD voltage 2.6 ~ 2.7 */ /* VDD voltage 2.7 ~ 2.8 */ /* VDD voltage 2.8 ~ 2.9 */ /* VDD voltage 2.9 ~ 3.0 */ /* VDD voltage 3.0 ~ 3.1 */ /* VDD voltage 3.1 ~ 3.2 */ /* VDD voltage 3.2 ~ 3.3 */ /* VDD voltage 3.3 ~ 3.4 */ /* VDD voltage 3.4 ~ 3.5 */ /* VDD voltage 3.5 ~ 3.6 */

const struct mmc_host_ops *ops;

struct notifier_block #define MMC_VDD_165_195 #define MMC_VDD_20_21 #define MMC_VDD_21_22 #define MMC_VDD_22_23 #define MMC_VDD_23_24 #define MMC_VDD_24_25 #define MMC_VDD_25_26 #define MMC_VDD_26_27 #define MMC_VDD_27_28 #define MMC_VDD_28_29 #define MMC_VDD_29_30 #define MMC_VDD_30_31 #define MMC_VDD_31_32 #define MMC_VDD_32_33 #define MMC_VDD_33_34 #define MMC_VDD_34_35 #define MMC_VDD_35_36 unsigned long

/* Host capabilities */

#define MMC_CAP_4_BIT_DATA (1 << 0) /* Can the host do 4 bit transfers */ 第 14 页 共 20 页 Create by binmn 2011-4-29

#define MMC_CAP_MMC_HIGHSPEED #define MMC_CAP_SD_HIGHSPEED #define MMC_CAP_SDIO_IRQ #define MMC_CAP_SPI

(1 << 1) /* Can do MMC high-speed timing */ (1 << 2) /* Can do SD high-speed timing */

(1 << 3) /* Can signal pending SDIO IRQs */ (1 << 4) /* Talks only SPI protocols */

#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */ #define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */ #define MMC_CAP_DISABLE (1 << 7) /* Can the host be disabled */ (1 << 8) /* Nonremovable e.g. eMMC */ #define MMC_CAP_NONREMOVABLE #define MMC_CAP_ERASE #define MMC_CAP_1_8V_DDR /* DDR mode at 1.8V */ #define MMC_CAP_1_2V_DDR /* DDR mode at 1.2V */ #define MMC_CAP_POWER_OFF_CARD #define MMC_CAP_BUS_WIDTH_TEST mmc_pm_flag_t (1 << 13) /* Can power off after boot */ (1 << 14) /* CMD14/CMD19 bus width ok */ (1 << 12) /* can support */

#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */ (1 << 10) /* Allow erase/trim commands */ (1 << 11) /* can support */

pm_caps; /* supported pm features */

#ifdef CONFIG_MMC_CLKGATE int unsigned int bool unsigned int spinlock_t struct mutex #endif /* host specific block data */ unsigned int unsigned short unsigned short unsigned int unsigned int unsigned int /* private data */ spinlock_t struct mmc_ios u32 ocr; lock; ios; /* lock for claim and bus ops */ /* current io bus settings */ max_seg_size; /* see blk_queue_max_segment_size */ max_segs; /* see blk_queue_max_segments */ unused; max_req_size; /* maximum number of bytes in one req */ max_blk_size; /* maximum size of one mmc block */ max_blk_count; /* maximum number of blocks in one req */ clk_requests; /* internal reference counter */ clk_delay; clk_gated; /* number of MCI clk hold cycles */ /* clock gated */

struct work_struct clk_gate_work; /* delayed clock gate */ clk_old; /* old clock value cache */ clk_lock; /* lock for clk fields */ clk_gate_mutex; /* mutex for clock gating */

/* the current OCR setting */

/* group bitfields together to minimize padding */ 第 15 页 共 20 页 Create by binmn 2011-4-29

unsigned int unsigned int unsigned int #ifdef CONFIG_MMC_DEBUG unsigned int #endif

use_spi_crc:1; claimed:1; bus_dead:1; removed:1; /* host exclusively claimed */ /* bus has been released */ /* host is being removed */

/* Only used with MMC_CAP_DISABLE */ int int int int unsigned int enabled; /* host is enabled */ rescan_disable; en_dis_recurs; /* disable card detection */ /* detect recursion */ /* disable delay in msecs */ nesting_cnt; /* "enable" nesting count */ disable_delay;

struct delayed_work struct mmc_card wait_queue_head_t wq;

disable; /* disabling work */ *card; /* device attached to this host */

struct task_struct *claimer; /* task that has host claimed */ int claim_cnt; /* "claim" nesting count */

struct delayed_work

detect; /* current bus driver */

const struct mmc_bus_ops *bus_ops; unsigned int unsigned int atomic_t mmc_pm_flag_t

bus_refs; /* reference counter */ sdio_irqs; sdio_irq_thread_abort; pm_flags; /* requested pm features */

struct task_struct *sdio_irq_thread;

#ifdef CONFIG_LEDS_TRIGGERS struct led_trigger *led; #endif #ifdef CONFIG_REGULATOR bool #endif struct dentry unsigned long }; 第 16 页 共 20 页 Create by binmn 2011-4-29 *debugfs_root; private[0] ____cacheline_aligned; regulator_enabled; /* regulator state */ /* activity led */

其中 struct s3c24xx_mci_pdata 用于型号引脚检测的信息。
struct s3c24xx_mci_pdata { unsigned int no_wprotect : 1; unsigned int no_detect : 1; unsigned int wprotect_invert : 1; unsigned int detect_invert : 1; unsigned int use_dma : 1; unsigned int gpio_detect; unsigned int gpio_wprotect; unsigned long ocr_avail; void }; (*set_power)(unsigned char power_mode, unsigned short vdd); /* set => detect active high. */

4.2 host 驱动函数 4.2.1 驱动注册,注销函数
static int __init s3cmci_init(void) { return platform_driver_register(&s3cmci_driver); } static void __exit s3cmci_exit(void) { platform_driver_unregister(&s3cmci_driver); } module_init(s3cmci_init); module_exit(s3cmci_exit);

SD 是以平台设备注册到系统中,因此要使用以下函数注册
extern int platform_driver_register(struct platform_driver *); extern void platform_driver_unregister(struct platform_driver *);

在文件 linux-2.6.38.2\include\linux\Platform_device.h 可以找到 4.2.2 platform_driver 接口函数
static struct platform_driver s3cmci_driver = { .driver = { = "s3c-sdi", = THIS_MODULE, .name .owner }, .id_table = s3cmci_driver_ids, .probe = s3cmci_probe, 第 17 页 共 20 页 Create by binmn 2011-4-29

.pm = s3cmci_pm_ops,

.remove };

= __devexit_p(s3cmci_remove),

.shutdown = s3cmci_shutdown,

设备的接口结构体定义在 Platform_device.h 中
struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*resume)(struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; };

4.2.3 探针函数 在驱动的接口函数中 s3cmci_probe() 函数,用于分配 mmc_host ,s3cmci_host 结构体, 并对结构体进行设置,在 SDI 主机控制器操作接口函数 mmc_host_ops 中会调用 s3cmci_host 结构体,申请中断并设置中断服务函数,将结构体 mmc_host 添加到主机。部分代码如下:
static int __devinit s3cmci_probe(struct platform_device *pdev) { struct s3cmci_host *host; struct mmc_host int ret; int is2440; int i; is2440 = platform_get_device_id(pdev)->driver_data; mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev); if (!mmc) { ret = -ENOMEM; goto probe_out; } for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) { ret = gpio_request(i, dev_name(&pdev->dev)); if (ret) { dev_err(&pdev->dev, "failed to get gpio %d\n", i); for (i--; i >= S3C2410_GPE(5); i--) gpio_free(i); goto probe_free_host; } } 第 18 页 共 20 页 Create by binmn 2011-4-29 *mmc;

host = mmc_priv(mmc); host->mmc host->pdev …… } = mmc; = pdev;

host->is2440 = is2440;

其中函数 mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);定义在 linux-2.6.38.2\drivers\mmc\core\Host.c 中 , 从 中 可 以 看 出 分 配 的 空 间 为 ( mmc_host + s3cmci_host) ,部分代码如下:
struct mmc_host *mmc_alloc_host(int extra, struct device *dev) { int err; struct mmc_host *host; if (!idr_pre_get(&mmc_host_idr, GFP_KERNEL)) return NULL; host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); if (!host) return NULL; spin_lock(&mmc_host_lock); .... }

4.3 mmc 接口操作 4.3.1 mmc_host_ops 接口函数结构
static struct mmc_host_ops s3cmci_ops = { .request = s3cmci_request, .set_ios = s3cmci_set_ios, .get_ro .get_cd }; 结 构体 mmc_host_ops 定义了对 host 主机进行操作的各种方法 , 其定义在 Core 核心层的 linux-2.6.38.2\include\linux\mmc\Host.h 中, 也就是 Core 核心层对 Host 主机层提供的接口函数 struct mmc_host_ops { int (*enable)(struct mmc_host *host); int (*disable)(struct mmc_host *host, int lazy); void (*request)(struct mmc_host *host, struct mmc_request *req);//实现host的请求处理(即: 命令和数据的发送和接收) void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);//通过核心层传递过来的ios, 配置host寄存器(使能时钟、总线带宽等) 第 19 页 共 20 页 Create by binmn 2011-4-29 = s3cmci_get_ro, = s3cmci_card_present,

.enable_sdio_irq = s3cmci_enable_sdio_irq,

int (*get_ro)(struct mmc_host *host);//通过读取GPIO端口来判断卡是否写有保护 int (*get_cd)(struct mmc_host *host);//通过读取GPIO端口来判断卡是否存在 void (*enable_sdio_irq)(struct mmc_host *host, int enable); /* optional callback for HC quirks */ void (*init_card)(struct mmc_host *host, struct mmc_card *card); };

从各函数原型上看,他们都将 mmc_host 结构体作为参数,所以 mmc_host 结构体是 MMC/SD 卡驱 动中比较重要的数据结构。可以这样说,他是 Core 层与 Host 层进行数据交换的载体。 4.3.2 其他接口函数

Mmc 的接口函数具体查看源文件代码,在《嵌入式 Linux 之我行——S3C2440 上 MMC/SD 卡驱动实例开发讲解(二) 》http://hbhuanggang.cublog.cn 一文有对这些函数的注释,可以 参考。以下是对这几个函数的部分代码说明,如 s3cmci_card_present 中
static int s3cmci_card_present(struct mmc_host *mmc) { struct s3cmci_host *host = mmc_priv(mmc); struct s3c24xx_mci_pdata *pdata = host->pdata; int ret; if (pdata->no_detect) return -ENOSYS; ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1; return ret ^ pdata->detect_invert; } mmc_priv 的原型为 static inline void *mmc_priv(struct mmc_host *host) { return (void *)host->private; } 所以是将 mmc_host *mmc->private 传递给 s3cmci_host *host,看起来似乎结构体指针并不匹配, 事实上在 mmc_host 结构体最后定义了一个零长度的数组 private,在探针函数 mmc_alloc_host()分配的

空间为(mmc_host + s3cmci_host)
struct mmc_host { ...... struct dentry unsigned long }; 而零长度数组的意义就是:在系统分配空间是并不分配 private 的空间,即计算 sizeof(mmc_host)时不包 括 private 的长度;而在使用时,他是指向紧接着 mmc_host 后面分配的数据结构的首地址 第 20 页 共 20 页 Create by binmn 2011-4-29 *debugfs_root; private[0] ____cacheline_aligned;

从这样看来 s3cmci_host *host 指针还是指向 s3cmci_host 结构数据的。

4.4 SD 卡移植方法 与其他模块一样,使用命令 make menuconfig 进入窗口配置界面
选择 CPU 类型 ——> ARM 中的 samsung 6410 在 设备驱动中 ——> MMC/SD card support 的各选项 编译下载到硬件是测试驱动。

第 21 页 共 20 页 Create by binmn 2011-4-29


相关文章:
嵌入式Linux工程师常见笔试题
嵌入式Linux工程师常见笔试题_IT/计算机_专业资料。...表现 出对问题的真正的好奇心, 把这看成学习的...的驱动程序, 它用到了 bit fields 因此完全对我无...
作为一个新人,怎样学习嵌入式Linux?
(就那么几条汇编指 在学习嵌入式 Linux 之前, 令...3. 做驱动,其实我不想称为“做驱动”,而是想称...选读<Linux 内核情景分析>, 相了解哪一块就读哪一...
嵌入式模块驱动实验报告
驱动开发实践,理解嵌入式 linux 系统中驱动程序开发 的模块设计方法,为进一步学习...对于这次实验本身, 我主要了解了 Makefile 文件代码的含义和编写 Makefile 文件时...
嵌入式Linux系统学习步骤
嵌入式Linux系统学习步骤_信息与通信_工程科技_专业资料。嵌入式Linux系统学习步骤1. 嵌入式软件开发应用领域 嵌入式系统是当前最热门、最具发展前途的 IT 应用领域...
linux sd卡驱动分析
驱动工作原理 我在讲嵌入式 Linux 驱动开发班的时候...所以就想写一下这方面的内容,希望对大家的 学习能...想了解 SD 卡的工作原理,首先需要了解的就是 SD ...
edu_ecologychuanke128275
驱动开发是嵌入式Linux 开发难度最高的内容,也是目前嵌入式行业最紧缺的人才之一。华清创客学院独家推出嵌入式Linux内核及驱动开发课程,从最简单的内核模块开始,逐步...
学习嵌入式linux的某位大虾的经历,很有用
1、学习 linux 根据我在论坛的了解,我选择学习嵌入式 linux,刚好我们学 校也重视嵌入式 linux, 从实验室到课程安排都是关于嵌入式 linux 方面,天时地利!这里我...
嵌入式心得体会
嵌入式心得体会_学习总结_总结/汇报_实用文档。这...通过网上了解,我查询了嵌入式的入门和所需要的知识,...还有应该学习linux 或者 wince 下的编程,这些对...
第4章 嵌入式Linux的构建(2010-12-7)
基于嵌入式LinuxSD卡驱动... 54页 8财富值 第...Linux 的构建 本章将学习如何进行嵌入式 Linux 的...通过本章,读者将了解以下内容: ● 嵌入式 ...
嵌入式Linux之我行——S3C2440上Flash驱动实例开发讲解(to_be_continue)
嵌入式 Linux 之我行,主要讲述和总结了本人在学习嵌入式 linux 中的每个步骤。...嵌入式Linux系统下NORFl... 3页 免费 S3C2440上SD卡驱动实例开... 28页 1...
更多相关标签: