2. VxWorks I/O 子系统基础

在深入 DMA 传输优化之前,必须理解 VxWorks 的 I/O 子系统如何组织文件系统、块设备驱动以及系统调用路径。本章将剖析从 open() 到物理扇区读写的完整链路,并澄清逻辑卷与物理设备之间的映射关系。

2.1 VxWorks 文件系统与块设备驱动架构

VxWorks 的 I/O 子系统采用分层架构,从上到下依次为:系统调用接口层、文件系统层、I/O 子系统核心层、块设备驱动层 和 物理设备层。块设备驱动通过 BLK_DEV 结构体向文件系统注册回调函数。

VxWorks I/O 子系统分层架构 系统调用接口层 (open / read / write / ioctl) 文件系统层 (dosFs / rawFs / nfs / romFs) I/O 子系统核心 (iosLib / 设备列表 / 驱动表) 块设备驱动层 (BLK_DEV / 策略函数) 物理设备层 (NAND Flash / eMMC / SATA SSD) 文件系统 注册 BLK_DEV 驱动实现 策略回调

2.2 I/O 系统调用流程

当应用程序调用 open("/ata0/1:0", O_RDWR) 时,VxWorks 内核经历以下完整路径:

  1. 系统调用分发:open() 进入内核态,通过 iosLib 查找文件描述符表。
  2. 设备名解析:解析路径 /ata0/1:0,识别设备驱动前缀 /ata0。
  3. 驱动匹配:在驱动表中查找匹配的 DEV_HDR,调用驱动的 create() 或 open() 回调。
  4. 文件系统挂载:若设备已格式化,文件系统层读取超级块,初始化卷结构。
  5. 返回 fd:用户获得文件描述符,后续 read()/write() 直接通过 fd 索引到设备。
I/O 系统调用流程:open("/ata0/1:0", O_RDWR) ① 应用调用 open() ② iosLib 查找驱动表 ③ 匹配 DEV_HDR ④ 驱动 create() 回调 ⑤ 文件系统挂载卷 ⑥ 返回 fd 关键数据结构 • DEV_HDR: 设备头 • BLK_DEV: 块设备描述符 • DOS_VOL_DESC: 卷描述符

2.3 逻辑卷与物理设备映射

VxWorks 通过 卷管理 实现逻辑地址到物理扇区的映射。一个物理设备可以被划分为多个逻辑卷,每个卷拥有独立的文件系统。映射关系由 BLK_DEV 结构体中的 bd_blkRd() 和 bd_blkWrt() 回调函数维护。

概念 描述 VxWorks 对应结构
物理设备 实际的存储硬件,如 NAND Flash、eMMC、SATA 盘 DEV_HDR + 驱动私有数据
逻辑卷 物理设备上的分区,拥有独立的文件系统 DOS_VOL_DESC / RAW_VOL_DESC
块设备 文件系统与物理设备之间的抽象接口 BLK_DEV (包含扇区大小、总扇区数、读写回调)
分区表 描述物理设备上分区布局的元数据 MBR 或 GPT 解析结果
逻辑卷与物理设备映射关系 逻辑视图 (文件系统层) 卷 A: dosFs (LBA 0-9999) 卷 B: rawFs (LBA 10000-19999) 卷 C: dosFs (LBA 20000-29999) 映射层 (BLK_DEV) bd_blkRd() / bd_blkWrt() LBA → 物理地址转换 分区偏移量计算 物理设备 扇区 0-9999 扇区 10000-19999 扇区 20000-29999 映射示例:卷 A 的 LBA 500 物理扇区 = 卷起始偏移 + LBA = 0 + 500 = 扇区 500 驱动通过 bd_blkRd(500, buf, nSectors) 发起 DMA 传输

2.4 BLK_DEV 结构体详解

块设备驱动的核心是 BLK_DEV 结构体,它定义了文件系统与硬件之间的契约。以下是关键字段:

typedef struct blk_dev {
    /* 设备参数 */
    ULONG       bd_blkRd;       /* 块读取策略函数指针 */
    ULONG       bd_blkWrt;      /* 块写入策略函数指针 */
    ULONG       bd_ioctl;       /* 设备控制函数指针 */
    ULONG       bd_reset;       /* 设备复位函数指针 */
    ULONG       bd_statusChk;   /* 状态检查函数指针 */
    ULONG       bd_removable;   /* 可移动介质标志 */
    ULONG       bd_nBlocks;     /* 总块数 */
    ULONG       bd_bytesPerBlk; /* 每块字节数 (通常512) */
    ULONG       bd_blkRdMax;    /* 单次读取最大块数 */
    ULONG       bd_blkWrtMax;   /* 单次写入最大块数 */
    void *      bd_dev;         /* 驱动私有数据指针 */
} BLK_DEV;

性能关键点:bd_blkRdMax 和 bd_blkWrtMax 直接决定了单次 DMA 传输的最大长度。在后续章节中,我们将通过调整这两个参数来优化 DMA 传输效率。

2.5 设备命名与路径解析

VxWorks 使用 设备前缀 机制将路径名映射到驱动。常见命名规则如下:

设备路径示例 驱动前缀 设备类型 卷标识
/ata0/1:0 /ata0 ATA 控制器 0 第 1 个设备,第 0 个分区
/flash0/0:1 /flash0 Flash 控制器 0 第 0 个设备,第 1 个分区
/mmc0/0:0 /mmc0 eMMC 控制器 0 第 0 个设备,第 0 个分区
/nvme0/ns1 /nvme0 NVMe 控制器 0 命名空间 1

优化提示:在 DMA 传输优化中,理解路径解析有助于定位驱动注册时的 BLK_DEV 实例。通过 iosDevShow() 可以查看当前系统中所有已注册的设备及其参数。

2.6 本章小结

  • VxWorks I/O 子系统采用五层架构,块设备驱动位于 I/O 子系统核心 与 物理设备 之间。
  • 系统调用 open() 经过 驱动表查找 → 设备匹配 → 回调执行 → 文件系统挂载 四个阶段。
  • 逻辑卷通过 BLK_DEV 的 LBA 偏移量 映射到物理扇区,映射逻辑由驱动实现。
  • BLK_DEV 结构体中的 bd_blkRdMax 和 bd_blkWrtMax 是 DMA 传输优化的关键参数。
  • 设备命名遵循 /驱动前缀/设备号:分区号 的格式,路径解析由 iosLib 完成。