0%

2025秋冬季OS训练营实习总结报告-PassingThroughStarDust

StarryOS SD/MMC 驱动 3 个月开发技术总结

摘要

本报告记录了我在泉城实验室为期3个月的实习期间,围绕 StarryOS SD 卡驱动展开的主要开发与优化工作。实习期间,我深入分析了原有的 simple-sdmmc 驱动,针对其在功能、性能和兼容性方面的不足,进行了系统性的优化和扩展,最终形成了功能更完善、兼容性更强的 simple-sdmmc-extended 版本。该版本补全和优化了硬件初始化流程与时钟与电源管理,还引入了 DMA(直接内存访问)支持,显著提升了大容量数据传输的效率和系统资源利用率。在驱动开发的同时,我还设计并实现了一个自动化测试框架,用于系统性地验证 SD/MMC 驱动在不同平台和多种极端场景下的功能正确性、性能表现以及平台兼容性。测试框架涵盖了基本功能、性能基准、并发一致性、平台专用等多类测试,能够自动统计吞吐量、IOPS、错误数等关键指标,并输出详细日志,极大提升了驱动开发和回归验证的效率。


1. 项目背景

在 StarryOS 项目早期,为实现对 SD/MMC 存储设备的基本支持,设计并实现了 simple-sdmmc 驱动。该驱动采用了轮询(Polling)方式进行控制器状态检测和数据传输:

  • 驱动通过不断轮询硬件寄存器,判断命令是否完成、FIFO 是否可读写、数据传输是否结束等,无需依赖中断。
  • 轮询方式实现简单,便于在无操作系统或早期启动阶段使用,适合嵌入式、裸机等资源受限场景。
  • 该设计保证了驱动的确定性和可控性,但在高性能或多任务环境下,CPU 占用较高,后续版本逐步引入了 DMA、并发等优化。

2. simple-sdmmc 的优化

2.2 关键优化点

2.2.1 硬件初始化流程完善

具体的工作包括了:

  • 时钟管理
    • 明确分步关闭/配置/开启时钟,确保卡片处于稳定状态
    • 多次发送 ResetClock 命令,保证控制器与卡片同步
  • 电源管理
    • 显式设置 PWREN,确保卡片上电
  • 延时与稳定性
    • 延长初始化等待周期,确保卡片在低频下充分稳定

硬件初始化的优化如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
优化前:
[关闭时钟]
→ [发送 ResetClock 命令]
→ [设置低速分频]
→ [开启时钟]
→ [再次发送 ResetClock]
→ [设置数据宽度为1bit]
→ [重置DMA]
→ [发送 GoIdleState 命令]
→ [发送 SendIfCond,检查卡片电压/版本]
→ [循环发送 AppCmd + SdSendOpCond,等待卡片上电完成]
→ [发送 AllSendCid,读取卡片CID]
→ [发送 SetRca,分配/获取RCA地址]
→ [发送 SendCsd,读取卡片CSD,解析容量/特性]
→ [选择卡片 SelectCard]
→ [设置块长度/计数]
→ [卡片初始化完成,可进行数据读写]

优化后:
[清理U-Boot遗留中断标志]
→ [关闭时钟]
→ [多次发送 ResetClock,确保同步]
→ [设置/开启时钟]
→ [显式上电 PWREN]
→ [延长等待,保证低频下稳定]
→ [设置数据宽度/分频/其他参数]
→ [发送 GoIdleState 命令]
→ [发送 SendIfCond,检查卡片电压/版本]
→ [循环发送 AppCmd + SdSendOpCond,等待卡片上电完成]
→ [发送 AllSendCid,读取卡片CID]
→ [发送 SetRca,分配/获取RCA地址]
→ [发送 SendCsd,读取卡片CSD,解析容量/特性]
→ [选择卡片 SelectCard]
→ [设置总线宽度/高速模式(如支持)]
→ [设置块长度/计数]
→ [(可选)切换到高速/4bit模式]
→ [卡片初始化完成,可进行数据读写]
2.2.2 DMA 支持与寄存器抽象

具体的工作包括了:

  • 新增描述符链数据结构 IdmacDescriptor 为 CPU 与 IDMAC 间的数据交换作支持。
  • 新增 dma_enabled 字段,初始化 IDMAC 控制器。
  • 优化寄存器访问抽象,提升代码可维护性与可移植性。
2.2.3 命令与数据传输流程增强
  • 将原有 send_cmd 仅用于控制类/非数据命令,数据传输相关命令全部优化为 send_cmd_idmac,实现命令与数据路径分离。
  • send_cmd_idmac 针对 DMA/IDMAC 场景,自动完成物理地址转换、描述符配置、DMA 启动、状态与错误检查等,极大提升了大块数据传输的效率与健壮性。
  • 两者均增加了详细的超时与状态检查、错误日志,便于定位问题。
  • 兼容部分命令(如 GoIdleState)超时非致命的实际情况。

