📄 vfifo.c
字号:
#ifndef __KERNEL__#define __KERNEL__#endif#ifndef MODULE#define MODULE#endif#define __NO_VERSION__#include <linux/init.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/genhd.h>#include <linux/blkdev.h>#include <linux/vmalloc.h>//The struct of the virtual device struct VFIFO_Dev { int size; u8* data; int usernum; //for mutual exclusion spinlock_t lock; struct requset_queue *que; struct gendisk *VFIFOram;};struct VFIFO_Dev Vfifo_Dev;//provide the operation to the device struct block_device_operations vfifo_fops;int major=0;//00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000//register and unregisterstatic int vfifo_init_module(void);static void vfifo_cleanup_module(void);//open and releasestatic int vfifo_open(struct inode *inode, struct file *filp);static int vfifo_release(struct inode *inode, struct file *filp);//read and writestatic void vfifo_read(struct VFIFO_Dev *vf, unsigned long sector, unsigned long nsect, char *buffer);static void vfifo_write(struct VFIFO_Dev *vf, unsigned long sector, unsigned long nsect, char *buffer);//one function to privade some operation for the queuestatic void vfifo_request(request_queue_t *q); //1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111//1//the function of register and unregisterstatic int vfifo_init_module(void){ vfifo_fops.open=&vfifo_open; vfifo_fops.release=&vfifo_release; major=register_blkdev(0,"vfifo"); if(major<=0) { printk(KERN_WARNING "vfifo: can't get major number\n"); return -1; } //apply for a struct struct VFIFO_Dev* vf=&Vfifo_Dev; memset(vf,0,sizeof(struct VFIFO_Dev)); //the size of this application is 1MB vf->size=1024*512; vf->data=vmalloc(vf->size); //fail to apply for that space if(vf->data==NULL) { printk(KERN_NOTICE "Fail to apply for the space! \n"); return -1; } spin_lock_init(&vf->lock); //for the queue vf->que=blk_init_queue(vfifo_request,&vf->lock); //now we make initialization for the gendisk vf->VFIFOram=alloc_disk(1); if(!vf->VFIFOram) { printk(KERN_NOTICE "Fail to alloc_disk!\n"); return -1; } vf->VFIFOram->major=major; vf->VFIFOram->first_minor=major+1; vf->VFIFOram->fops=&vfifo_fops; vf->VFIFOram->queue=vf->que; vf->VFIFOram->private_data=vf; snprintf(vf->VFIFOram->disk_name,32,"VFIF%c",'O'); set_capacity(vf->VFIFOram,1024); add_disk(vf->VFIFOram); printk(KERN_EMERG "The vitual device VFIFO init......\n"); return 0;} static void vfifo_cleanup_module(void){ vfree(Vfifo_Dev.data); del_gendisk(Vfifo_Dev.VFIFOram); unregister_blkdev(major,"vfifo"); printk(KERN_EMERG "VFIFO is leaving...\n"); return;}module_init(vfifo_init_module);module_exit(vfifo_cleanup_module); //2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222//2//open and releasestatic int vfifo_open(struct inode *inode, struct file *filp){ struct VFIFO_Dev *vf=inode->i_bdev->bd_disk->private_data; filp->private_data = vf; //just increase the number of the users spin_lock(&vf->lock); vf->usernum=vf->usernum+1; spin_unlock(&vf->lock); return 0;}static int vfifo_release(struct inode *inode, struct file *filp){ struct VFIFO_Dev *vf=inode->i_bdev->bd_disk->private_data; //just decrease the number of the users spin_lock(&vf->lock); vf->usernum=vf->usernum-1; spin_unlock(&vf->lock); return 0;}//3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333//3//read and writestatic void vfifo_read(struct VFIFO_Dev *vf, unsigned long sector, unsigned long nsect, char *buffer){ unsigned long offset = sector*512; unsigned long nbytes = nsect*512; if((offset+nbytes) > vf->size) { printk(KERN_NOTICE "I'am sorry,it's beyond my size!\n"); return; } printk(KERN_NOTICE "I'am reading...(%ld %ld)\n",offset,nbytes); memcpy(buffer,vf->data+offset,nbytes); return;}static void vfifo_write(struct VFIFO_Dev *vf, unsigned long sector, unsigned long nsect, char *buffer){ unsigned long offset = sector*512; unsigned long nbytes = nsect*512; if((offset+nbytes) > vf->size) { printk(KERN_NOTICE "I'am sorry,it's beyond my size!\n"); return; } printk(KERN_NOTICE "I'am writing...(%ld %ld)\n",offset,nbytes); memcpy(vf->data+offset,buffer,nbytes); return;}//44444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444//one function to privade some operation for the queuestatic void vfifo_request(request_queue_t *q){ struct request *req; //it's over if and only if the queue becomes empty while((req = elv_next_request(q)) != NULL) { struct VFIFO_Dev *vf=req->rq_disk->private_data; printk(KERN_NOTICE "vf_request (%d %p)\n",vf->size,vf->data); if(!blk_fs_request(req)) { printk(KERN_NOTICE "Skip non-fs request!\n"); end_request(req,0); continue; } //it's a write request if(rq_data_dir(req)) { vfifo_write(vf,req->sector,req->current_nr_sectors,req->buffer); } //it's a read request else { vfifo_read(vf,req->sector,req->current_nr_sectors,req->buffer); } end_request(req,1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -