


版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、作者:日期:linux简单虚拟硬盘驱动分析2012 06-06 16 : 15 122人阅读 评论(0)收藏 举报#inelude linux/init。h># in elude linu x/module。h# in elude <li nu x/ker nel.h># include linux/fs.h# include <linux/errno.h# include linux/types。h># include linux/fentl.h# include linux/vmalloc。h>#include linux/hdreg.h >#in
2、clude linux/blkdev.h ># include <linux/blkpg。h># include asm/uaccess.h># define VHDD_DEV_NAME vhdd”# define VHDD_DEV_MAJOR 220#defi ne VHDD_MAX_DEVICE 2 #define VHDD_MAX_PARTITONS 16 /衣vhdd可以进行分区,允许的分区总共为15个,因此总分区数应为16* /#define VHDD_DEVICE_SIZE(4*1024 衣 1024)/*vhdd ram disk模拟了硬盘,因此要定义相应
3、的内容。扇区大小为512字节,可以任意指定圆柱面(cylinder)书设定为256每个cylinder的扇区数设定为16磁头数(VHDD_HEADS )设为2一台设备容量为(扇区大小*圆柱面数*扇区数 *磁头数),这里=4M,应为disk 提供的大小相一致衣/# define VHDD_SECTOR_SIZE 512#defi ne VHDD_SECTORS 16# define VHDD_HEADS 2#defi ne VHDD_CYLINDERS 256#define VHDD_SECTOR_TOTAL (VHDD_SECTORS 衣 VHDD_HEADS*VHDD_CYLINDERS )
4、# define VHDD_SIZE (VHDD_SECTOR_SIZE 衣 VHDD_SECTOR_TOTAL)typedef structunsigned char * data;struct request_queue * queue;spinlock_t lock;/ *分别管理自己的 lock * /struct gen disk * gd; vhdd_device;/char *vdisk VHDD_MAX_DEVICE = NULL, ;extern char * vdiskVHDD_MAX_DEVICE ;static vhdd_device device VHDD_MAX_D
5、EVICE;/ * vhdd为模拟硬盘的运行,使用内核定时器启动中断(interrupt)。为了使用内核 定时器,定义 了 timer_list结构体变量vhdd_timer。另外,为了处理请求函数的 重入定义了 vhdd_busy变量.该值不为0时,块设备驱动程序的请求处理函数 vhdd_request)就会处于运行状态。这不仅仅是中断的启动方式,也是必要的变 量,因为整体设备会因一个中断而运行* /static struct timer_list vhdd_timer;static int vhdd_busy=0;static void vhdd_request( struct reque
6、st_queue *q)vhdd_device * pdevice;struct request * vhdd_req;char * pData;int size;if (vhdd_busy) return; /*先检查当前块设备是否处于处理请求的状态,如果 处于处理状态,就立即终止函数。这是因为处理中断的过程中还会调用 vhdd_request 函数 */while ( 1)vhdd_req = elv_next_request(q ;if (! vhdd_req) return; /* vhdd_request函数反复执行,知道处理完等待中的所 有请求。使用elv_next_request
7、函数获得处理请求。若处理请求的request结构体地址返回NULL时,表明没有处理请求,因此结束函数*/pdevice = (vhdd_device *) vhdd_reqrq_disk->private_data;pData = pdevice->data + (vhdd_reqsector) * VHDD_SECTOR_SIZE ;/ * vhdd_req->current_nr_sectors包含处理扇区数,如果超出范围,想内核同志出错, 调用end_request(vhdd_req, 0)想内核通知出错,并处理下一个请求*/if (vhdd_req-sector +
8、vhdd_reqcurrent_nr_sectorsget_capacity (vhdd_req-rq_disk)en d_request(vhdd_req 0);con ti nue;size = vhdd_reqcurrent_nr_sectors * VHDD_SECTOR_SIZE;switch (rq_data_dir (vhdd_req)case READ:memcpy(vhdd_req-buffer, pData, size);break;case WRITE:memcpy (pData, vhdd_req >buffer, size);break;default®
9、;nd_request(vhdd_req, 0); continue;/*普通的硬盘在读取数据的时候,先把将要读取的扇区信息传递到硬盘上,并等待 中断。确认发生了中断,并正常处理后,读取硬盘上的数据。相反,在向硬盘上 写入数据时,先要传递写入扇区的信息和数据,再等待中断结束处理后发生中断。 这里使用内核的定时器模拟结束处理的中断.本例子中,vhdd进以简单的ram模拟硬盘,并在vhdd_request处理数据后,使 用内核的定时器模拟结束处理的中断。在使用 vhdd_timer内核定时器时,经一段 时间后,调用作为中断函数的 vhdd_interrupt函数,为了表示块设备驱动程序的 运行状态
10、,把vhdd_busy设为1,然后结束函数。如前所述,该值就是用于忽略数 据处理过程中内核调用的vhdd_request函数*/vhdd_timer。expires = jiffies + 2 ;vhdd_timer。data = ( unsigned long) pdevice;add_timer (& vhdd_timer);vhdd_busy = 1;return;void vhdd_i nterrupt( un sig ned long data)vhdd_device * pdevice;struct request * vhdd_req;pdevice = (vhdd_de
11、vice *) data;vhdd_req = elv_ next_request(pdevice- queue);end_request(vhdd_req 1);vhdd_busy = 0;vhdd_request (pdevice-queue ;int vhdd_open (struct inode * inode, struct file * filp)return 0;int vhdd_release (struct inode *inode struct file * filp)return 0;/ * vhdd模拟硬盘,因此只需要能处理ioctl磁盘结构的HDIO_GETGEO,其
12、余军返 回 ENOTTYHDIO_GETGEO是fdisk等分区处理程序,适用于获取设备的磁盘结构信息的命 令,为了执行该命令,在hd_geometry结构体变量上传递cylinder数,扇区数,head 数及实际扇区的起始值。与2。4内核不同的是,2。6内核中可以直接代如扇区的 起始值,也可以使用get_start_sect函数处理该值.内核源代码中支持的大多数设 备驱动程序都使用get_start_sect处理扇区值。* /int vhddoctl(struct inode * inode, struct file * filp , unsigned int cmd,un sig ned
13、long argint err;struct hd_geometry geo;switch(cmd)case HDIO_GETGEO:err = !access_ok(VERIFY_WRITE, arg, sizeof (geo);if(err) return EFAULT ;geoo cylinders = VHDD_CYLINDERS;geo.heads = VHDD_HEADS;geo.sectors = VHDD_SECTORS;geco start = get_start_sect(inodi_bdev);if (copy_to_user( (void * )arg, &ge
14、o, sizeof(geo) return -EFAULT ;return 0;return ENOTTY;static struct block_device_operatio ns vhdd_fops =。owner = THIS_MODULE,。open = vhdd_open.release = vhdd_release,。ioctl = vhdd_ioctl ,;int vhdd_i nit(void)int lp;/vdisk 0 = vmalloc(VHDD_DEVICE_SIZE );vdisk1 = vmalloc(VHDD_DEVICE_SIZE);memset(vdisk
15、O , 0, VHDD_DEVICE_SIZE);/memset (vdisk1, 0, VHDD_DEVICE_SIZE);/ *使用下面的函数初始化内核定时器结构题vhdd_timer变量后,把由定时器而启动的 vhdd_interrupt()函数注册到 vhdd_timer。function 函数中.vhdd_timer.function()函数用于模拟硬盘的中断* / init_timer (& (vhdd_timer);vhdd_timer.f un cti on = vhdd_i nterrupt;register_blkdev(VHDD_DEV_MAJOR , VHDD_
16、DEV_NAME )for(lp = 0; lp VHDD_MAX_DEVICE; lp+) devicelp.data = vdisk lp ; /*定义此data,使vdisk所获得的内存地址能够用 在request ()函数上* / / *分配gen disk结构体,而gen disk结构体是注册块设备的信息结构体。vhdd共 处理15个分区,因此,变量上代入16。在内核里该值大于2时,确定存在内存分 区,并执行分区处理* / device lp .gd = alloc_disk(VHDD_MAX_PARTITONS);/*使用blk_init_queue函数注册内核和块设备驱动程序的实
17、际输入输出路径 vhdd_request函数,在deviceIp 0queue上设置生成的请求队列.对于 blk_init_queue 函数,除了 request ()函数外,为了管理等待队列的 Lock,需要使用spinlock_t 结构体,因此,下面初始化lock变量,并代如到blk_init_queue函数中* / spinock_init(&device lp .lock);devicelp .queue = blk_init_queue (vhdd_request, &devicelpock);devicelp.gd-major = VHDD_DEV_MAJOR;de
18、vicelp .gd>first_minor = lp * VHDD_MAX_PARTITONS ;devicelp.gd->fops = &vhdd_fops;devicelp.gd-queue = device Ip。queue;device Ip。gd-> private_data = &device Ip;/*为了在proc和sysfs文件系统中表示分区及块设备,在devicelp.gd->disk_name 上分别代入”hdda", ” vhddb,然后使用set_capacity函数设置各台块设备的扇区 数* /sprintf(devicelp.gd- > disk_name,” vhdd%c" ,' a';+lpset_capacity (device lp .gd, VHDD_SECTOR_TOTAL);/*为了检索分区并注册块设备,调用 add_disk ()函数.调用该函数后,内核会在内 核内部注册各台块设备,需要检索分区时,在 gen disk结构体的内部设置分区处 理变量*/add_disk(device lp.gd);return 0; void vhdd_exit (vo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年江西烟草招聘考试真题及答案
- 考点解析人教版八年级上册物理光现象《平面镜成像》定向攻克试题(解析版)
- 2025年道路运输企业主要负责人和安全生产管理人员考试(安全生产管理人员)练习题及答案
- 2025年建筑结构设计与技术施工综合测评试题及答案
- 难点解析人教版八年级物理上册第5章透镜及其应用-5.5显微镜和望远镜专题训练试题(含详解)
- 2025年煤矿企业主要负责人安管能力考试考前模拟试题及答案
- 综合解析人教版八年级上册物理机械运动《运动的描述》综合练习练习题(含答案解析)
- 2025高中从句试题及答案解析
- 考点解析人教版八年级物理上册第5章透镜及其应用-凸透镜成像的规律专项训练练习题
- 综合解析人教版八年级物理《压强》单元测试练习题(含答案详解)
- 2025年材料员考试题库及完整答案(历年真题)
- 品质测量基础知识培训课件
- 贸易安全意识培训课件
- 保温材料安全培训课件
- 颜勤礼碑课件详解
- 2025年年少先队知识竞赛考试真题题库及答案
- 2025-2026学年江苏省镇江市初三上学期数学月考试题【附答案】
- 2025年许昌禹州市特招医学院校毕业生招聘86名备考练习试题及答案解析
- 脑梗阿替普酶溶栓课件
- 激光基础知识培训课件
- DLT5210.1-2021电力建设施工质量验收规程第1部分-土建工程
评论
0/150
提交评论