命令与数据传输流程优化前后对比:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
优化前:
[设置块大小/计数]
→ [配置命令参数]
→ [发送读命令]
→ [等待命令完成]
→ [轮询FIFO,逐字节读取数据]
→ [检查/清理中断状态]
→ [返回数据]

优化后:
[设置块大小/计数]
→ [配置命令参数]
→ [选择数据传输模式(CPU轮询或IDMAC DMA)]
→ [发送读命令]
→ [等待命令/数据完成,超时与错误检查]
→ [CPU模式:轮询FIFO读取]
→ [DMA模式:配置描述符,启动IDMAC,等待完成]
→ [检查/清理中断与DMA状态]
→ [返回数据]

2.3 典型问题与解决方案

2.3.1 U-Boot 遗留状态导致初始化失败
  • 现象:U-Boot 预设时钟/宽度,驱动未重置,导致卡片未能正常初始化
  • 解决:驱动启动时强制重配时钟、电源、数据宽度,确保硬件状态一致
2.3.2 GoIdleState 超时
  • 现象:部分卡片在 CMD0 (GoIdleState) 阶段超时,但后续流程可继续
  • 解决:将 CMD0 超时视为可接受,后续命令继续执行
2.3.3 DMA/CPU 模式性能对比
  • 通过测试框架对比 DMA 与 CPU 直传模式,量化性能提升

2.4 优化效果

  • 驱动在 VisionFive2 等平台下可稳定初始化并识别大容量 SD 卡
  • 性能测试显示 DMA 模式下吞吐量显著提升
  • 代码结构更清晰,便于后续维护与扩展

3. 测试框架设计与实现

3.1 测试框架描述

整个测试框架存储在 sdmmc-tests 项目中,通过分模块自动化验证 SD/MMC 驱动的各项能力,涵盖基本读写、边界与异常、性能基准、并发一致性、以及平台专用(如 VisionFive2)等多类测试。每类测试包含单块/多块读写、边界块访问、错误注入、顺序与随机性能、DMA/CPU对比、缓存一致性、多线程压力、时钟切换、中断延迟和大容量寻址等典型场景。测试框架会自动统计吞吐量、IOPS、错误数等指标,并输出详细日志,便于定位驱动在不同平台和极端条件下的功能与性能问题。所有测试均可一键批量运行,极大提升了驱动开发和回归验证的效率与可靠性。

3.2 测试分类与功能说明

当前 sdmmc-tests 测试框架将测试分为以下几大类,每类覆盖不同的驱动能力:

  • 基本功能与正确性测试(basic/)

    • 单块/多块读写:验证驱动对单个和多个数据块的读写正确性。
    • 边界条件:测试首块、末块、分区边界等特殊地址的访问,确保无越界和数据一致性。
    • 异常与错误处理:如非法块号、错误缓冲区长度、超时等,验证驱动能否正确检测和报告错误。
  • 性能基准测试(benchmark/)

    • 顺序吞吐量:测量大块连续读写的最大带宽。
    • 随机访问性能:评估随机读写的 IOPS 和延迟。
    • DMA/CPU 模式对比:对比 DMA 直传与 CPU 轮询两种模式下的性能差异,量化 DMA 优势。
  • 并发与一致性测试(concurrency/)

    • 缓存一致性:验证 DMA 传输下 CPU 缓存与物理内存的数据一致性,确保写后读、读后写无异常。
    • 并发压力:模拟多线程/多任务下的交错读写,检验驱动在高并发场景下的稳定性和正确性。
  • 平台专用测试(visionfive2/)

    • SDIO 时钟切换:动态切换多种时钟频率,验证驱动对不同速率的适配能力。
    • 中断延迟:测量中断响应时间,评估驱动实时性。
    • LBA48 支持:测试大容量卡 (>2TB) 的 48 位寻址能力。

每类测试均配有详细日志和统计信息,便于定位问题和量化性能。

3.3 测试框架设计要点

  • 统一的 TestResult/TestError 类型,便于错误归类与统计
  • TestStats 支持吞吐量、IOPS 等性能指标自动统计
  • 详细日志输出,便于定位问题
  • 支持特性开关(如 vf2)灵活适配不同硬件

3.4 运行方式

  • 可集成于 StarryOS 镜像,在真实硬件或 QEMU 上运行
  • 支持独立 cargo 运行,便于 API 层测试

相关仓库

  1. 优化后的 StarryOS 代码与日志仓库
  2. 优化后的 simple-sdmmc 代码仓库
  3. 测试集框架代码仓库