乾坤合一:Linux裝置驅動之塊裝置驅動

李輝發表於2016-05-12

1. 題外話

在蛻變成蝶的一系列學習當中,我們已經掌握了大部分Linux驅動的知識,在乾坤合一的分享當中,以綜合例項為主要講解,在一個月的蛻繭成蝶的學習探索當中,覺得資料結構,指標,連結串列等等佔據了程式碼的大部分框架,這些都需要我們平時多看程式碼,並且在相關知識點的時候需要在電腦上進行操作,這也讓自己受益匪淺,筆者在這期間受到了幾家IT學院的邀請錄製視訊,當兼職佈道師。但畢竟自己還是個學生,應該潛心學習,爭取更好的做一個IT的人才,所以都沒有接受,這裡很抱歉,並且會更加努力,好好鑽研,希望和大家一起共同進步~

2. 塊裝置與字元裝置I/O口操作異同

2.1 塊裝置只能以塊為單位接受輸入和返回輸出,而字元裝置則以位元組為單位。大多數裝置是字元裝置,因為它們不需要緩衝而且不以固定塊大小進行操作。

2.2 塊裝置對於I/O 請求有對應的緩衝區,因此它們可以選擇以什麼順序進行響應,字元裝置無須緩衝且被直接讀寫。對於儲存裝置而言調 讀寫的順序作用巨大,因為在讀寫連續的扇區比分離的扇區更快。

2.3 字元裝置只能被順序讀寫,而塊裝置可以隨機訪問。雖然塊裝置可隨機訪問,但是對於磁碟這類機械裝置而言,順序地組織塊裝置的訪問可以提高效能。

3. 塊裝置驅動結構

3.1 block_device_operations 結構體

3.2 gendisk 結構體

3.3 gendisk的操作

3.4 request 與bio 結構體

1) 請求

在Linux 塊裝置驅動中,使用request 結構體來表徵等待進行的I/O 請求,request 結構體的主要成員包括(只用於核心塊裝置層):

2) 請求佇列

一個塊請求佇列是一個塊I/O 請求的佇列,請求佇列跟蹤的塊I/O 請求,它儲存用於描述這個裝置能夠支援的請求的型別資訊、它們的最大大小、多少不同的段可進入一個請求、硬體扇區大小、對齊要求等引數,其結果是:如果請求佇列被配置正確了,它不會交給該裝置一個不能處理的請求。

3) 塊I/O

通常一個bio 對應一個I/O 請求,一個請求可以包含多個bio。

3.5  塊裝置驅動註冊與登出

首先註冊她們自己到核心,其函式原型如下

與register_blkdev()對應的登出函式是unregister_blkdev(),其原型為:

4 Linux 塊裝置驅動的模組載入與解除安裝

4.1 需要完成的工作

  • 分配、初始化請求佇列,繫結請求佇列和請求函式。
  • 分配、初始化gendisk,給gendisk 的maj or、fops 、queue 等成員賦值,最後新增gendisk。
  • 註冊塊裝置驅動。

4.2 塊裝置驅動的模組載入函式模板 (使用bl k_a llo c_que ue )

4.3 塊裝置驅動的模組載入函式模板(使用bl k_ i nit_queue )

4.4 在塊裝置的open()函式中賦值private_data

5 塊裝置的I/O請求處理

5.1 使用求情佇列

塊裝置驅動請求函式的原型為:

下面給出了一個更復雜的請求函式,它進行了3 層遍歷:遍歷請求隊 列中的每個請求,遍歷請求中的每個bio,遍歷bio 中的每個段。請求函式遍歷請求、bio 和段如下:

5.2 不適用請求佇列

有些裝置不需要使用請求佇列,其函式原型如下:

在處理處理bio完成後應該使用bio_endio()函式通知處理結束,如下所示:

不管對應的I/O 處理成功與否,“製造請求”函式都應該返回0 。如果“製造請求” 函式返回一個非零值,bio 將被再次提交。下面程式碼所示為一個 “製造請求”函式的例子。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

乾坤合一:Linux裝置驅動之塊裝置驅動 乾坤合一:Linux裝置驅動之塊裝置驅動

相關文章