实验七(补充)sbull虚拟的磁盘驱动的编写.doc_第1页
实验七(补充)sbull虚拟的磁盘驱动的编写.doc_第2页
实验七(补充)sbull虚拟的磁盘驱动的编写.doc_第3页
实验七(补充)sbull虚拟的磁盘驱动的编写.doc_第4页
实验七(补充)sbull虚拟的磁盘驱动的编写.doc_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

sbull虚拟的磁盘驱动的编写 分类: EmbeddedARM/DSP. 驱动 2011-11-28 17:24 191人阅读 评论(0) 收藏 举报 原理指导:我们通过vmalloc在内存中开辟一部分空间,作为一个虚拟的磁盘,然后我们以块设备的方式来访问这片内存,例如这个sbull模型。sbull(SimpleBlockUtilityforLoadingLocalities),该驱动程序实现了一个使用系统内存的块设备,从本质上讲,属于一种RAM磁盘驱动程序。字符设备的IO操作则是直接不绕弯的,块设备的IO操作会配对和整合。驱动的任务是处理请求,对于这些请求的排队和整合的工作有IO调度算法处理。所以块设备的核心工作就是:请求处理函数或者是制造请求。Block_devices_operations结构体中没有读写一类的成员函数,而只是包含打开、释放和IO控制等函数。块设备的流程:(1)先把模块模型搭建好MODULE_LICENSE(DualBSD/GPL);staticstructblock_device_operationssbull_ops=.owner=THIS_MODULE,.open =sbull_open,.release =sbull_release,.media_changed=sbull_media_changed,.revalidate_disk=sbull_revalidate,.ioctl =sbull_ioctl,.getgeo =sbull_getgeo,;module_init(sbull_init);module_exit(sbull_exit);(2)定义一个我们用内存虚拟出来的块设备sbull_devstructsbull_devintsize;/*Devicesizeinsectors*/u8*data;/*Thedataarray*/shortusers;/*Howmanyusers*/shortmedia_change;/*Flagamediachange?*/spinlock_tlock;/*Formutualexclusion*/structrequest_queue*queue;/*Thedevicerequestqueue*/structgendisk*gd;/*Thegendiskstructure*/structtimer_listtimer;/*Forsimulatedmediachanges*/;这个设备结构体是我们工作的核心,也许你不知道需要哪些成员,不要紧,还是那句话,编写驱动的时候,需要设备表现出那些性质和功能,相应的添加上就OK了。(3)设备的初始化 sbull_init()一、sbull_major=register_blkdev(sbull_major,sbull);二、Staticstructsbull_dev*Devices=kmalloc(ndevices*sizeof(structsbull_dev),GFP_KERNEL);/在这里可以对Kmalloc的结果判断下,然后进一步处理.三、setup_device()跳到我们设备注册函数中去/初始化函数结束(4)开始注册我们的这个设备setup_device()/安装(注册)一个设备前,一定要保证它被初始化了这些成员都得出初始化好:一、intsize;/*Devicesizeinsectors*/u8*data;/*Thedataarray*/shortusers;/*Howmanyusers*/spinlock_tlock;/*Formutualexclusion*/structrequest_queue*queue;/*Thedevicerequestqueue*/structgendisk*gd;/*Thegendiskstructure*/二、add_disk(dev-gd);/这个重要的注册函数 /函数结束(5)扇区大小、data数组、user、锁lock的初始化:一、dev-size=nsectors*hardsect_size;dev-data=vmalloc(dev-size);spin_lock_init(&dev-lock);二、/dev-queue=blk_alloc_queue(GFP_KERNEL);/RM_NOQUEUE/dev-queue=blk_init_queue(sbull_full_request,&dev-lock);/RM_FULLdev-queue=blk_init_queue(sbull_request,&dev-lock);/RM_SIMPLE(6)告知内核硬件扇区尺寸、和timer模拟的初始化blk_queue_logical_block_size(dev-queue,hardsect_size);init_timer(&dev-timer);dev-timer.data=(unsignedlong)dev;dev-timer.function=sbull_invalidate;gendisk初始化一、初始化gendisk:dev-gd=alloc_disk(SBULL_MINORS);二、初始化gendisk的成员dev-gd-major=sbull_major;dev-gd-first_minor=which*SBULL_MINORS;dev-gd-fops=&sbull_ops;dev-gd-queue=dev-queue;dev-gd-private_data=dev;(7)设置gendisk容量为xxx_size个扇区大小set_capacity(dev-gd,nsectors*(hardsect_size/KERNEL_SECTOR_SIZE);(8)剩下的就是为devices_operation结构体里声明的那些接口进行实现:.open =sbull_open,.release =sbull_release,.media_changed=sbull_media_changed,.revalidate_disk =sbull_revalidate,.ioctl =sbull_ioctl,.getgeo =sbull_getgeo,一、sbull_open(structblock_device*bdev,fmode_tmode)二、sbull_release(structgendisk*bd_disk,fmode_tmode)三、sbull_media_changed(structgendisk*gd)四、sbull_revalidate(structgendisk*gd)五、sbull_invalidate(unsignedlongldev)六、sbull_ioctl(structblock_device*bdev,fmode_tmode,unsignedintcmd,unsignedlongarg)七、sbull_getgeo(structblock_device*bdev,structhd_geometry*geo)以下是代码:cpp view plaincopyprint?1. /*2. *Samplediskdriverfor2.6.35.3. */4. 5. /#include 6. #include 7. #include 8. #include 9. 10. #include 11. #include/*printk()*/ 12. #include/*kmalloc()*/ 13. #include/*everything.*/ 14. #include/*errorcodes*/ 15. #include 16. #include/*size_t*/ 17. #include/*O_ACCMODE*/ 18. #include/*HDIO_GETGEO*/ 19. #include 20. #include 21. #include 22. #include 23. #include/*invalidate_bdev*/ 24. #include 25. 26. MODULE_LICENSE(DualBSD/GPL);27. 28. staticintsbull_major=0;29. module_param(sbull_major,int,0);30. staticinthardsect_size=512;31. module_param(hardsect_size,int,0);32. staticintnsectors=25600;/*Howbigthedriveis*/33. module_param(nsectors,int,0);34. staticintndevices=1;35. module_param(ndevices,int,0);36. 37. /*38. *Thedifferentrequestmodeswecanuse.39. */40. enum41. RM_SIMPLE=0,/*Theextra-simplerequestfunction*/42. RM_FULL=1,/*Thefull-blownversion*/43. RM_NOQUEUE=2,/*Usemake_request*/44. ;45. /staticintrequest_mode=RM_FULL; 46. /staticintrequest_mode=RM_SIMPLE; 47. staticintrequest_mode=RM_NOQUEUE;48. module_param(request_mode,int,0);49. 50. /*51. *Minornumberandpartitionmanagement.52. */53. #defineSBULL_MINORS16 54. #defineMINOR_SHIFT4 55. #defineDEVNUM(kdevnum)(MINOR(kdev_t_to_nr(kdevnum)MINOR_SHIFT 56. 57. /*58. *Wecantweakourhardwaresectorsize,butthekerneltalkstous59. *intermsofsmallsectors,always.60. */61. #defineKERNEL_SECTOR_SIZE512 62. 63. /*64. *Afterthismuchidletime,thedriverwillsimulateamediachange.65. */66. #defineINVALIDATE_DELAY60*HZ 67. 68. /*69. *Theinternalrepresentationofourdevice.70. */71. structsbull_dev72. intsize;/*Devicesizeinsectors*/73. u8*data;/*Thedataarray*/74. shortusers;/*Howmanyusers*/75. shortmedia_change;/*Flagamediachange?*/76. spinlock_tlock;/*Formutualexclusion*/77. structrequest_queue*queue;/*Thedevicerequestqueue*/78. structgendisk*gd;/*Thegendiskstructure*/79. structtimer_listtimer;/*Forsimulatedmediachanges*/80. ;81. 82. staticstructsbull_dev*Devices=NULL;83. 84. /*85. *HandleanI/Orequest.86. */87. staticvoidsbull_transfer(structsbull_dev*dev,unsignedlongsector,88. unsignedlongnsect,char*buffer,intwrite)89. 90. unsignedlongoffset=sector*KERNEL_SECTOR_SIZE;91. unsignedlongnbytes=nsect*KERNEL_SECTOR_SIZE;92. /printk(in%soffset=%dnbytes=%dwrite=%dn,_FUNCTION_,offset,nbytes,write); 93. /buffer10=0; 94. /printk(buffer); 95. /printk(n); 96. if(offset+nbytes)dev-size)97. printk(KERN_NOTICEBeyond-endwrite(%ld%ld)n,offset,nbytes);98. return;99. 100. if(write)101. memcpy(dev-data+offset,buffer,nbytes);102. else103. memcpy(buffer,dev-data+offset,nbytes);104. 105. 106. /*Thesimpleformoftherequestfunction.*/107. 108. staticvoidsbull_request(structrequest_queue*q)109. 110. structrequest*req;111. 112. req=blk_fetch_request(q);113. while(req!=NULL)114. structsbull_dev*dev=req-rq_disk-private_data;115. if(!blk_fs_request(req)116. printk(KERN_NOTICESkipnon-fsrequestn);117. _blk_end_request_all(req,-EIO);118. continue;119. 120. /printk(KERN_NOTICEReqdev%ddir%ldsec%ld,nr%df%lxn, 121. /dev-Devices,rq_data_dir(req), 122. /req-sector,req-current_nr_sectors, 123. /req-flags); 124. /printk(sectors=%dn,req-current_nr_sectors); 125. sbull_transfer(dev,blk_rq_pos(req),blk_rq_cur_sectors(req),126. req-buffer,rq_data_dir(req);127. if(!_blk_end_request_cur(req,0)128. req=NULL;129. 130. 131. 132. 133. 134. /*135. *TransferasingleBIO.136. */137. staticintsbull_xfer_bio(structsbull_dev*dev,structbio*bio)138. 139. inti;140. structbio_vec*bvec;141. sector_tsector=bio-bi_sector;142. 143. /*Doeachsegmentindependently.*/144. bio_for_each_segment(bvec,bio,i)145. char*buffer=_bio_kmap_atomic(bio,i,KM_USER0);146. sbull_transfer(dev,sector,bio_cur_bytes(bio)9,147. buffer,bio_data_dir(bio)=WRITE);148. sector+=bio_cur_bytes(bio)9;149. _bio_kunmap_atomic(bio,KM_USER0);150. 151. return0;/*Alwayssucceed*/152. 153. 154. /*155. *Transferafullrequest.156. */157. staticintsbull_xfer_request(structsbull_dev*dev,structrequest*req)158. 159. structbio*bio;160. intnsect=0;161. 162. _rq_for_each_bio(bio,req)163. sbull_xfer_bio(dev,bio);164. nsect+=bio-bi_size/KERNEL_SECTOR_SIZE;165. 166. returnnsect;167. 168. 169. 170. 171. /*172. *Smarterrequestfunctionthathandlesclustering.*/173. staticvoidsbull_full_request(structrequest_queue*q)174. 175. 176. structrequest*req;177. intnsect;178. structsbull_dev*dev;179. req=blk_fetch_request(q);180. dev=req-rq_disk-private_data;181. while(req!=NULL)182. if(!blk_fs_request(req)183. printk(KERN_NOTICESkipnon-fsrequestn);184. _blk_end_request_all(req,-EIO);185. continue;186. 187. /printk(KERN_NOTICEReqdev%ddir%ldsec%ld,nr%df%lxn, 188. /dev-Devices,rq_data_dir(req), 189. /req-sector,req-current_nr_sectors, 190. /req-flags); 191. /printk(sectors=%dn,req-current_nr_sectors); 192. nsect=sbull_xfer_request(dev,req);193. _blk_end_request(req,0,(nsectqueuedata;206. intstatus;207. 208. status=sbull_xfer_bio(dev,bio);209. /bio_endio(bio,bio-bi_size,status); 210. bio_endio(bio,status);211. return0;212. 213. 214. 215. /*216. *Openandclose.217. */218. 219. staticintsbull_open(structblock_device*bdev,fmode_tmode)220. 221. structsbull_dev*dev=bdev-bd_disk-private_data;222. /printk(fdfjdlksjfdlkjn); 223. del_timer_sync(&dev-timer);224. spin_lock(&dev-lock);225. if(!dev-users)226. check_disk_change(bdev);227. dev-users+;228. spin_unlock(&dev-lock);229. return0;230. 231. 232. staticintsbull_release(structgendisk*bd_disk,fmode_tmode)233. 234. structsbull_dev*dev=bd_disk-private_data;235. 236. spin_lock(&dev-lock);237. dev-users-;238. 239. if(!dev-users)240. dev-timer.expires=jiffies+INVALIDATE_DELAY;241. add_timer(&dev-timer);242. 243. spin_unlock(&dev-lock);244. 245. return0;246. 247. 248. /*249. *Lookfora(simulated)mediachange.250. */251. intsbull_media_changed(structgendisk*gd)252. 253. structsbull_dev*dev=gd-private_data;254. 255. returndev-media_change;256. 257. 258. /*259. *Revalidate.WEDONOTTAKETHELOCKHERE,forfearofdeadlocking260. *withopen.Thatneedstobereevaluated.261. */262. intsbull_revalidate(structgendisk*gd)263. 264. structsbull_dev*dev=gd-private_data;265. 266. if(dev-media_change)267. dev-media_change=0;268. memset(dev-data,0,dev-size);269. 270. return0;271. 272. 273. /*274. *Theinvalidatefunctionrunsoutofthedevicetimer;itsets275. *aflagtosimulatetheremovalofthemedia.276. */277. voidsbull_invalidate(unsignedlongldev)278. 279. structsbull_dev*dev=(structsbull_dev*)ldev;280. 281. spin_lock(&dev-lock);282. if(dev-users|!dev-data)283. printk(KERN_WARNINGsbull:timersanitycheckfailedn);284. else285. dev-media_change=1;286. spin_unlock(&dev-lock);287. 288. 289. /*290. *Theioctl()implementation291. */292. 293. intsbull_ioctl(structblock_device*bdev,fmode_tmode,294. unsignedintcmd,unsignedlongarg)295. 296. return0;297. 298. 299. staticintsbull_getgeo(structblock_device*bdev,structhd_geometry*geo)300. 301. unsignedlongsize;302. structsbull_dev*pdev=bdev-bd_disk-private_data;303. 304. size=pdev-size;305. geo-cylinders=(size&0x3f)6;306. geo-heads=4;307. geo-sectors=16;308. geo-start=0;309. return0;310. 311. 312. 313. /*314. *Thedeviceoperationsstructure.315. */316. staticstructblock_device_operationssbull_ops=317. .owner=THIS_MODULE,318. .open=sbull_open,319. .release=sbull_release,320. .media_changed=sbull_media_changed,321. .revalidate_disk=sbull_revalidate,322. .ioctl=sbull_ioctl,323. .getgeo=sbull_getgeo,324. ;325. 326. 327. /*328. *Setupourinternaldevice.329. */330. staticvoidsetup_device(structsbull_dev*dev,intwhich)331. 332. /*333. *Getsomememory.334. */335. memset(dev,0,sizeof(structsbull_dev);336. dev-size=nsectors*hardsect_size;337. dev-data=vmalloc(dev-size);338. if(dev-data=NULL)339. printk(KERN_NOTICEvmallocfailure.n);340. return;341. 342. spin_lock_init(&dev-lock);343. 344. /*345. *Thetimerwhichinvalidatesthedevice.346. */347. init_timer(&dev-timer);348. dev-timer.data=(unsignedlong)dev;349. dev-timer.function=sbull_invalidate;350. 351. /*352. *TheI/Oqueue,dependingonwhetherweareusingourown353. *make_requestfunctionornot.354. */355. switch(request_mode)356. caseRM_NOQUEUE:357. dev-queue=blk_alloc_queue(GFP_KERNEL);358. if(dev-queue=NULL)359. gotoout_vfree;360. blk_queue_make_request(dev-queue,sbull_make_request);361. break;362. 363. caseRM_FULL:364. dev-queue=blk_init_queue(sbull_full_request,&dev-lock);365. if(dev-queue=NULL)366. gotoout_vfree;367. break;368. 369. default:370. printk(KERN_NOTICEBadrequestmode%d,usingsimplen,request_mode);371. /*fallinto.*/372. 373. caseRM_SIMPLE:374. dev-queue=blk_init_queue(sbull_request,&dev-lock);375. if(dev-queue=NULL)376. gotoout_vfree;377. break;378. 379. /blk_queue_hardsect_size(dev-queue,hardsect_size); 380. blk_queue_logical_block_size(dev-queue,hardsect_size);381. dev-queue-queuedata=dev;382. /*383. *Andthegendiskstructure.384. */385. dev-gd=alloc_disk(SBULL_MINORS);386. if(!dev-gd)387. printk(KERN_NOTICEalloc_diskfailuren);388. gotoout_vfree;389. 390. dev-gd-major=sbull_major;391. dev-gd-first_minor=which*SBULL_MINORS;392. dev-gd-fops=&sbull_ops;393. dev-gd-queue=dev-queue;394. dev-gd-private_d

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论