当前位置:首页>Linux>深度解析Linux MMC子系统

深度解析Linux MMC子系统

  • 2026-07-03 10:06:14
深度解析Linux MMC子系统

一、前言

1.1 业务场景

MMC(MultiMedia Card)和 SD(Secure Digital)卡是嵌入式系统中最常用的存储介质之一,广泛应用于:

  • 消费电子:手机、平板、相机、游戏机
  • 工业控制:PLC、嵌入式终端、数据采集器
  • 物联网设备:路由器、网关、智能传感器
  • 车载系统:行车记录仪、车载娱乐系统

这些设备都需要高性能、高可靠性的存储方案,而 MMC/SD 卡驱动就是连接硬件和文件系统的桥梁。

1.2 应用价值

  • 数据存储:为用户提供可扩展的存储空间
  • 系统启动:许多嵌入式设备从 SD 卡启动
  • 固件升级:通过 SD 卡更新系统固件
  • 日志记录:保存系统运行日志和调试信息

1.3 驱动作用

MMC/SD 驱动在内核中的作用:

  1. 硬件抽象:将复杂的 MMC 协议简化为标准块设备接口
  2. 请求调度:通过 blk-mq 优化 I/O 请求的处理顺序
  3. 错误处理:自动重试、错误恢复、坏块管理
  4. 电源管理:支持动态电压调整、休眠唤醒

二、技术原理

2.1 MMC 子系统整体架构

MMC 子系统采用分层设计,从上到下分为:

2.2 核心层次详解

层次一:MMC 核心层(core/)

MMC 核心层是整个子系统的中枢,负责:

功能模块
职责说明
卡管理
卡的检测、识别、初始化和移除
命令处理
命令发送、响应解析、错误处理
数据传输
块读写、DMA 管理、请求调度
块设备接口
与通用块层交互,提供标准块设备接口
SDIO 支持
SDIO 设备枚举、函数管理、中断处理
电源管理
电压切换、时钟控制、省电模式

核心文件详解:

文件
主要功能
关键函数
core/core.c
核心初始化、命令发送、卡状态管理
mmc_start_request()
mmc_wait_for_req()
core/bus.c
设备总线管理、驱动匹配、设备枚举
mmc_bus_probe()
mmc_bus_remove()
core/sd.c
SD 卡特定逻辑、ACMD 命令、SDIO 检测
mmc_sd_init_card()
mmc_sd_setup_card()
core/mmc.c
MMC/eMMC 卡特定逻辑
mmc_init_card()
mmc_setup_card()
core/block.c
块设备接口、请求队列管理
mmc_blk_issue_rq()
mmc_blk_complete_rq()
core/sdio.c
SDIO 功能支持
sdio_init_func()
sdio_read_bytes()
core/host.c
主机控制器注册、注销、配置
mmc_alloc_host()
mmc_add_host()
core/pwrseq.c
电源序列管理
mmc_pwrseq_power_on()
mmc_pwrseq_power_off()

层次二:主机驱动层(host/)

主机驱动层负责与具体的 MMC 控制器硬件交互。不同芯片厂商的控制器差异较大,但都遵循相同的核心接口。

主要主机驱动:

驱动文件
适用控制器
特点
dw_mmc.c
DesignWare MMC Controller
通用驱动,支持多种平台
dw_mmc-pltfm.c
DesignWare 平台驱动
平台设备绑定
dw_mmc-rockchip.c
瑞芯微平台特定
瑞芯微 RK 系列优化
sdhci.c
SD Host Controller Interface
标准 SDHCI 控制器
sdhci-pltfm.c
SDHCI 平台驱动
平台设备绑定
renesas_sdhi_internal_dmac.c
瑞萨 SDHI
瑞萨特定实现
mxc_mmc.c
飞思卡尔 MMC
i.MX 系列

层次三:SDIO 层(sdio/)

SDIO(Secure Digital Input Output)层支持 SDIO 设备(如 WiFi 模块、蓝牙模块等):

  • SDIO 总线枚举:发现总线上的 SDIO 设备
  • SDIO 函数驱动:为每个 SDIO 函数提供驱动支持
  • 中断处理:处理 SDIO 设备产生的中断

2.3 MMC 协议基础

2.3.1 MMC/SD 命令类型

MMC/SD 卡使用命令-响应协议进行通信:

命令类型
范围
说明
BC
CMD0-127
广播命令(无响应)
BCR
CMD0-127
广播命令(带响应)
AC
CMD0-127
寻址命令(无响应)
ACR
CMD0-127
寻址命令(带响应)
ADTC
CMD128-255
带数据的寻址命令

2.3.2 常用命令

