本帖最后由 vsf 于 2018-4-1 13:36 编辑
VSF应用实例--模拟U盘(1)USB设备端协议栈
VSF应用实例--模拟U盘(2)SCSI设备和块设备
VSF应用实例--模拟U盘(3)fakefat32模拟FAT32块设备
之前讲到mal2scsi模块输入一个mal块设备,输出一个scsi设备。这里模拟U盘的话,U盘使用FAT32文件系统,并且,这个文件系统不对应实际的块设备,而是应用一个模拟的FAT32块设备。直接上数据结构:
.mal.fakefat32.sector_size = 512,
.mal.fakefat32.sector_number = 0x00001000,
.mal.fakefat32.sectors_per_cluster = 8,
.mal.fakefat32.volume_id = 0x0CA93E47,
.mal.fakefat32.disk_id = 0x12345678,
.mal.fakefat32.root[0].memfile.file.name= "ROOT",
.mal.fakefat32.root[0].memfile.d.child = (struct vsfile_memfile_t *)usrapp.fakefat32.root_dir,
.mal.mal.drv = &fakefat32_mal_drv,
.mal.mal.param = &usrapp.mal.fakefat32,
这里,对于fakefat32的话,关键参数是sector_size、sector_number、sectors_per_cluster以及root根目录。根目录的数据结构定义了模拟的FAT32磁盘里的目录结构。对于mal块设备的话,参数就支持drv和param,定义了块设备的驱动和参数。后面,就只需要定义根目录结构就可以了:.fakefat32.root_dir =
{
{
.memfile.file.name = "VSFVM",
.memfile.file.attr = VSFILE_ATTR_VOLUMID,
},
{
.memfile.file.name = "ide.py",
.memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_READONLY,
.memfile.file.size = sizeof(usrapp_param.ide.py),
.memfile.file.f.buff = usrapp_param.ide.py,
},
{
.memfile.file.name = "compile",
.memfile.file.size = 1,
.memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_HIDDEN | VSFILE_ATTR_SYSTEM,
.cb.write = usrapp_write_compile,
},
{
.memfile.file.name = "run",
.memfile.file.size = 1,
.memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_HIDDEN | VSFILE_ATTR_SYSTEM,
.cb.write = usrapp_write_run,
},
{
.memfile.file.name = "stop",
.memfile.file.size = 1,
.memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_HIDDEN | VSFILE_ATTR_SYSTEM,
.cb.write = usrapp_write_stop,
},
{
.memfile.file.name = "bytecode.bin",
.memfile.file.size = sizeof(usrapp.vsfvm.token),
.memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_HIDDEN | VSFILE_ATTR_SYSTEM,
.cb.read = usrapp_read_bytecode,
.cb.write = usrapp_write_bytecode,
},
{
.memfile.file.name = "source.txt",
.memfile.file.attr = VSFILE_ATTR_ARCHIVE | VSFILE_ATTR_HIDDEN | VSFILE_ATTR_SYSTEM,
.cb.read = usrapp_read_source,
.cb.write = usrapp_write_source,
},
{
.memfile.file.name = NULL,
},
},
这里就是模拟的U盘里的目录结构,模拟FAT32磁盘的话,根目录第一个都是VOLUMID,在电脑上会显示为磁盘的名字。其他的都是文件或者目录。另外,对于文件的读写操作,用户可以自己定义callback接口(cb.read和cb.write),实现虚拟文件。这里就用compile文件的callback接口举例:
static vsf_err_t usrapp_write_compile(struct vsfsm_pt_t *pt, vsfsm_evt_t evt,
struct fakefat32_file_t *file, uint64_t offset, uint8_t *buff,
uint32_t pagesize)
{
vsfsm_post_evt_pending(&usrapp.vsfvm.sm, USRAPP_EVT_VM_COMPILE);
return VSFERR_NONE;
}
PC上,ide.py界面中,用户单击compile命令后,只是会简单写compile文件,然后,会调用到compile文件的cb.write接口,就是这里的usrapp_write_compile,简单发送事件给虚拟机任务,执行编译操作。同样,run文件也是一样的处理:
static vsf_err_t usrapp_write_run(struct vsfsm_pt_t *pt, vsfsm_evt_t evt,
struct fakefat32_file_t *file, uint64_t offset, uint8_t *buff,
uint32_t pagesize)
{
vsfsm_post_evt_pending(&usrapp.vsfvm.sm, USRAPP_EVT_VM_RUN);
return VSFERR_NONE;
}
fakefat32的结构:
总体模块结构:
另外,fakefat32除了可以提供mal块设备接口还,还可以提供fs文件系统的接口。这样,模拟的FAT32磁盘,可以直接接入到VSF里的文件子系统。
这里,fs_op是文件系统的操作接口,实现的是memfs文件系统,可以链接到vsfile文件子系统。
另外,mal_drv可以通过mim(mal in mal模块),去掉MBR等系统扇区,只保留FAT32相关的扇区,然后通过malfs(块文件系统)里的vsffat(FAT文件系统驱动),接入到vsfile文件子系统。
这些和模拟U盘无关,所以就不介绍了。
|