块设备是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;
BLKD_iRetry 至少为 1;
BLKD_ulNSector 为 0 时,系统将通过 BLKD_pfuncBlkIoctl 函数获取;
BLKD_ulBytesPerBlock 为 0 时,系统将通过 BLKD_pfuncBlkIoctl 函数获取;
BLKD_ulBytesPerSector 最小为 512 必须为 2 的 n 次方 (FAT 扇区最大支持 4096 字节);
BLKD_pfuncBlkReset fatFsDevCreate函数将会挂载设备, 同时为设备通电, 然 后立即调用此函数复位设备。当一个块设备存在多个分区时, 每次挂载不同分区时都会调用此函数;
BLKD_bRemovable 是否是可移动设备;
BLKD_bDiskChange 磁盘介质是否发生改变(初始化时必须为 FALSE, 当 磁盘发生改变时, 将无法再次操作必须重新建立卷);
BLKD_iFlag O_RDONLY 表示磁盘写保护;
BLKD_iLogic 是否为逻辑磁盘, 用户驱动程序只要将其设置为 0 即可;
BLKD_iLinkCounter 物理设备驱动相关字段, 初始化时必须为 0;
BLKD_pvLink 物理设备驱动相关字段, 初始化时必须为 NULL;
BLKD_uiPowerCounter 电源控制计数器, 初始化时必须为 0;
BLKD_uiInitCounter 磁盘初始化计数器, 初始化时必须为 0;
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);
pcBlkName 块设备名称;
bRdonly 只读;
bLogic 是否为逻辑分区;
pblkraw 创建的blk raw控制块;
函数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;
BLKRAW_blkd 块设备;
BLKRAW_iFd 块设备的文件描述符;
BLKRAW_mode 块设备打开模式;
推荐使用第一种方法简单可靠, 直接使用 oemDiskMount/oemDiskMountEx 即可, oemDiskMount 函数会自动创建 blk设备文件在 /dev/blk 目录内。
无
原文地址:http://12557713.blog.51cto.com/12547713/1916256