首页 > 代码库 > SylixOS块设备驱动模型

SylixOS块设备驱动模型

 

1. 块设备简介

块设备是I/O设备中的一类,是将信息存储在固定大小的块中,每个块有自己的地址,数据块大小通常在512字节到32768字节之间。块设备的基本特征是每个块都能独立于其他块而读写。磁盘是最常见的块设备。

2. 技术实现

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设备文件模式,用户可以根据自身系统的特点灵活选择。

2.1. LW_BLK_DEV模式

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)

2.2. LOCK设备文件模式

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 目录内。

3. 参考资料

SylixOS块设备驱动模型