块设备驱动模型
块设备是 I/O 设备中的一类,将信息存储在固定大小的块中,每个块都有自己的地址。数据块的大小通常在 512 字节到 32768 字节之间。块设备的基本特征是每个块都能独立于其他块而读写。磁盘是最常见的块设备。
SylixOS 实现了兼容 POSIX 标准的输入输出系统,SylixOS 的 I/O 概念继承了 UNIX 操作系统的概念,认为一切皆为文件。本章介绍 SylixOS 在 I/O 层之下提供的块设备模型,用户驱动可以使用此标准化的设备模型来编写,这样可以对上层提供统一的、标准的设备 API,方便应用程序移植。块设备驱动相关信息位于 ”libsylixos/SylixOS/system/device/block”下。
带有磁盘缓冲器和分区处理工具的 SylixOS 块设备结构如下图所示。
SylixOS 存在两种块设备驱动模型,即 LW_BLK_DEV 模型和 LW_BLK_RAW 模型,对应着两种文件系统的装载方式,即 LW_BLK_DEV 模式和 BLOCK 设备文件模式,用户可以根据自身系统的特点灵活选择。
LW_BLK_DEV 模式
LW_BLK_DEV 模式是 SylixOS 的默认挂载模式,如下图所示。
LW_BLK_DEV 整体与 I/O 系统无关,仅是一个文件系统设备操作的实体,对于用户应用程序不可见,类似于很多嵌入式第三方文件系统软件提供的方式。此方式更加适合于嵌入式系统,推荐使用此方式。
其块设备驱动创建函数原型如下:
#include <SylixOS.h>
INT __blockIoDevCreate (PLW_BLK_DEV pblkdNew);
函数 __blockIoDevCreate 原型分析:
- 此函数成功返回设备表索引,块设备错误返回 PX_ERROR ,空间已满返回 -2 。
- 参数 pblkdNew 是新的块设备控制块。
函数 __blockIoDevCreate 在驱动层创建了一个块设备驱动,使用结构体 LW_BLK_DEV 向内核提供操作函数集和基本信息,其详细描述如下:
typedef struct {
PCHAR BLKD_pcName; /* 可以为 NULL 或者 "\0" */
/* nfs romfs 文件系统使用 */
FUNCPTR BLKD_pfuncBlkRd; /* function to read blocks */
FUNCPTR BLKD_pfuncBlkWrt; /* function to write blocks */
FUNCPTR BLKD_pfuncBlkIoctl; /* function to ioctl device */
FUNCPTR BLKD_pfuncBlkReset; /* function to reset device */
FUNCPTR BLKD_pfuncBlkStatusChk; /* function to check status */
ULONG BLKD_ulNSector; /* number of sectors */
ULONG BLKD_ulBytesPerSector; /* Bytes per sector */
ULONG BLKD_ulBytesPerBlock; /* Bytes per block */
BOOL BLKD_bRemovable; /* removable medium flag */
BOOL BLKD_bDiskChange; /* media change flag */
INT BLKD_iRetry; /* retry count for IO error */
INT BLKD_iFlag; /* O_RDONLY or O_RDWR */
/*
* 以下参数操作系统使用, 必须初始化为 0.
*/
INT BLKD_iLogic; /* if this is a logic disk */
UINT BLKD_uiLinkCounter; /* must be 0 */
PVOID BLKD_pvLink; /* must be NULL */
UINT BLKD_uiPowerCounter; /* must be 0 */
UINT BLKD_uiInitCounter; /* must be 0 */
} LW_BLK_DEV;
typedef LW_BLK_DEV BLK_DEV;
typedef LW_BLK_DEV *PLW_BLK_DEV;
typedef LW_BLK_DEV *BLK_DEV_ID;
结构体 LW_BLK_DEV 提供了块设备的一系列静态参数,以及读、写、复位、I/O 控制等功能函数。
LW_BLK_DEV 模式下除了提供块设备驱动创建函数,SylixOS 还提供了一系列相关操作函数,如初始化、删除、读写、复位、控制块设备及获取块设备状态等,用户可在“libsylixos/SylixOS/system/device/block/blockIo.c”文件中自行查阅。
BLOCK 设备文件模式
BLOCK 设备文件模式是 SylixOS 可选择的文件系统挂载方式,对应着 LW_BLK_RAW 模型,如下图所示。
LW_BLK_RAW 是存在于 I/O 系统中的一个设备,用户可以通过 I/O 系统直接访问此设备,对于用户来说是可见的设备。使用 mount 将此设备挂接文件系统后,文件系统将通过 I/O 操作此设备,此方法类似于 Linux 等大型操作系统提供的方法。例如插入一个 U 盘,如果驱动程序注册为 Blk Raw I/O ,则 I/O 系统中会出现一个 /dev/blk/xxx 的设备,之后通过 mount 指令将其挂载入文件系统操作,如“mount -t vfat /dev/blk/xxx /mnt/udisk”。用户操作 dev/blk/xxx 等于绕过文件系统直接操作物理设备。用户操作 /mnt/udisk 表示使用文件系统操作物理设备。此操作类型需要 LW_CFG_MOUNT_EN 与 LW_CFG_SHELL_EN 支持,即使能 mount 工具和 tshell。
创建 BLK RAW 设备驱动的函数原型如下:
#include <SylixOS.h>
INT API_BlkRawCreate (CPCHAR pcBlkName,
BOOL bRdOnly,
BOOL bLogic,
PLW_BLK_RAW pblkraw);
函数 API_BlkRawCreate 原型分析:
- 此函数成功返回 ERROR_NONE ,失败返回 PX_ERROR 。
- 参数 pcBlkName 是块设备名称。
- 参数 bRdOnly 是表明是否为只读设备。
- 参数 bLogic 是表明是否为逻辑分区。
- 参数 pblkraw 是创建的 blk raw 控制块。
函数 API_BlkRawCreate 通过/dev/blk/xxx 块设备生成一个 BLOCK 控制块,该函数只能内核程序调用,使用结构体 LW_BLK_RAW 向内核提供操作函数集和基本信息,其详细描述如下:
typedef struct {
LW_BLK_DEV BLKRAW_blkd;
INT BLKRAW_iFd;
mode_t BLKRAW_mode;
} LW_BLK_RAW;
typedef LW_BLK_RAW *PLW_BLK_RAW;
- BLKRAW_blkd :块设备。
- BLKRAW_iFd :块设备的文件描述符。
- BLKRAW_mode :块设备打开模式。
推荐使用第一种方法简单可靠,直接使用 oemDiskMount/oemDiskMountEx 即可,oemDiskMount 函数会自动在 /dev/blk 目录内创建 blk 设备文件。