块设备是I/O设备中的一类,是将信息存储在固定大小的块中,每个块有自己的地址,数据块大小通常在512字节到32768字节之间。块设备的基本特征是每个块都能独立于其他块而读写。磁盘是最常见的块设备。
SylixOS实现了兼容POSIX标准的输入输出系统,SylixOS的I/O概念继承了UNIX操作系统的概念,认为一切皆为文件。本章介绍SylixOS在I/O层之下提供的块设备模型,用户驱动可以使用此标准化的设备模型来编写,这样可以对上层提供统一的、标准的设备API,方便应用程序移植。块设备驱动相关信息位于"libsylixos/SylixOS/system/device/block"下。
SylixOS内部提供了多种标准的文件系统,方便用户使用,它实际上就是一组虚拟的设备驱动,提供两组API接口,对上符合I/O系统虚拟文件系统(VFS)标准,对下要求设备符合块设备标准。带有磁盘缓冲器和分区处理工具的SylixOS块设备结构如图 21所示。
图 21 SylixOS块设备结构
SylixOS存在两种块设备驱动模型,即LW_BLK_DEV模型和LW_BLK_RAW模型,对应着两种文件系统的装载方式,即LW_BLK_DEV模式和BLOCK设备文件模式,用户可以根据自身系统的特点灵活选择。
LW_BLK_DEV模式是操作系统的默认挂载模式,如图 22所示。
图 22 LW_BLK_DEV模式
LW_BLK_DEV整体与I/O系统无关,仅是一个文件系统设备操作的实体,对于用户应用程序不可见, 类似于很多嵌入式第三方文件系统软件提供的方式。此方式更加适合于嵌入式系统,推荐使用此方式。
其块设备驱动创建函数原型如程序清单 21所示。
程序清单 21 LW_BLK_DEV模式块设备驱动创建
INT __blockIoDevCreate (PLW_BLK_DEV pblkdNew)
函数__blockIoDevCreate在驱动层创建了一个块设备驱动,使用结构体LW_BLK_DEV向内核提供操作函数集和基本信息,其详细描述如程序清单 22所示。
程序清单 22 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 I/O errors */
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模式下除了提供块设备驱动创建函数,SylixOS还提供了一系列相关操作函数,如初始化、删除、读写、复位、控制块设备及获取块设备状态等,如程序清单 23所示。
程序清单 23 LW_BLK_DEV模式操作函数
VOID __blockIoDevInit (VOID)
VOID __blockIoDevDelete (INT iIndex)
PLW_BLK_DEV __blockIoDevGet (INT iIndex)
INT __blockIoDevRead (INT iIndex,
VOID *pvBuffer,
ULONG ulStartSector,
ULONG ulSectorCount)
INT __blockIoDevWrite (INT iIndex,
VOID *pvBuffer,
ULONG ulStartSector,
ULONG ulSectorCount)
INT __blockIoDevIoctl (INT iIndex, INT iCmd, LONG lArg)
INT __blockIoDevReset (INT iIndex)
INT __blockIoDevStatus (INT iIndex)
INT __blockIoDevIsLogic (INT iIndex)
INT __blockIoDevFlag (INT iIndex)
BLOCK设备文件模式是SylixOS可选择的文件系统挂载方式,对应着LW_BLK_RAW模型,如图 23所示。
图 23 BLOCK设备文件模式
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与LW_CFG_SHELL_EN支持。
创建BLK RAW设备驱动的函数原型如程序清单 24。
程序清单 24创建BLK RAW设备驱动
INT API_BlkRawCreate(CPCHAR pcBlkName, BOOL bRdOnly, BOOL bLogic, PLW_BLK_RAW pblkraw);
函数API_BlkRawCreate通过/dev/blk/xxx块设备生成一个BLOCK控制块,该函数只能内核程序调用,使用结构体LW_BLK_RAW向内核提供操作函数集和基本信息,其详细描述如程序清单 25所示。
程序清单 25 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;
推荐使用第一种方法简单可靠, 直接使用 oemDiskMount/oemDiskMountEx 即可, oemDiskMount 函数会自动创建 blk设备文件在 /dev/blk 目录内。
无