塊裝置驅動程式
<1>.塊裝置和字元裝置的區別
1,讀取資料的單元不同,塊裝置讀寫資料的基本單元式塊,字元裝置的基本單元是位元組。
2,塊裝置可以隨機訪問,字元裝置只能順序訪問。
<2>.linux核心中塊裝置的描述
struct gendisk ;
裝置操作
struct block_device_operations
<3>.裝置註冊
void add_disk(struct gendisk *gd);
<4>.io請求
linux核心中,使用struct request來表示等待處理的塊裝置io請求。
struct request
<5>.請求佇列
請求佇列就是io請求request所形成的佇列。在linux核心中用struct request_queue來描述。
<6>.佇列操作函式
struct request_queue *blk_init_queue(request_fn_proc *rfn,spinlock_t *lock);
初始化請求佇列,一般在模組載入函式中被呼叫。
void blk_cleanup_queue(request_queue *q);
清除請求佇列,完成將請求佇列返回給系統任務,一般在模組解除安裝函式中呼叫。
struct request *elv_next_request(request_queue_t *queue);
返回下乙個要處理的請求,如果沒有請求則返回null。elv_next_request()不會清除請求,仍然把這個請求放到
佇列上,因此,連續呼叫它兩次,會返回同乙個請求結構體。
void blkdev_dequeue_request(struct request *req);從佇列中刪除乙個請求結構體。
<7>.塊裝置驅動測試
insmod ******-blk.ko
ls /dev/simp_blkdev
mkfs.ext3 /dev/simp_blkdev
mkdir -p /mnt/blk
mount
cp /etc/init.d/* /mnt/blk
ls /mnt/blk
umount /mnt/blk
ls /mnt/blk
<8>.bio結構
乙個struct bio代表一次塊裝置的io請求,io排程器可將連續的bio合併成乙個請求struct request。
struct bio
struct bio_vec
在_make_request函式中,使用了io排程器,將多個bio訪問順序進行優化,調整,合併成乙個request,然後提交給使用者
指定的處理函式。然而對於u盤,ramdisk,記憶棒之類的裝置,並不存在磁碟所需要的尋道時間。因此對這樣的裝置而言
乙個io排程器,不但發揮不了作用,而且會浪費很多的記憶體和cpu資源。
解決方法:驅動程式自己實現request_queue所需要的make_request_fn 函式,不使用_make_request函式。
<9>.請求處理的另一種實現方法。
分配請求佇列。
request_queue_t *blk_alloc_queue(int fgp_mask);
對於flash,ram等完全隨機訪問的非機械裝置,並不需要進行複雜的io排程,這個時候應該使用上述函式分配乙個請求佇列。
void blk_queue_make_request(request_queue_t *q,make_request_fn *fn);
繫結請求佇列和製造請求函式
裝置驅動 塊裝置驅動程式
塊裝置驅動程式提供對面向塊的裝置的訪問,這種裝置以隨機訪問的方式傳輸資料,並且資料總是具有固定大小的塊。典型的塊裝置是磁碟驅動器,也有其它型別的塊裝置。塊裝置和字元裝置有很大區別。比如塊裝置上可以掛載檔案系統,字元裝置不可以。這是隨機訪問帶來的優勢,因為檔案系統需要能按塊儲存資料,同時更需要能隨機讀...
塊裝置驅動程式
裝置描述 定義於linux genhd.h struct gendisk 裝置註冊 void add disk struct gendisk gd 裝置操作 字元裝置通過file operations結構來定義它所支援的操作。塊裝置通過struct block device operations結構...
塊裝置驅動程式
1 塊裝置驅動程式的引入 對於塊裝置,不能像字元裝置那樣直接提供讀寫函式 假設 寫扇區0和扇區1 原先是這樣寫扇區0 a.讀出整塊到buffer b.修改buffer裡的扇區0 c.擦除整塊 d.燒寫整塊 原先是這樣寫扇區1 a.讀出整塊到buffer b.修改buffer裡的扇區1 c.擦除整塊 ...