⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vfifo.c

📁 linux下的字符设备驱动代码
💻 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 + -