版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
上章回顧 塊設備驅動程序第7章預習檢查本章目標掌握Linux下塊設備驅動程序的設計方法本章結構塊設備驅動程序block_device_operations結構體
gendisk結構體請求和請求隊列Linux塊設備驅動結構
塊設備驅動注冊與注銷
塊設備的打開與釋放
塊設備的ioctl函數(shù)
塊設備的I/O請求處理
塊設備與字符設備的區(qū)別屬性\類別塊設備字符設備訪問單位/次有固定大小無固定大小隨機訪問(lseek)支持不支持用戶直接訪問不可可以驅動程序復雜相對簡單塊設備驅動程序的特點塊設備接口相對復雜,不如字符設備明晰易用塊設備驅動程序對整個系統(tǒng)的性能影響較大,速度和效率是設計塊設備驅動程要重點考慮的問題系統(tǒng)中使用緩沖區(qū)與訪問請求的優(yōu)化管理(合并與重新排序)來提高系統(tǒng)性能塊設備驅動的實現(xiàn)步驟確定主設備號和次設備號確定設備名稱創(chuàng)建設備文件實現(xiàn)塊設備驅動程序實現(xiàn)block_device_operations結構體實現(xiàn)request(請求)實現(xiàn)初始化函數(shù),注冊塊設備實現(xiàn)銷毀函數(shù),取消塊設備7.1.1block_device_operations結構體structblock_device_operations{ int(*open)(structinode*,structfile*); int(*release)(structinode*,structfile*); int(*ioctl)(structinode*,structfile*,unsigned,unsignedlong); long(*unlocked_ioctl)(structfile*,unsigned,unsignedlong); long(*compat_ioctl)(structfile*,unsigned,unsignedlong); int(*direct_access)(structblock_device*,sector_t,unsignedlong*); int(*media_changed)(structgendisk*); int(*revalidate_disk)(structgendisk*); int(*getgeo)(structblock_device*,structhd_geometry*); structmodule*owner;};7.1.1block_device_operations結構體int(*open)(structinode*,structfile*); int(*release)(structinode*,structfile*); int(*ioctl)(structinode*,structfile*,unsigned,unsignedlong);int(*media_changed)(structgendisk*);與字符設備中對應函數(shù)功能作用相同,當設備被打開或者關閉時調(diào)用它們塊設備層會首先截取大量的標準請求,因此大多數(shù)塊設備的ioctl函數(shù)都十分短小內(nèi)核調(diào)用該函數(shù)以檢查用戶是否更換了驅動器內(nèi)的介質表示一個獨立的磁盤7.1.2gendisk結構體每一個塊設備物理實體由一個gendisk結構體來表示每個gendisk可以支持若干個分區(qū)每個gendisk中包含本物理實體的全部信息及操作函數(shù)接口整個塊設備的注冊過程都是圍繞gendisk來開展的7.1.2gendisk結構體structgendisk{ intmajor; /*majornumberofdriver*/ intfirst_minor; intminors;/*maximumnumberofminors,=1for
disksthatcan'tbepartitioned.*/ chardisk_name[32]; /*nameofmajordriver*/ structhd_struct**part; /*[indexedbyminor]*/
intpart_uevent_suppress; structblock_device_operations*fops; structrequest_queue*queue; void*private_data; sector_tcapacity;
intflags; structdevice*driverfs_dev; structkobjectkobj; structkobject*holder_dir; structkobject*slave_dir; structtimer_rand_state*random; intpolicy; atomic_tsync_io; /*RAID*/ unsignedlongstamp; intin_flight; #ifdef CONFIG_SMP structdisk_stats*dkstats; #else structdisk_statsdkstats; #endif}用于Linux的驅動模型7.1.2gendisk結構體設備號,及設備名
各種設備操作structblock_device_operations*fops; 管理設備I/O請求structrequest_queue*queue;sector_tcapacity以512字節(jié)為一個扇區(qū)時,該驅動器可包含的扇區(qū)數(shù),驅動程序不能直接設置該成員,而要將扇區(qū)數(shù)傳遞給set_capacity
intmajor; /*majornumberofdriver*/ intfirst_minor; intminors;/*maximumnumberofminors,=1for *disksthatcan'tbepartitioned.*/chardisk_name[32]; /*nameofmajordriver*/7.1.2gendisk結構體分配gendisk并初始化向系統(tǒng)注冊卸載gendisk計數(shù)操作get_diskput_diskstructgendisk*alloc_disk(intminors)voiddel_gendisk(structgendisk*disk)voidadd_disk(structgendisk*disk)7.1.3請求與請求隊列request(請求)結構的主要成員
sector_tsector;unsignedlongnr_sectors;unsignedintcurrent_nr_sectors;還沒有傳輸?shù)牡谝粋€扇區(qū)等待傳輸扇區(qū)的總量當前Bio中剩余的扇區(qū)數(shù)structbio*biochar*buffer請求的bio結構鏈表,需要使用rq_for_each_bio訪問sector_tsector;unsignedlongnr_sectors;unsignedintcurrent_nr_sectors;用來查找需要傳輸?shù)木彌_區(qū)7.1.3請求與請求隊列內(nèi)核扇區(qū)和硬件扇區(qū)的轉換內(nèi)核總是認為扇區(qū)大小是512字節(jié),而硬件扇區(qū)卻不都是512字節(jié),所以要相應的轉換。調(diào)用blk_queue_hardsect_size設置硬件扇區(qū)大小將硬件扇區(qū)數(shù)轉換成內(nèi)核扇區(qū)數(shù)sectors=nsectors*(hardsect_size/KERNEL_SECTOR_SIZE);nsecotrs:硬件實際的扇區(qū)數(shù);hardsect_size:硬件扇區(qū)大?。籏ERNEL_SECTOR_SIZE:內(nèi)核扇區(qū)大小512字節(jié);sectors:對應于內(nèi)核扇區(qū)大小的扇區(qū)總數(shù)通過set_capacity()可以設置硬件存儲器的實際容量set_capacity(structgendisk*gd,sector_tsectors);blk_queue_hardsect_size(request_queue_t*queue,unsignedshortmax);7.1.3請求與請求隊列請求隊列(request_queue)塊設備的請求隊列指包含塊設備I/O請求的序列。創(chuàng)建和初始化請求隊列的函數(shù)是:釋放和刪除請求隊列返回下一個需要處理的請求指針
將請求從隊列中刪除request_queue_t*blk_init_queue(request_fn_proc*request,spinlock_t*lock);voidblk_cleanup_queue(request_queue_t*);structrequest*elv_next_request(request_queue_t*queue);voidblkdev_dequeue_request(structrequest*req);7.17.1.3request與bio結構體
請求隊列(request_queue)將刪除的請求再次加入到隊列設置請求參數(shù)voidelv_requeue_request(request_queue_t*queue,structrequest*req);voidblk_queue_max_sectors(request_queue_t*queue,
unsignedshortmax);voidblk_queue_max_phys_segments(request_queue_t*queue, unsignedshortmax);voidblk_queue_max_hw_segments(request_queue_t*queue, unsignedshortmax);voidblk_queue_max_segment_size(request_queue_t*queue, unsignedintmax);voidblk_queue_hardsect_size(request_queue_t*queue, unsignedshortmax);7.2塊設備驅動的注冊與注銷塊設備驅動注冊函數(shù)塊設備驅動注銷函數(shù)intregister_blkdev(unsignedintmajor,constchar*name); intunregister_blkdev(unsignedintmajor,constchar*name);7.2塊設備驅動的注冊與注銷塊設備驅動初始化函數(shù)主要工作分配、初始化請求隊列,綁定請求隊列和請求函數(shù)分配、初始化gendisk,給gendisk的major、fops、 queue等成員賦值,最后添加gendisk。注冊塊設備驅動。7.2塊設備驅動的注冊與注銷staticint__initxxx_init(void){ //塊設備驅動注冊 if(register_blkdev(XXX_MAJOR,“xxx”)) { err=-EIO; gotoout; }
//請求隊列初始化xxx_queue=blk_init_queue(xxx_request, xxx_lock); if(!xxx_queue) { gotoout_queue; } //硬件扇區(qū)尺寸設置
blk_queue_hardsect_size(xxx_queue, xxx_blocksize);
//gendisk初始化 xxx_disks->major=XXX_MAJOR; xxx_disks->first_minor=0; xxx_disks->fops=&xxx_op; xxx_disks->queue=xxx_queue; sprintf(xxx_disks->disk_name, “xxx%d”,i);
set_capacity(xxx_disks,xxx_size*2); add_disk(xxx_disks);//添加gendisk return0;out_queue:unregister_blkdev(XXX_MAJOR, “xxx”);out:put_disk(xxx_disks); blk_cleanup_queue(xxx_queue);
return–ENOMEM;}7.2塊設備驅動的注冊與注銷
塊設備驅動退出函數(shù)主要工作清除請求隊列;刪除gendisk和對gendisk的引用;刪除對塊設備的引用,注銷塊設備驅動;7.2塊設備驅動的注冊與注銷staticvoid__exitxxx_exit(void)
{
if(bdev)
{
invalidate_bdev(xxx_bdev,1); blkdev_put(xxx_bdev);
}
del_gendisk(xxx_disks);//刪除gendisk
put_disk(xxx_disk);
blk_cleanup_queue(xxx_queue);//清除請求隊列
unregister_blkdev(XXX_MAJOR,“xxx”);
}7.3塊設備的打開與釋放塊設備驅動的open()和release()函數(shù)并非是必須的.open()函數(shù)模板release()函數(shù)模板
staticintxxx_open(structinode*inode,structfile*filp){ structxxx_dev*dev=inode->i_bdev->bd_disk->private_data; filp->private_data=dev;//賦值file的private_data … return0;}staticintxxx_release(structinode*inode,structfile*filp){ structxxx_dev*dev=inode->i_bdev->bd_disk->private_data; … return0;}7.4塊設備的ioctl函數(shù)實際上在一個現(xiàn)代塊設備驅動程序中,許多ioctl命令根本就不用實現(xiàn)?;蛑恍鑼崿F(xiàn)很少部分。intxxx_ioctl(structinode*inode,structfile*filp unsignedintcmd,unsignedlongarg){ longsize;
structhd_geometrygeo;
structxxx_dev*dev=filp->private_data; switch(cmd){ caseHDIO_GETGEO: size=dev->size*(hardsect_size/KERNEL_SECTOR_SIZE);
geo.cylinders=(size&~0x3f)>>6;
geo.heads=4;
geo.sectors=16;
geo.start=4;
if(copy_to_user((void__user*)arg,&geo,sizeof(geo))) return-EFAULT;
return0;
} return-ENOTTY;/*未知命令*/}即使塊設備沒有磁道和柱面,通常也要模擬提供這些信息,主要是為了讓fdisk等工具可以在設備上工作7.5塊設備的I/O請求處理塊設備驅動對塊設備進行讀、寫主要通過request來實現(xiàn)。
塊設備驅動請求函數(shù)的原型為: voidrequest(request_queue_t*queue);塊設備驅動程序處理請求的過程請求處理開始獲取當前請求合法讀/寫請求結束否是寫操作讀操作讀寫7.5塊設備的I/O請求處理 1staticvoidxxx_request(request_queue_t*q) 2{ 3 structrequest*req; 4 while((req=elv_next_request(q))!=NULL) 5 { 6 structxxx_dev*dev=req->rq_disk->private_data; 7 if(!blk_fs_request(req))//判斷是否是文件系統(tǒng)請求? 8 { 9 printk(KERN_NOTICE“Skipnon-fsrequest\n”); 10 end_request(req,0);//通知請求處理失敗 11 continue; 12 } 13 xxx_transfer(dev,req->sector,req->current_nr_sectors, 14 req->buffer,rq_data_dir(req));//處理這個請求 15 end_request(req,1);//通知成功完成這個請求 16 } 17}
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 欽北區(qū)2023-2024年部編版九年級上學期語文期中試卷
- 九年級上學期語文期中考試卷
- 第三中學八年級上學期語文第二次質量檢測試卷
- 結構加固合同范本(2篇)
- 《數(shù)學物理方法》第5章測試題
- 南京航空航天大學《單片微控制器原理及應用》2022-2023學年期末試卷
- 南京工業(yè)大學浦江學院《商業(yè)銀行經(jīng)營與管理》2023-2024學年第一學期期末試卷
- 分式的約分說課稿
- 噸的認識說課稿
- 南京工業(yè)大學浦江學院《管理學原理》2023-2024學年第一學期期末試卷
- 2024年抗菌藥物業(yè)務學習培訓課件
- 護理操作中法律風險防控
- GB 30253-2024永磁同步電動機能效限定值及能效等級
- 合肥市2023-2024學年七年級上學期期中語文考試卷
- 中核集團在線測評多少道題
- 公共衛(wèi)生與預防醫(yī)學繼續(xù)教育平臺“大學習”活動線上培訓欄目題及答案
- 語文第13課《紀念白求恩》課件-2024-2025學年統(tǒng)編版語文七年級上冊
- 人教版(2024新版)七年級上冊英語 Unit 1 You and Me 單元測試卷(含答案解析)
- 人教版(2024)七年級上冊生物全冊教學設計
- 2024-2030年真空鍍膜行業(yè)經(jīng)營效益分析及投資價值戰(zhàn)略規(guī)劃研究報告
- 11 對人有禮貌 教學設計-2024-2025學年道德與法治一年級上冊統(tǒng)編版
評論
0/150
提交評論