块设备是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所示。 ui
图 21 SylixOS块设备结构this
SylixOS存在两种块设备驱动模型,即LW_BLK_DEV模型和LW_BLK_RAW模型,对应着两种文件系统的装载方式,即LW_BLK_DEV模式和BLOCK设备文件模式,用户能够根据自身系统的特色灵活选择。spa
LW_BLK_DEV模式是操做系统的默认挂载模式,如图 22所示。操作系统
图 22 LW_BLK_DEV模式继承
LW_BLK_DEV总体与I/O系统无关,仅是一个文件系统设备操做的实体,对于用户应用程序不可见, 相似于不少嵌入式第三方文件系统软件提供的方式。此方式更加适合于嵌入式系统,推荐使用此方式。接口
其块设备驱动建立函数原型如程序清单 21所示。rem
程序清单 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 目录内。
无