## 第?16?章?塊驅動
至今, 我們的討論一直限于字符驅動. 但是, 在 Linux 系統中有其他類型的驅動, 并且到時候要開闊我們的視野了. 因此, 本章討論塊驅動.
一個塊驅動提供設備的存取, 這個設備可隨機地以固定大小的塊傳送數據--主要的是, 磁盤驅動. Linux 內核看待塊設備根本上不同于字符設備; 結果, 塊驅動有明顯不同的接口和它們自己的特殊的挑戰.
高效的塊驅動對于性能是重要的 -- 不只是為在用戶應用程序的明確的讀和寫. 現代的有虛擬內存的系統將不需要的數據移向(希望地)二級存儲中, 它常常是一個磁盤驅動器. 塊驅動是核心內存和二級存儲之間的導管; 因此, 它們可組成虛擬內存子系統的一部分. 雖然可能編寫一個塊驅動不必知道 struct page 和其他重要的內存概念, 任何需要編寫一個高性能驅動的人必須使用 15 章所涉及的內容.
許多塊層的設計圍繞性能. 許多字符設備可在它們的最大速率以下運行, 并且系統的總體性能不被影響. 但是如果它的塊 I/O 子系統沒有調整好, 系統不能很好地運行. Linux 塊驅動接口允許你從一個塊設備中獲得最多輸出, 但是有必要, 施加一些你必須處理的復雜性. 好的是, 2.6 的塊接口比之前的內核很大提高.
如你會期望的, 本章的討論集中在一個例子驅動, 它實現了一個面向塊的, 基于內存的設備. 基本上, 它是一個 ramdisk. 內核硬件包含了一個很高級的 ramdisk 實現, 但是我們的驅動(稱為 sbull)讓我們演示創建一個塊驅動, 同時最小化無關的復雜性.
在進入細節之前, 我們精確定義幾個詞語. 一個塊是一個固定大小的數據塊, 大小由內核決定. 塊常常是 4096 字節, 但是這個值可依賴體系和使用的文件系統而變化. 一個扇區, 相反, 是一個小塊, 它的大小常常由底層的硬件決定. 內核期望處理實現 512-字節扇區的設備. 如果你的設備使用不同的大小, 內核調整并且避免產生硬件無法處理的 I/O 請求. 但是, 它值得記住, 任何時候內核給你一個扇區號, 它是工作在一個 512-字節扇區的世界. 如果你使用不同的硬件扇區大小, 你必須相應地調整內核的扇區號. 我們在 sbull 驅動中見如何完成這個.
- Linux設備驅動第三版
- 第 1 章 設備驅動簡介
- 1.1. 驅動程序的角色
- 1.2. 劃分內核
- 1.3. 設備和模塊的分類
- 1.4. 安全問題
- 1.5. 版本編號
- 1.6. 版權條款
- 1.7. 加入內核開發社團
- 1.8. 本書的內容
- 第 2 章 建立和運行模塊
- 2.1. 設置你的測試系統
- 2.2. Hello World 模塊
- 2.3. 內核模塊相比于應用程序
- 2.4. 編譯和加載
- 2.5. 內核符號表
- 2.6. 預備知識
- 2.7. 初始化和關停
- 2.8. 模塊參數
- 2.9. 在用戶空間做
- 2.10. 快速參考
- 第 3 章 字符驅動
- 3.1. scull 的設計
- 3.2. 主次編號
- 3.3. 一些重要數據結構
- 3.4. 字符設備注冊
- 3.5. open 和 release
- 3.6. scull 的內存使用
- 3.7. 讀和寫
- 3.8. 使用新設備
- 3.9. 快速參考
- 第 4 章 調試技術
- 4.1. 內核中的調試支持
- 4.2. 用打印調試
- 4.3. 用查詢來調試
- 4.4. 使用觀察來調試
- 4.5. 調試系統故障
- 4.6. 調試器和相關工具
- 第 5 章 并發和競爭情況
- 5.1. scull 中的缺陷
- 5.2. 并發和它的管理
- 5.3. 旗標和互斥體
- 5.4. Completions 機制
- 5.5. 自旋鎖
- 5.6. 鎖陷阱
- 5.7. 加鎖的各種選擇
- 5.8. 快速參考
- 第 6 章 高級字符驅動操作
- 6.1. ioctl 接口
- 6.2. 阻塞 I/O
- 6.3. poll 和 select
- 6.4. 異步通知
- 6.5. 移位一個設備
- 6.6. 在一個設備文件上的存取控制
- 6.7. 快速參考
- 第 7 章 時間, 延時, 和延后工作
- 7.1. 測量時間流失
- 7.2. 獲知當前時間
- 7.3. 延后執行
- 7.4. 內核定時器
- 7.5. Tasklets 機制
- 7.6. 工作隊列
- 7.7. 快速參考
- 第 8 章 分配內存
- 8.1. kmalloc 的真實故事
- 8.2. 后備緩存
- 8.3. get_free_page 和其友
- 8.4. 每-CPU 的變量
- 8.5. 獲得大量緩沖
- 8.6. 快速參考
- 第 9 章 與硬件通訊
- 9.1. I/O 端口和 I/O 內存
- 9.2. 使用 I/O 端口
- 9.3. 一個 I/O 端口例子
- 9.4. 使用 I/O 內存
- 9.5. 快速參考
- 第 10 章 中斷處理
- 10.1. 準備并口
- 10.2. 安裝一個中斷處理
- 10.3. 前和后半部
- 10.4. 中斷共享
- 10.5. 中斷驅動 I/O
- 10.6. 快速參考
- 第 11 章 內核中的數據類型
- 11.1. 標準 C 類型的使用
- 11.2. 安排一個明確大小給數據項
- 11.3. 接口特定的類型
- 11.4. 其他移植性問題
- 11.5. 鏈表
- 11.6. 快速參考
- 第 12 章 PCI 驅動
- 12.1. PCI 接口
- 12.2. 回顧: ISA
- 12.3. PC/104 和 PC/104+
- 12.4. 其他的 PC 總線
- 12.5. SBus
- 12.6. NuBus 總線
- 12.7. 外部總線
- 12.8. 快速參考
- 第 13 章 USB 驅動
- 13.1. USB 設備基礎知識
- 13.2. USB 和 sysfs
- 13.3. USB 的 Urbs
- 13.4. 編寫一個 USB 驅動
- 13.5. 無 urb 的 USB 傳送
- 13.6. 快速參考
- 第 14 章 Linux 設備模型
- 14.1. Kobjects, Ksets 和 Subsystems
- 14.2. 低級 sysfs 操作
- 14.3. 熱插拔事件產生
- 14.4. 總線, 設備, 和驅動
- 14.5. 類
- 14.6. 集成起來
- 14.7. 熱插拔
- 14.8. 處理固件
- 14.9. 快速參考
- 第 15 章 內存映射和 DMA
- 15.1. Linux 中的內存管理
- 15.2. mmap 設備操作
- 15.3. 進行直接 I/O
- 15.4. 直接內存存取
- 15.5. 快速參考
- 第 16 章 塊驅動
- 16.1. 注冊
- 16.2. 塊設備操作
- 16.3. 請求處理
- 16.4. 一些其他的細節
- 16.5. 快速參考
- 第 17 章 網絡驅動
- 17.1. snull 是如何設計的
- 17.2. 連接到內核
- 17.3. net_device 結構的詳情
- 17.4. 打開與關閉
- 17.5. 報文傳送
- 17.6. 報文接收
- 17.7. 中斷處理
- 17.8. 接收中斷緩解
- 17.9. 連接狀態的改變
- 17.10. Socket 緩存
- 17.11. MAC 地址解析
- 17.12. 定制 ioctl 命令
- 17.13. 統計信息
- 17.14. 多播
- 17.15. 幾個其他細節
- 17.16. 快速參考
- 第 18 章 TTY 驅動
- 18.1. 一個小 TTY 驅動
- 18.2. tty_driver 函數指針
- 18.3. TTY 線路設置
- 18.4. ioctls 函數
- 18.5. TTY 設備的 proc 和 sysfs 處理
- 18.6. tty_driver 結構的細節
- 18.7. tty_operaions 結構的細節
- 18.8. tty_struct 結構的細節
- 18.9. 快速參考