虚拟块设备驱动源码
#define __SYLIXOS_KERNEL #include <SylixOS.h> #include <module.h> #include <stdlib.h> #include <string.h> /* * BSP内存需求: * 1. 虚拟磁盘由于是在内核用malloc申请的一块内存,所以需要保证BSP中内核data区域要大于这个磁盘内存的大小 * 2. 如果需要DCATTR_stMemSize磁盘缓存cache,这个cache是内核在内核堆上申请的,所以BSP中的data区也要大于这大小 * 3. 读猝发缓冲区大小为:猝发扇区数 * 扇区大小 * 4. 写猝发缓冲区大小为:猝发扇区数 * 扇区大小 * DCATTR_iMsgCount * 5. 3和4如果使用cache一致性,那么内核申请的区域是DMA区域,否则是内核堆区 * */ #define SECTOR_BYTES 512 #define VIRTUAL_DISK_SIZE 20 * LW_CFG_MB_SIZE #define BUSTOR_SECTOR 64 #define DISK_CACHE_SIZE 64 * LW_CFG_KB_SIZE static LW_BLK_DEV vdisk_dev; static PLW_OEMDISK_CB *vdisk_oemcb; static void *vdisk_start; static int vdisk_read (PLW_BLK_DEV dev, void *buf, int blk_start, int blk_num) { //计算要读取的虚拟磁盘起始位置 void *addr = vdisk_start + blk_start * dev->BLKD_ulBytesPerSector; //读取虚拟磁盘数据 memcpy(buf, addr, blk_num * dev->BLKD_ulBytesPerSector); return (ERROR_NONE); } static int vdisk_write (PLW_BLK_DEV dev, void *buf, int blk_start, int blk_num) { //计算要读取的虚拟磁盘起始位置 void *addr = vdisk_start + blk_start * dev->BLKD_ulBytesPerSector; //写入虚拟磁盘数据 memcpy(addr, buf, blk_num * dev->BLKD_ulBytesPerSector); return (ERROR_NONE); } static int vdisk_ioctl (PLW_BLK_DEV dev, int cmd, long arg) { switch (cmd) { /* * 必须要支持的命令 */ case FIOSYNC: case FIODATASYNC: case FIOSYNCMETA: case FIOFLUSH: /* 将缓存写入磁盘 */ case FIOUNMOUNT: /* 卸载卷 */ case FIODISKINIT: /* 初始化磁盘 */ case FIODISKCHANGE: /* 磁盘媒质发生变化 */ break; case FIOTRIM: /* AHCI_TRIM_EN */ break; /* * 低级格式化 */ case FIODISKFORMAT: /* 格式化卷 */ return (PX_ERROR); /* 不支持低级格式化 */ /* * FatFs 扩展命令 */ case LW_BLKD_CTRL_POWER: case LW_BLKD_CTRL_LOCK: case LW_BLKD_CTRL_EJECT: break; case LW_BLKD_GET_SECSIZE: case LW_BLKD_GET_BLKSIZE: *((LONG *)arg) = (LONG)dev->BLKD_ulBytesPerSector; break; case LW_BLKD_GET_SECNUM: *((ULONG *)arg) = (ULONG)dev->BLKD_ulNSector; break; case FIOWTIMEOUT: case FIORTIMEOUT: break; default: _ErrorHandle(ENOSYS); return (PX_ERROR); } return (ERROR_NONE); } static int vdisk_reset (PLW_BLK_DEV dev) { return (ERROR_NONE); } static int vdisk_status_chk (PLW_BLK_DEV dev) { return (ERROR_NONE); } int module_init (void) { PLW_BLK_DEV pdev = &vdisk_dev; LW_DISKCACHE_ATTR dcattrl; vdisk_start = malloc(VIRTUAL_DISK_SIZE); if (!vdisk_start) { printk("create virtual disk fail.\n"); return (PX_ERROR); } /* * 配置块设备参数 */ pdev->BLKD_pcName = "VirtualDisk"; pdev->BLKD_ulNSector = VIRTUAL_DISK_SIZE / SECTOR_BYTES; pdev->BLKD_ulBytesPerSector = SECTOR_BYTES; pdev->BLKD_ulBytesPerBlock = SECTOR_BYTES; pdev->BLKD_bRemovable = LW_TRUE; pdev->BLKD_iRetry = 1; pdev->BLKD_iFlag = O_RDWR; pdev->BLKD_bDiskChange = LW_TRUE; pdev->BLKD_pfuncBlkRd = vdisk_read; pdev->BLKD_pfuncBlkWrt = vdisk_write; pdev->BLKD_pfuncBlkIoctl = vdisk_ioctl; pdev->BLKD_pfuncBlkReset = vdisk_reset; pdev->BLKD_pfuncBlkStatusChk = vdisk_status_chk; pdev->BLKD_iLogic = 0; pdev->BLKD_uiLinkCounter = 0; pdev->BLKD_pvLink = LW_NULL; pdev->BLKD_uiPowerCounter = 0; pdev->BLKD_uiInitCounter = 0; dcattrl.DCATTR_pvCacheMem = LW_NULL; dcattrl.DCATTR_stMemSize = (size_t)(DISK_CACHE_SIZE); dcattrl.DCATTR_iBurstOpt = LW_DCATTR_BOPT_CACHE_COHERENCE; dcattrl.DCATTR_iMaxRBurstSector = (INT)BUSTOR_SECTOR; dcattrl.DCATTR_iMaxWBurstSector = (INT)BUSTOR_SECTOR; dcattrl.DCATTR_iMsgCount = 4; dcattrl.DCATTR_bParallel = LW_TRUE; dcattrl.DCATTR_iPipeline = 1; vdisk_oemcb = API_OemDiskMount2("/media/vdisk", pdev, &dcattrl); if (!vdisk_oemcb) { printk("oem disk mount fail.\r\n"); free(vdisk_start); return (PX_ERROR); } return (ERROR_NONE); } void module_exit (void) { if (vdisk_oemcb) { API_OemDiskUnmount(vdisk_oemcb); } if (vdisk_start) { free(vdisk_start); } }
2021年1月10日 20:20 1F
没意思去扬州你不去