命令
名称
用途
CMD0
GO_IDLE_STATE
复位卡到空闲状态
CMD1
SEND_OP_COND
发送操作条件
CMD2
ALL_SEND_CID
请求卡 ID
CMD3
SEND_REL_ADDR
设置相对卡地址
CMD6
SWITCH_FUNC
切换功能
CMD7
SELECT/DESELECT_CARD
选择/取消选择卡
CMD8
SEND_EXT_CSD
发送扩展 CSD
CMD9
SEND_CSD
请求卡特定数据
CMD10
SEND_CID
请求卡 ID
CMD12
STOP_TRANSMISSION
停止数据传输
CMD13
SEND_STATUS
请求卡状态
CMD16
SET_BLOCKLEN
设置块长度
CMD17
READ_SINGLE_BLOCK
读单个块
CMD18
READ_MULTIPLE_BLOCK
读多个块
CMD24
WRITE_BLOCK
写单个块
CMD25
WRITE_MULTIPLE_BLOCK
写多个块

2.3.3 SD 卡特有命令(ACMD)

SD 卡有一些特殊的应用命令(Application-Specific Commands),需要先发送 CMD55 才能发送:

ACMD
名称
用途
ACMD41
SD_SEND_OP_COND
SD 卡操作条件
ACMD51
SEND_SCR
发送 SD 配置寄存器
ACMD6
SET_BUS_WIDTH
设置总线宽度

2.4 核心数据结构详解

2.4.1 struct mmc_host - 主机控制器描述

