塊設備驅動

    在Linux下,驅動設備有字符設備驅動、塊設備驅動和網絡設備驅動三種,之前學習了字符設備驅動,現在開始學習塊設備驅動。首先來比較看這兩種設備驅動有何不通,爲什麼要分割成不同類型的驅動。舉一個例子說明引入塊設備驅動的必要:

假如按照字符設備一樣的框架去構造驅動,如圖:

wKioL1aLwRGxcuEyAACIYQ7Yglo702.png

則需要頻繁地對存儲設備進行擦除,如果使用另一種框架構思(塊設備思想):

wKiom1aLwVWwNsP0AACnuAbEULA318.png

對比之下,對於這樣的存儲設備,則引入塊設備顯然使得操作的效果大爲提高。由此可知塊設備的特點就是:把請求放入隊列,優化後執行。

字符設備與塊設備I/O操作的區別:

a.塊設備只能按照塊爲單位進行輸入輸出,而字符設備則是以字節爲單位。大多數設備都是字符設備,因爲它們不需要緩衝而且不是以固定塊大小操作。

b.塊設備對應I/O請求有對應的緩衝區,因此它們可以以選擇任意順序來響應,字符設備無需緩衝區且可以直接讀寫。對於存儲設備而言,調整順序十分重要,因爲讀寫連續扇區比分離扇區快。

c.字符設備只能被順序讀寫,而塊設備可以隨機訪問。

    類比於字符設備,在塊設備中,有一個類似於字符設備中file_operations的結構體:block_device_operations;在Linux內核中,使用一個gendisk結構體來表示一個獨立的磁盤設備或分區;在Linux內核中,使用一個queue隊列來管理這個設備的I/O請求。這就是塊設備的大體構架。

    編寫塊設備驅動程序的框架主要爲:

1.用alloc_disk(int minors);來分配gendisk結構體

2.設置gendisk結構體

3.分配/設置queue隊列

4.設置gendisk的其他信息(如:容量)

5.註冊gendisk結構體:add_disk

相關操作函數:

struct gendisk *alloc_disk(int minors);//分配gendisk結構體

void add_disk(struct gendisk *disk);//註冊gendisk結構體

request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock);//分配隊列,rfn爲一個請求處理函數,lock是一個自旋鎖

int register_blkdev(unsigned int major, const char *name);////註冊塊設備,name在註冊驅動後,對應 cat /proc/devices裏的名字

例子:

wKioL1aLxAKjuXY0AADbv6cbuZw417.png

wKiom1aLw33z8PiSAALYJy34v2U445.png

wKioL1aLxCST9-PpAABy1YgnH4w381.png

以上就是塊設備驅動程序的框架。塊設備驅動程序相對於字符設備驅動程序要複雜,但對於像存儲設備這樣的塊設備,這樣的驅動構架可以提高效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章