### Linux SD卡驱动分析
#### 块请求处理(linux/driver/mmc/card)
Linux环境下的SD卡驱动设计遵循了一套清晰的分层结构。在`linux/driver/mmc/card`目录下,主要关注的是块请求处理的部分。这部分是SD卡驱动与Linux块设备层之间的重要接口。
##### 1. Probe函数
Probe函数是设备驱动加载时执行的第一个函数,它负责检测并初始化硬件设备。在SD卡驱动中,`mmc_blk_init`函数作为探针函数的核心,实现了SD卡块设备的注册和初始化。
```c
static int __init mmc_blk_init(void) {
int res;
res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
if (res)
goto out;
res = mmc_register_driver(&mmc_driver);
if (res)
goto out2;
return 0;
out2:
unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
out:
return res;
}
```
通过`register_blkdev`函数注册块设备,并且为SD卡分配主设备号。之后通过`mmc_register_driver`函数将SD卡驱动注册到mmc核心层。
##### 2. do_request函数
`do_request`函数用于处理来自上层(如文件系统)的块I/O请求。该函数通常会根据请求类型(读或写)选择合适的处理路径,并最终调用底层硬件的操作函数。这部分代码在实际SD卡驱动实现中非常重要,因为它直接影响到I/O性能。
```c
void mmc_do_request(struct request *req) {
// 这里省略部分代码
// 实现对SD卡的读写操作
}
```
#### core层处理(linux/driver/mmc/core)
在`linux/driver/mmc/core`目录下,主要关注的是核心层处理,这部分代码处理SD卡与主机之间的通信协议。核心层提供了与底层硬件交互的接口,并管理SD卡的状态。
##### 1. Core层初始化
在核心层初始化阶段,会创建一个总线类型的实例,并注册各种必要的属性和回调函数。这些回调函数包括匹配、UEVENT事件处理和探针函数等。
```c
static struct bus_type mmc_bus_type = {
.name = "mmc",
.dev_attrs = mmc_dev_attrs,
.match = mmc_bus_match,
.uevent = mmc_bus_uevent,
.probe = mmc_bus_probe,
};
```
##### 2. mmc_claim_host & mmc_release_host
`mmc_claim_host`和`mmc_release_host`函数用于管理SD卡主机控制器资源的锁定与释放。它们确保在同一时刻只有一个驱动程序能够访问特定的SD卡主机控制器。
```c
int mmc_claim_host(struct mmc_host *host) {
// 获取锁,独占SD卡主机控制器资源
}
void mmc_release_host(struct mmc_host *host) {
// 释放锁,允许其他驱动程序访问SD卡主机控制器
}
```
##### 3. mmc_wait_for_req & mmc_wait_for_cmd
`mmc_wait_for_req`和`mmc_wait_for_cmd`函数用于等待SD卡操作完成。这些函数确保驱动程序可以同步地等待命令执行完毕或者等待数据传输结束。
```c
int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) {
// 等待SD卡操作完成
}
int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd) {
// 等待SD卡命令执行完成
}
```
#### SD控制器初始化(linux/driver/mmc/host)
在`linux/driver/mmc/host`目录下,关注的是SD控制器的初始化和硬件操作。
##### 1. s3cmci_get_ro
`get_ro`函数用于获取SD卡的只读状态。
```c
int s3cmci_get_ro(struct mmc_host *host) {
// 获取SD卡的只读状态
}
```
##### 2. s3cmci_set_ios
`s3cmci_set_ios`函数用于设置SD卡的工作模式和其他I/O参数。
```c
int s3cmci_set_ios(struct mmc_host *host, struct mmc_ios *ios) {
// 设置SD卡的工作模式
}
```
##### 3. s3cmci_request
`s3cmci_request`函数是SD卡控制器处理读写请求的核心函数。它包含两个主要部分:命令处理和数据传输。
- **命令处理**:通过发送特定的命令来控制SD卡的行为,例如读取SD卡的状态。
- **数据传输**:负责实际的数据读写操作。
```c
int s3cmci_request(struct mmc_host *host, struct mmc_request *mrq) {
// 处理SD卡读写请求
}
```
#### 小结
Linux中的SD卡驱动设计采用了一种清晰的分层架构,从高层的块设备层到中间的核心层,再到底层的控制器层,每一层都有其明确的功能和职责。这种设计不仅使得驱动程序易于理解,还提高了整体系统的可扩展性和可维护性。通过本文的介绍,我们可以了解到SD卡驱动的关键组件及其工作原理。