structmmc_host {structdevice       *parent;// 父设备(平台设备)structdeviceclass_dev;// 类设备,用于用户空间访问conststructmmc_host_ops *ops;// 主机操作函数指针集structmmc_iosios;// 当前 I/O 设置(时钟、电压、总线宽度)    u32         f_min;                  // 最小时钟频率(Hz)    u32         f_max;                  // 最大时钟频率(Hz)    u32         f_init;                 // 初始化时钟频率(通常 400kHz)unsignedlong   caps;               // 主机能力标志(支持的功能)unsignedlong   caps2;              // 扩展能力标志structmmc_card *card;// 当前连接的卡(最多一张)structrequest_queue *queue;// 块设备请求队列structgendisk  *disk;// 块设备描述符structmmc_host_statsstats;// 统计信息structwork_structdetect;// 卡检测工作队列structdelayed_workrw_timeout_work;// 读写超时工作/* 私有数据指针,主机驱动可以存储自己的数据 */void *private;/* 电源管理相关 */structmmc_pwrseq *pwrseq;// 电源序列unsignedint power_mode;             // 当前电源模式/* 队列相关 */structmmc_queue *mq;// MMC 请求队列spinlock_t    queue_lock;           // 队列锁/* 中断相关 */int         irq;                    // 中断号structtasklet_structcomplete;// 完成 tasklet    ...};

关键字段详解:

字段
说明
ops
指向主机驱动实现的操作函数,如 request、set_ios 等
ios
当前的 I/O 设置,包括时钟频率、电压级别、总线宽度、电源模式
caps
能力标志,如 MMC_CAP_4_BIT_DATA(支持4位总线)、MMC_CAP_SD_HIGHSPEED(支持高速模式)等
card
当前连接的卡,如果没有卡则为 NULL
queue
请求队列,用于接收来自块层的 I/O 请求
mq
MMC 专用的请求队列,管理 mmc_request

2.4.2 struct mmc_ios - I/O 设置

structmmc_ios {unsignedint    clock;              // 当前时钟频率(Hz)unsigned short  vdd;                // 电压级别(见 MMC_VDD_* 定义)unsignedchar   bus_mode;           // 总线模式(开漏/推挽)unsignedchar   chip_select;        // 片选信号unsignedchar   power_mode;         // 电源模式(关/低功耗/正常)unsignedchar   bus_width;          // 总线宽度(1/4/8位)unsignedchar   timing;             // 时序模式(legacy/high-speed等)unsignedchar   signal_voltage;     // 信号电压(1.8V/3.3V)unsignedchar   drv_type;           // 驱动类型(A/B/C/D)};

2.4.3 struct mmc_card - 卡描述

structmmc_card {structmmc_host   *host;// 所属主机控制器structdevicedev;// 设备对象unsignedint      rca;              // 相对卡地址(卡识别后分配)unsignedint      type;             // 卡类型(MMC/SD/SDIO/组合卡)structmmc_cidcid;// 卡唯一标识(Card ID)structmmc_csdcsd;// 卡特定数据(Card Specific Data)structmmc_scrscr;// SD 卡配置寄存器(SD Configuration Register)structmmc_ext_csdext_csd;// 扩展 CSD(eMMC 专用)unsignedlong    state;             // 卡状态标志unsignedint    flags;              // 卡特性标志structmmc_card_data *data;// 私有数据/* 分区信息 */unsignedint      nr_erase_groups;  // 擦除组数量unsignedint      erase_group_size; // 擦除组大小/* 速度信息 */unsignedint      max_dtr;          // 最大数据传输速率unsignedint      actual_dtr;       // 当前数据传输速率/* 块设备信息 */unsignedint      block_bits;       // 块大小的位数(如 9 表示 512 字节)sector_t         capacity;          // 总容量(扇区数)    ...};

卡类型常量:

常量
说明
MMC_TYPE_MMC
0
MMC 卡
MMC_TYPE_SD
1
SD 卡
MMC_TYPE_SDIO
2
SDIO 卡
MMC_TYPE_SD_COMBO
3
SD 组合卡(同时支持 SD 和 SDIO)

2.4.4 struct mmc_request - 请求描述

structmmc_request {structmmc_command *cmd;// 命令描述符structmmc_command *stop;// 停止命令(用于多块传输)structmmc_data   *data;// 数据描述符structmmc_host  *host;// 目标主机structmmc_card  *card;// 目标卡void (*done)(struct mmc_request *); // 请求完成回调函数unsignedint      retries;          // 重试次数unsignedint      error;            // 错误码/* 统计信息 */unsignedlong    start_time;        // 请求开始时间unsignedint      nr_sectors;       // 扇区数unsignedint      bytes_xfered;     // 已传输字节数    ...};

2.4.5 struct mmc_command - 命令描述

structmmc_command {    u32         opcode;                 // 命令操作码(CMDx)    u32         arg;                    // 命令参数structmmc_data   *data;// 关联的数据传输structmmc_request *mrq;// 所属请求unsignedint      flags;             // 命令标志/* 响应 */    u32         resp[4];               // 响应数据(最多4个32位字)int         error;                  // 错误码/* 状态 */unsignedint      retries;          // 重试次数unsignedint      busy_timeout;      // 忙等待超时时间    ...};

命令标志:

标志
说明
MMC_RSP_NONE
无响应
MMC_RSP_R1
R1 类型响应
MMC_RSP_R1B
R1B 类型响应(带忙信号)
MMC_RSP_R2
R2 类型响应(CID/CSD)
MMC_RSP_R3
R3 类型响应(OCR)
MMC_RSP_R4
R4 类型响应(SDIO)
MMC_RSP_R5
R5 类型响应(SDIO)
MMC_RSP_R6
R6 类型响应(RCA)
MMC_RSP_R7
R7 类型响应(接口条件)
MMC_CMD_ADTC
带数据的命令

2.4.6 struct mmc_data - 数据描述

structmmc_data {unsignedint      timeout_ns;       // 超时时间(纳秒)unsignedint      blksz;            // 块大小(字节)unsignedint      blocks;           // 块数量unsignedint      flags;             // 数据标志(读/写等)structscatterlist *sg;// 分散/聚集列表unsignedint      sg_len;           // SG 元素数量structmmc_request *mrq;// 所属请求/* 状态 */int         error;                  // 错误码unsignedint      bytes_xfered;     // 已传输字节数/* DMA 相关 */dma_addr_t       dma_addr;          // DMA 地址unsignedint      dma_len;          // DMA 长度    ...};

数据标志:

标志
说明
MMC_DATA_READ
读操作
MMC_DATA_WRITE
写操作
MMC_DATA_STREAM
流式传输
MMC_DATA_MULTI
多块传输

2.4.7 数据结构关系图

2.5 MMC 请求处理流程详解

2.6 卡识别与初始化流程

卡的识别和初始化是一个复杂的过程,包含多个阶段:

初始化阶段详解:

阶段
命令
目的
1. 复位
CMD0
将卡置于空闲状态
2. 电压检测
CMD8
检查卡支持的电压范围
3. 操作条件
CMD1/ACMD41
发送操作条件,等待卡就绪
4. 获取CID
CMD2
获取卡唯一标识
5. 获取RCA
CMD3
获取相对卡地址
6. 获取CSD
CMD9
获取卡特定数据(容量等)
7. 选择卡
CMD7
选中卡进行后续操作
8. 获取EXT_CSD
CMD8
eMMC 卡获取扩展信息
9. 配置
ACMD6/ACMD51
设置总线宽度、获取配置

2.7 关键 API 详解

2.7.1 主机控制器管理

API
功能
详细说明
mmc_alloc_host(size, parent)
分配主机控制器
分配 mmc_host 结构体及私有数据空间
mmc_add_host(host)
注册主机控制器
将主机添加到系统,创建设备节点
mmc_remove_host(host)
注销主机控制器
从系统移除主机,清理资源
mmc_free_host(host)
释放主机控制器
释放分配的内存
mmc_of_parse(host)
解析设备树
从设备树获取配置信息

2.7.2 命令和数据传输

API
功能
详细说明
mmc_wait_for_req(host, mrq)
同步发送请求
发送请求并等待完成
mmc_start_request(host, mrq)
异步发送请求
发送请求,通过回调通知完成
mmc_send_cmd(host, cmd, timeout)
发送单个命令
发送命令并等待响应
mmc_read_blocks(card, buf, blk, cnt)
读块
读取指定数量的块
mmc_write_blocks(card, buf, blk, cnt)
写块
写入指定数量的块

2.7.3 卡管理

API
功能
详细说明
mmc_attach(host)
识别并初始化卡
执行卡识别流程
mmc_detach(host)
移除卡
清理卡相关资源
mmc_rescan(host)
重新扫描卡
检测卡插拔状态
mmc_sd_init_card(host)
初始化 SD 卡
SD 卡特定初始化
mmc_init_card(host)
初始化 MMC 卡
MMC 卡特定初始化

2.7.4 电源和时钟管理

API
功能
详细说明
mmc_set_ios(host)
设置 I/O 参数
配置时钟、电压、总线宽度
mmc_set_clock(host, freq)
设置时钟频率
动态调整时钟
mmc_bus_reset(host)
总线复位
复位 MMC 总线
mmc_power_up(host)
上电
为卡供电
mmc_power_off(host)
断电
关闭卡电源

三、core 层核心代码详解

3.1 core/core.c - 核心功能实现

3.1.1 命令发送流程

intmmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq){int ret;    mrq->done = mmc_wait_done;  // 设置完成回调/* 发送请求 */    mmc_start_request(host, mrq);/* 等待完成(可中断) */    wait_event_interruptible(host->wq, mrq->completed);    ret = mrq->error;return ret;}staticvoidmmc_start_request(struct mmc_host *host, struct mmc_request *mrq){structmmc_queue *mq = host->mq;/* 设置请求的主机和卡 */    mrq->host = host;    mrq->card = host->card;/* 调用主机驱动的请求函数 */if (host->ops->request) {        host->ops->request(host, mrq);    }}

3.1.2 卡识别流程

intmmc_attach_mmc(struct mmc_host *host){structmmc_card *card;int err;/* 分配卡结构体 */    card = mmc_alloc_card(host);if (!card)return -ENOMEM;/* 发送CMD0复位 */    err = mmc_send_cmd(host, MMC_CMD_GO_IDLE_STATE, 0, MMC_RSP_NONE);if (err)goto err;/* 发送CMD1直到卡就绪 */for (i = 0; i < MMC_MAX_OP_COND_RETRIES; i++) {        err = mmc_send_cmd(host, MMC_CMD_SEND_OP_COND, ocr, MMC_RSP_R3);if (!(err & MMC_CARD_BUSY))break;        msleep(10);    }/* 获取CID */    err = mmc_send_cmd(host, MMC_CMD_ALL_SEND_CID, 0, MMC_RSP_R2);if (err)goto err;/* 获取RCA */    err = mmc_send_cmd(host, MMC_CMD_SEND_REL_ADDR, 0, MMC_RSP_R6);if (err)goto err;/* 获取CSD */    err = mmc_send_cmd(host, MMC_CMD_SEND_CSD, card->rca << 16, MMC_RSP_R2);if (err)goto err;/* 选择卡 */    err = mmc_send_cmd(host, MMC_CMD_SELECT_CARD, card->rca << 16, MMC_RSP_R1B);if (err)goto err;/* 完成初始化 */    mmc_attach_card(host, card);return0;err:    mmc_free_card(card);return err;}

3.2 core/block.c - 块设备接口

3.2.1 请求处理

staticblk_status_tmmc_blk_issue_rq(struct blk_mq_hw_ctx *hctx,const struct blk_mq_queue_data *bd){structrequest *req = bd->rq;structmmc_queue *mq = hctx->queue->queuedata;structmmc_card *card = mq->card;structmmc_blk_request *brq;/* 分配请求 */    brq = mmc_blk_get_request(mq);if (!brq)return BLK_STS_RESOURCE;/* 设置请求参数 */    brq->mrq.cmd->opcode = rq_data_dir(req) == READ ?        MMC_CMD_READ_MULTIPLE_BLOCK : MMC_CMD_WRITE_MULTIPLE_BLOCK;    brq->mrq.cmd->arg = blk_rq_pos(req) * 512;    brq->mrq.data->blksz = 512;    brq->mrq.data->blocks = blk_rq_sectors(req);    brq->mrq.data->flags = rq_data_dir(req) == READ ?        MMC_DATA_READ : MMC_DATA_WRITE;/* 映射SG列表 */    brq->mrq.data->sg = blk_rq_sg(req);    brq->mrq.data->sg_len = blk_rq_sg_nents(req);/* 发送请求 */    mmc_start_request(card->host, &brq->mrq);return BLK_STS_OK;}

3.2.2 请求完成

voidmmc_blk_complete_rq(struct mmc_request *mrq){structmmc_blk_request *brq = container_of(mrqstructmmc_blk_requestmrq);structrequest *req = brq->req;/* 设置完成状态 */if (mrq->error) {        blk_mq_end_request(req, BLK_STS_IOERR);    } else {        blk_mq_end_request(req, BLK_STS_OK);    }/* 释放请求 */    mmc_blk_put_request(brq);}

3.3 core/host.c - 主机控制器管理

3.3.1 主机分配和注册

struct mmc_host *mmc_alloc_host(int extra, struct device *parent){structmmc_host *host;size_t size;/* 计算所需内存大小 */    size = sizeof(struct mmc_host) + extra;/* 分配并清零内存 */    host = kzalloc(size, GFP_KERNEL);if (!host)returnNULL;/* 初始化设备 */    host->parent = parent;    device_initialize(&host->class_dev);    host->class_dev.parent = parent;/* 初始化工作队列 */    INIT_DELAYED_WORK(&host->detect, mmc_rescan);/* 初始化定时器 */    setup_timer(&host->watchdog_timer, mmc_watchdog_timer, (unsignedlong)host);return host;}intmmc_add_host(struct mmc_host *host){int err;/* 设置默认时钟范围 */if (!host->f_min)        host->f_min = MMC_MIN_FREQ;if (!host->f_max)        host->f_max = MMC_MAX_FREQ;/* 注册类设备 */    err = device_add(&host->class_dev);if (err)return err;/* 启动卡检测 */    schedule_delayed_work(&host->detect, 0);return0;}

3.4 core/bus.c - 总线驱动

3.4.1 设备匹配和探测

staticintmmc_bus_match(struct device *dev, struct device_driver *drv){structmmc_card *card = mmc_dev_to_card(dev);structmmc_driver *drv = to_mmc_driver(drv);/* 检查驱动是否支持此卡类型 */if (drv->id_table) {conststructmmc_device_id *id;for (id = drv->id_table; id->name[0]; id++) {if (!strcmp(id->name, mmc_card_name(card)))return1;        }    }return0;}staticintmmc_bus_probe(struct device *dev){structmmc_card *card = mmc_dev_to_card(dev);structmmc_driver *drv = to_mmc_driver(dev->driver);if (drv->probe)return drv->probe(card);return0;}staticstructbus_typemmc_bus_type = {    .name       = "mmc",    .match      = mmc_bus_match,    .probe      = mmc_bus_probe,    .remove     = mmc_bus_remove,};

四、主机驱动开发详解

4.1 DesignWare MMC 控制器驱动

DesignWare MMC 控制器是一种通用的 MMC/SD/SDIO 控制器,被许多芯片厂商使用。

4.1.1 驱动结构

structdw_mci {structmmc_host   *mmc;// MMC 主机structdevice     *dev;// 设备void __iomem     *regs;          // 寄存器基地址int              irq;            // 中断号/* 时钟 */structclk       *ciu_clk;// 控制器时钟structclk       *biu_clk;// 总线接口时钟structclk       *sample_clk;// 采样时钟/* DMA */structdma_chan  *dma_rx;// 接收 DMA 通道structdma_chan  *dma_tx;// 发送 DMA 通道/* 请求处理 */structmmc_request *mrq;// 当前请求structmmc_request *pending_mrq;// 挂起请求/* 状态 */unsignedint     cur_slot;        // 当前槽位bool            pending;          // 是否有挂起请求/* 锁 */spinlock_t       lock;            // 自旋锁/* 私有数据 */conststructdw_mci_drv_data *drv_data;};

4.1.2 平台驱动注册

staticconststructof_device_iddw_mci_rockchip_match[] = {    { .compatible = "rockchip,rk3568-dw-mshc",      .data = &rockchip_drv_data },    { .compatible = "rockchip,rk3588-dw-mshc",      .data = &rockchip_drv_data },    { }};MODULE_DEVICE_TABLE(of, dw_mci_rockchip_match);staticstructplatform_driverdw_mci_rockchip_pltfm_driver = {    .probe      = dw_mci_pltfm_register,    .remove     = dw_mci_pltfm_remove,    .driver     = {        .name       = "dwmmc_rockchip",        .probe_type = PROBE_PREFER_ASYNCHRONOUS,        .of_match_table = dw_mci_rockchip_match,        .pm     = &dw_mci_rockchip_dev_pm_ops,    },};module_platform_driver(dw_mci_rockchip_pltfm_driver);

4.1.3 Probe 函数

staticintdw_mci_pltfm_register(struct platform_device *pdev){structdw_mci *host;structresource *res;int err;/* 分配主机结构 */    host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);if (!host)return -ENOMEM;/* 获取寄存器地址 */    res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dwmmc");    host->regs = devm_ioremap_resource(&pdev->dev, res);if (IS_ERR(host->regs))return PTR_ERR(host->regs);/* 获取中断 */    host->irq = platform_get_irq(pdev, 0);if (host->irq < 0)return host->irq;/* 获取时钟 */    host->ciu_clk = devm_clk_get(&pdev->dev, "ciu");    host->biu_clk = devm_clk_get(&pdev->dev, "biu");/* 初始化 MMC 主机 */    host->mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), &pdev->dev);if (!host->mmc)return -ENOMEM;/* 设置主机操作函数 */    host->mmc->ops = &dw_mci_ops;/* 设置能力标志 */    host->mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |                      MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;/* 注册中断 */    err = devm_request_irq(&pdev->dev, host->irq, dw_mci_interrupt,                           IRQF_SHARED, "dwmmc", host);if (err)return err;/* 添加主机到系统 */    err = mmc_add_host(host->mmc);if (err)return err;    platform_set_drvdata(pdev, host);return0;}

4.1.4 请求处理

staticvoiddw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq){structdw_mci *host = mmc_priv(mmc);unsignedlong flags;    spin_lock_irqsave(&host->lock, flags);/* 如果当前有请求在处理,加入pending队列 */if (host->cur_slot) {        host->pending = true;        host->pending_mrq = mrq;        spin_unlock_irqrestore(&host->lock, flags);return;    }/* 开始处理请求 */    dw_mci_start_request(host, mrq);    spin_unlock_irqrestore(&host->lock, flags);}staticvoiddw_mci_start_request(struct dw_mci *host, struct mmc_request *mrq){structmmc_command *cmd = mrq->cmd;structmmc_data *data = mrq->data;/* 保存当前请求 */    host->mrq = mrq;/* 设置命令 */    dw_mci_set_cmd(host, cmd);/* 如果有数据传输 */if (data) {/* 配置DMA */        dw_mci_prep_dma(host, data);/* 使能DMA */        dw_mci_enable_dma(host);    }/* 发送命令 */    dw_mci_send_cmd(host);}

4.1.5 中断处理

staticirqreturn_tdw_mci_interrupt(int irq, void *dev_id){structdw_mci *host = dev_id;    u32 status;/* 读取中断状态 */    status = dw_mci_readl(host, DW_MCI_STATUS);/* 清除中断 */    dw_mci_writel(host, status, DW_MCI_STATUS);/* 检查命令完成 */if (status & DW_MCI_INT_CMD_DONE) {        dw_mci_cmd_complete(host);    }/* 检查数据完成 */if (status & DW_MCI_INT_DATA_DONE) {        dw_mci_data_complete(host);    }/* 检查错误 */if (status & DW_MCI_INT_ERROR) {        dw_mci_error(host, status);    }return IRQ_HANDLED;}staticvoiddw_mci_cmd_complete(struct dw_mci *host){structmmc_request *mrq = host->mrq;structmmc_command *cmd = mrq->cmd;/* 读取响应 */    cmd->resp[0] = dw_mci_readl(host, DW_MCI_RESPONSE0);    cmd->resp[1] = dw_mci_readl(host, DW_MCI_RESPONSE1);    cmd->resp[2] = dw_mci_readl(host, DW_MCI_RESPONSE2);    cmd->resp[3] = dw_mci_readl(host, DW_MCI_RESPONSE3);/* 如果没有数据传输,完成请求 */if (!mrq->data) {        dw_mci_request_complete(host);    }}staticvoiddw_mci_request_complete(struct dw_mci *host){structmmc_request *mrq = host->mrq;/* 调用完成回调 */if (mrq->done)        mrq->done(mrq);/* 检查pending请求 */if (host->pending) {        host->pending = false;        dw_mci_start_request(host, host->pending_mrq);    } else {        host->cur_slot = 0;    }}

4.2 主机操作函数集

staticconststructmmc_host_opsdw_mci_ops = {    .request        = dw_mci_request,    .set_ios        = dw_mci_set_ios,    .get_ro         = dw_mci_get_ro,    .card_present   = dw_mci_card_present,    .enable_sdio_irq = dw_mci_enable_sdio_irq,#ifdef CONFIG_PM    .suspend        = dw_mci_suspend,    .resume         = dw_mci_resume,#endif};staticvoiddw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios){structdw_mci *host = mmc_priv(mmc);/* 设置时钟频率 */if (ios->clock != host->cur_clk) {        clk_set_rate(host->ciu_clk, ios->clock);        host->cur_clk = ios->clock;    }/* 设置总线宽度 */if (ios->bus_width != host->cur_bus_width) {        dw_mci_set_bus_width(host, ios->bus_width);        host->cur_bus_width = ios->bus_width;    }/* 设置电源模式 */if (ios->power_mode != host->cur_power_mode) {        dw_mci_set_power_mode(host, ios->power_mode);        host->cur_power_mode = ios->power_mode;    }}

五、编译测试

5.1 内核配置

要启用 MMC/SD 支持,需要在内核配置中启用以下选项:

Device Drivers --->  <*> MMC/SD/SDIO card support --->    <*> MMC block device driver    [*] Secure Digital Host Controller Interface support    <*> Arasan Multimedia Card Interface support    <*> Synopsys Designware Memory Card Interface support    <*> Renesas SDHI SD/SDIO controller support    <*> MMC host driver debugging

关键配置选项:

配置选项
说明
CONFIG_MMC
启用 MMC/SD/SDIO 支持
CONFIG_MMC_BLOCK
启用 MMC 块设备驱动
CONFIG_MMC_DW
启用 DesignWare MMC 控制器支持
CONFIG_MMC_DW_ROCKCHIP
启用瑞芯微 DesignWare MMC 支持
CONFIG_MMC_SDHCI
启用 SDHCI 控制器支持
CONFIG_MMC_DEBUG
启用调试信息

5.2 编译

# 配置内核make ARCH=arm64 menuconfig# 编译内核make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)# 编译模块make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- modules -j$(nproc)# 安装模块make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=./modules modules_install

5.3 加载测试

# 查看设备树节点ls /sys/bus/platform/devices/ | grep mmc# 查看已加载的 MMC 模块lsmod | grep mmc# 如果驱动是模块形式,手动加载insmod dw_mmc_pltfm.koinsmod dw_mmc_rockchip.ko# 查看内核日志dmesg | tail -30

5.4 验证设备识别

# 查看块设备lsblk# 查看 MMC 设备ls -la /dev/mmcblk*# 查看分区信息cat /proc/partitions# 查看卡信息cat /sys/class/mmc_host/mmc0/mmc0:*/cidcat /sys/class/mmc_host/mmc0/mmc0:*/csd# 挂载测试mkdir -p /mnt/sdcardmount /dev/mmcblk0p1 /mnt/sdcardls /mnt/sdcard

5.5 性能测试

# 读取测试dd if=/dev/mmcblk0 of=/dev/null bs=1M count=100 conv=fsync# 写入测试dd if=/dev/zero of=/tmp/testfile bs=1M count=100dd if=/tmp/testfile of=/dev/mmcblk0 bs=1M count=100 conv=fsync# 使用 hdparm 测试hdparm -t /dev/mmcblk0# 使用 fio 进行基准测试fio --name=mmc_test --filename=/dev/mmcblk0 --size=512M --bs=4k --rw=read --iodepth=32 --direct=1

六、排坑总结

6.1 常见编译错误

错误
原因
解决方案
error: linux/mmc/host.h: No such file or directory
没有启用 MMC 支持
确保 CONFIG_MMC=y
undefined reference to 'mmc_alloc_host'
缺少 MMC 核心模块
确保 CONFIG_MMC=y
macro 'MMC_CAP_8_BIT_DATA' undeclared
内核版本差异
检查内核版本,使用正确的能力标志
dma_mapping_error() failed
DMA 配置问题
检查 DMA mask 设置和设备树配置

6.2 常见运行时问题

问题一:卡无法识别

现象dmesg 显示 "mmc0: error -110 whilst initialising SD card"

原因分析

  • 电源电压配置错误
  • 时钟频率过高
  • 卡检测引脚配置错误
  • 卡本身有问题

解决方案

// 检查电源配置structmmc_iosios = {0};ios.vdd = MMC_VDD_32_33 | MMC_VDD_33_34;mmc_set_ios(host, &ios);// 降低初始化时钟host->f_init = 400000;  // 设置为 400kHz// 检查卡检测引脚if (!mmc_card_present(host)) {    dev_warn(host->dev, "No card present\n");return -ENODEV;}

问题二:传输速度慢

现象:读取速度远低于预期

原因分析

  • 总线宽度配置为 1-bit
  • 时钟频率没有提升到高速模式
  • DMA 没有启用
  • I/O 调度器配置不当

解决方案

// 启用 4-bit 或 8-bit 总线host->caps |= MMC_CAP_4_BIT_DATA;// 设置最大时钟频率host->f_max = 150000000;  // 150MHz// 启用 DMAhost->caps |= MMC_CAP_DMA;// 使用 noop 调度器(对于闪存设备更合适)echo noop > /sys/block/mmcblk0/queue/scheduler

问题三:写入失败

现象dd 写入时出现 I/O 错误

原因分析

  • 写保护开关开启
  • 卡已满或只读
  • 坏块问题
  • 电压不稳定

解决方案

// 检查写保护状态if (mmc_get_ro(host)) {    dev_warn(host->dev, "Card is read-only\n");return -EROFS;}// 检查卡状态if (card->state & MMC_CARD_READ_ONLY) {    dev_warn(host->dev, "Card is locked\n");return -EROFS;}// 尝试重新初始化mmc_attach(host);

问题四:热插拔问题

现象:卡拔出后再插入无法识别

原因分析

  • 热插拔中断没有正确配置
  • 卡检测工作队列没有正确调度
  • 电源没有正确复位

解决方案

// 确保热插拔中断已注册request_irq(host->irq, dw_mci_interrupt, IRQF_TRIGGER_RISING, "mmc", host);// 调度卡检测schedule_delayed_work(&host->detect, HZ);// 复位卡mmc_bus_reset(host);

6.3 版本兼容性问题

内核版本
变化
影响
5.10+
blk-mq 成为默认
需要使用 blk-mq API
5.15+
mmc_alloc_host
 接口变化
需要检查参数
6.0+
DMA 映射 API 变化
需要更新 DMA 相关代码
6.10+
电源管理优化
需要检查 PM 回调

七、总结延伸

7.1 知识点回顾

  1. MMC 子系统架构

    • 三层架构:核心层、主机驱动层、SDIO 层
    • 分层设计提高代码复用性
    • 通过 ops 指针实现硬件抽象
  2. 核心数据结构

    • struct mmc_host:主机控制器描述
    • struct mmc_card:卡描述
    • struct mmc_request:请求描述
    • struct mmc_command:命令描述
    • struct mmc_data:数据描述
  3. 请求处理流程

    • 用户空间 → 文件系统 → 通用块层 → MMC 核心层 → 主机驱动 → 硬件
    • 使用异步回调机制
    • 支持多请求排队
  4. 卡初始化流程

    • 复位 → 电压检测 → 获取 CID → 获取 RCA → 获取 CSD → 选择卡 → 配置

7.2 拓展学习方向

📚 进阶内容

  1. 深入理解 MMC 协议

    • 学习 SD Specifications Part 1 Physical Layer
    • 理解 UHS-I/UHS-II 高速模式
    • 研究 DDR50/DDR104 模式
  2. 探索 eMMC 驱动

    • eMMC 特有功能(BOOT 分区、RPMB)
    • EXT_CSD 寄存器详解
    • 分区管理和命名空间
  3. 研究 SD Express

    • PCIe 接口的 SD 卡
    • NVMe over PCIe
    • 高性能存储优化
  4. 分析 SDIO 驱动

    • SDIO 设备枚举流程
    • SDIO 函数驱动开发
    • WiFi/蓝牙 SDIO 设备驱动
  5. 电源管理优化

    • 运行时 PM 支持
    • 低功耗模式配置
    • 唤醒事件处理

🔧 相关项目

  1. 为新的 MMC 控制器添加驱动支持
  2. 实现 MMC 测试工具
  3. 优化 MMC 驱动性能
  4. 添加 SD Express 支持
  5. 实现 eMMC BOOT 分区功能

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-03 10:59:37 HTTP/2.0 GET : https://f.mffb.com.cn/a/495425.html
  2. 运行时间 : 0.099329s [ 吞吐率:10.07req/s ] 内存消耗:5,098.47kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=fe783a75701cef3e12e67d914e26fc88
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000599s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000760s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000357s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000250s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000539s ]
  6. SELECT * FROM `set` [ RunTime:0.000210s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000586s ]
  8. SELECT * FROM `article` WHERE `id` = 495425 LIMIT 1 [ RunTime:0.000885s ]
  9. UPDATE `article` SET `lasttime` = 1783047577 WHERE `id` = 495425 [ RunTime:0.008928s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 67 LIMIT 1 [ RunTime:0.000395s ]
  11. SELECT * FROM `article` WHERE `id` < 495425 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000633s ]
  12. SELECT * FROM `article` WHERE `id` > 495425 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000471s ]
  13. SELECT * FROM `article` WHERE `id` < 495425 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000875s ]
  14. SELECT * FROM `article` WHERE `id` < 495425 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.014650s ]
  15. SELECT * FROM `article` WHERE `id` < 495425 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001229s ]
0.100927s