close
LINUX 驅動程式 LDD3
http://www.21cstar.com/dhome/uploadfile/ldd3_html/index.html
簡體版本
目錄
- 1. 第一章 設備驅動簡介
- 1.1. 驅動程式的角色
- 1.2. 劃分核心
- 1.2. 劃分核心
- 1.3. 設備和模組的分類
- 1.4. 安全問題
- 1.5. 版本編號
- 1.6. 版權條款
- 1.7. 加入核心開發社團
- 1.8. 本書的內容
- 2. 建立和執行模組
- 1.4. 安全問題
- 2.1. 設定你的測試系統
- 2.2. Hello World 模組
- 2.3. 核心模組相比於應用程式
- 2.2. Hello World 模組
- 2.3.1. 用戶空間和核心空間
- 2.3.2. 核心的並發
- 2.3.3. 當前進程
- 2.3.4. 幾個別的細節
- 2.4. 編譯和加載
- 2.3.2. 核心的並發
- 2.4.1. 編譯模組
- 2.4.2. 加載和卸載模組
- 2.4.3. 版本倚賴
- 2.4.4. 平台倚賴性
- 2.5. 核心符號表
- 2.6. 預備知識
- 2.7. 初始化和關停
- 2.4.2. 加載和卸載模組
- 2.7.1. 清理函數
- 2.7.2. 初始化中的錯誤處理
- 2.7.3. 模組加載競爭
- 2.8. 模組參數
- 2.9. 在用戶空間做
- 2.10. 快速參考
- 3. 字元驅動
- 2.7.2. 初始化中的錯誤處理
- 3.1. scull 的設計
- 3.2. 主次編號
- 3.2. 主次編號
- 3.2.1. 設備編號的內部表示
- 3.2.2. 分發和釋放設備編號
- 3.2.3. 主編號的動態分發
- 3.3. 一些重要數據架構
- 3.2.2. 分發和釋放設備編號
- 3.3.1. 檔案操作
- 3.3.2. 檔案架構
- 3.3.3. inode 架構
- 3.4. 字元設備註冊
- 3.3.2. 檔案架構
- 3.4.1. scull 中的設備註冊
- 3.4.2. 老方法
- 3.5. open 和 release
- 3.4.2. 老方法
- 3.5.1. open 方法
- 3.5.2. release 方法
- 3.6. scull 的記憶體使用
- 3.7. 讀和寫
- 3.5.2. release 方法
- 3.7.1. read 方法
- 3.7.2. write 方法
- 3.7.3. readv 和 writev
- 3.8. 使用新設備
- 3.9. 快速參考
- 4. 調試技術
- 3.7.2. write 方法
- 4.1. 核心中的調試支援
- 4.2. 用列印調試
- 4.2. 用列印調試
- 4.2.1. printk
- 4.2.2. 重定向控制台消息
- 4.2.3. 消息是如何記錄的
- 4.2.4. 打開和關閉消息
- 4.2.5. 速率限制
- 4.2.6. 列印設備編號
- 4.3. 用查詢來調試
- 4.2.2. 重定向控制台消息
- 4.3.1. 使用 /proc 檔案系統
- 4.3.2. ioctl 方法
- 4.4. 使用觀察來調試
- 4.5. 調試系統故障
- 4.3.2. ioctl 方法
- 4.5.1. oops 消息
- 4.5.2. 系統掛起
- 4.6. 調試器和相關工具
- 4.5.2. 系統掛起
- 4.6.1. 使用 gdb
- 4.6.2. kdb 核心調試器
- 4.6.3. kgdb 補丁
- 4.6.4. 用戶模式 Linux 移植
- 4.6.5. Linux 追蹤工具
- 4.6.6. 動態探針
- 5. 並發和競爭情況
- 4.6.2. kdb 核心調試器
- 5.1. scull 中的缺陷
- 5.2. 並發和它的管理
- 5.3. 旗標和互斥體
- 5.2. 並發和它的管理
- 5.3.1. Linux 旗標實現
- 5.3.2. 在 scull 中使用旗標
- 5.3.3. 讀者/寫者旗標
- 5.4. Completions 機制
- 5.5. 自旋鎖
- 5.3.2. 在 scull 中使用旗標
- 5.5.1. 自旋鎖 API 簡介
- 5.5.2. 自旋鎖和原子上下文
- 5.5.3. 自旋鎖函數
- 5.5.4. 讀者/寫者自旋鎖
- 5.6. 鎖陷阱
- 5.5.2. 自旋鎖和原子上下文
- 5.6.1. 模糊的規則
- 5.6.2. 加鎖順序規則
- 5.6.3. 細 -粗- 粒度加鎖
- 5.7. 加鎖的各種選擇
- 5.6.2. 加鎖順序規則
- 5.7.1. 不加鎖算法
- 5.7.2. 原子變量
- 5.7.3. 位操作
- 5.7.4. seqlock 鎖
- 5.7.5. 讀取-拷貝-更新
- 5.8. 快速參考
- 6. 進階字元驅動操作
- 5.7.2. 原子變量
- 6.1. ioctl 界面
- 6.1.1. 選擇 ioctl 命令
- 6.1.2. 返回值
- 6.1.3. 預定義的命令
- 6.1.4. 使用 ioctl 參數
- 6.1.5. 兼容性和受限操作
- 6.1.6. ioctl 命令的實現
- 6.1.7. 不用 ioctl 的設備控制
- 6.2. 阻塞 I/O
- 6.1.2. 返回值
- 6.2.1. 睡眠的介紹
- 6.2.2. 簡單睡眠
- 6.2.3. 阻塞和非阻塞操作
- 6.2.4. 一個阻塞 I/O 的例子
- 6.2.5. 進階睡眠
- 6.2.6. 測試 scullpipe 驅動
- 6.3. poll 和 select
- 6.2.2. 簡單睡眠
- 6.3.1. 與 read 和 write 的交互
- 6.3.2. 底層的數據架構
- 6.4. 異步通知
- 6.3.2. 底層的數據架構
- 6.5. 移位一個設備
- 6.6. 在一個設備檔案上的存取控制
- 6.6.1. 單 open 設備
- 6.6.2. 一次對一個用戶限制存取
- 6.6.3. 阻塞 open 作為對 EBUSY 的替代
- 6.6.4. 在 open 時複製設備
- 6.7. 快速參考
- 7. 時間, 延時, 和延後工作
- 6.6.2. 一次對一個用戶限制存取
- 7.1. 測量時間流失
- 7.1.1. 使用 jiffies 計數器
- 7.1.2. 處理器特定的暫存器
- 7.2. 獲知當前時間
- 7.3. 延後執行
- 7.1.2. 處理器特定的暫存器
- 7.3.1. 長延時
- 7.3.2. 短延時
- 7.4. 核心定時器
- 7.3.2. 短延時
- 7.4.1. 定時器 API
- 7.4.2. 核心定時器的實現
- 7.5. Tasklets 機制
- 7.6. 工作隊列
- 7.4.2. 核心定時器的實現
- 7.7. 快速參考
- 7.7.1. 時間管理
- 7.7.2. 延遲
- 7.7.3. 核心定時器
- 7.7.4. Tasklets 機制
- 7.7.5. 工作隊列
- 8. 分發記憶體
- 7.7.2. 延遲
- 8.1. kmalloc 的真實故事
- 8.1.1. flags 參數
- 8.1.2. size 參數
- 8.2. 後備緩存
- 8.1.2. size 參數
- 8.2.1. 一個基於 Slab 緩存的 scull: scullc
- 8.2.2. 記憶體池
- 8.3. get_free_page 和其友
- 8.2.2. 記憶體池
- 8.3.1. 一個使用整頁的 scull: scullp
- 8.3.2. alloc_pages 界面
- 8.3.3. vmalloc 和 其友
- 8.3.4. 一個使用虛擬位址的 scull : scullv
- 8.4. 每-CPU 的變量
- 8.5. 獲得大量緩衝
- 8.3.2. alloc_pages 界面
- 8.6. 快速參考
- 9. 與硬體通訊
- 9. 與硬體通訊
- 9.1. I/O 端口和 I/O 記憶體
- 9.2. 使用 I/O 端口
- 9.2.1. I/O 端口分發
- 9.2.2. 操作 I/O 端口
- 9.2.3. 從用戶空間的 I/O 存取
- 9.2.4. 字串操作
- 9.2.5. 暫停 I/O
- 9.2.6. 平台倚賴性
- 9.3. 一個 I/O 端口例子
- 9.2.2. 操作 I/O 端口
- 9.3.1. 並口縱覽
- 9.3.2. 一個例子驅動
- 9.4. 使用 I/O 記憶體
- 9.3.2. 一個例子驅動
- 9.4.1. I/O 記憶體分發和映射
- 9.4.2. 存取 I/O 記憶體
- 9.4.3. 作為 I/O 記憶體的端口
- 9.4.4. 重用 short 為 I/O 記憶體
- 9.4.5. 在 1 MB 之下的 ISA 記憶體
- 9.4.6. isa_readb 和其友
- 9.5. 快速參考
- 10. 中斷處理
- 9.4.2. 存取 I/O 記憶體
- 10.1. 準備並口
- 10.2. 安裝一個中斷處理
- 10.2. 安裝一個中斷處理
- 10.2.1. /proc 界面
- 10.2.2. 自動檢測 IRQ 號
- 10.2.3. 快速和慢速處理
- 10.2.4. 實現一個處理
- 10.2.5. 處理者的參數和返回值
- 10.2.6. 使能和禁止中斷
- 10.3. 前和後半部
- 10.2.2. 自動檢測 IRQ 號
- 10.3.1. Tasklet 實現
- 10.3.2. 工作隊列
- 10.4. 中斷共享
- 10.3.2. 工作隊列
- 10.4.1. 安裝一個共享的處理者
- 10.4.2. 執行處理者
- 10.4.3. /proc 界面和共享中斷
- 10.5. 中斷驅動 I/O
- 10.4.2. 執行處理者
- 10.6. 快速參考
- 11. 核心中的數據類型
- 11. 核心中的數據類型
- 11.1. 標準 C 類型的使用
- 11.2. 安排一個明確大小給數據項
- 11.3. 界面特定的類型
- 11.4. 其他移植性問題
- 11.2. 安排一個明確大小給數據項
- 11.4.1. 時間間隔
- 11.4.2. 頁大小
- 11.4.3. 位元組序
- 11.4.4. 數據對齊
- 11.4.5. 指標和錯誤值
- 11.5. 連結表
- 11.6. 快速參考
- 12. PCI 驅動
- 11.4.2. 頁大小
- 12.1. PCI 界面
- 12.1.1. PCI 尋址
- 12.1.2. 啟動時間
- 12.1.3. 配置暫存器和初始化
- 12.1.4. MODULEDEVICETABLE巨集
- 12.1.5. 註冊一個 PCI 驅動
- 12.1.6. 老式 PCI 探測
- 12.1.7. 使能 PCI 設備
- 12.1.8. 存取配置空間
- 12.1.9. 存取 I/O 和記憶體空間
- 12.1.10. PCI 中斷
- 12.1.11. 硬體抽象
- 12.2. 回顧: ISA
- 12.1.2. 啟動時間
- 12.2.1. 硬體資源
- 12.2.2. ISA 編程
- 12.2.3. 即插即用規範
- 12.3. PC/104 和 PC/104+
- 12.4. 其他的 PC 匯流排
- 12.2.2. ISA 編程
- 12.4.1. MCA 匯流排
- 12.4.2. EISA 匯流排
- 12.4.3. VLB 匯流排
- 12.5. SBus
- 12.6. NuBus 匯流排
- 12.7. 外部匯流排
- 12.8. 快速參考
- 13. USB 驅動
- 12.4.2. EISA 匯流排
- 13.1. USB 設備基礎知識
- 13.1.1. 端點
- 13.1.2. 界面
- 13.1.3. 配置
- 13.2. USB 和 sysfs
- 13.3. USB 的 Urbs
- 13.1.2. 界面
- 13.3.1. 架構 struct urb
- 13.3.2. 建立和銷毀 urb
- 13.3.3. 提交 urb
- 13.3.4. 完成 urb: 完成回調處理者
- 13.3.5. 取消 urb
- 13.4. 編寫一個 USB 驅動
- 13.3.2. 建立和銷毀 urb
- 13.4.1. 驅動支援什麼設備
- 13.4.2. 註冊一個 USB 驅動
- 13.4.3. 提交和控制一個 urb
- 13.5. 無 urb 的 USB 傳送
- 13.4.2. 註冊一個 USB 驅動
- 13.5.1. usb_bulk_msg 界面
- 13.5.2. usb_control_msg 界面
- 13.5.3. 使用 USB 數據函數
- 13.6. 快速參考
- 14. Linux 設備模型
- 13.5.2. usb_control_msg 界面
- 14.1. Kobjects, Ksets 和 Subsystems
- 14.1.1. Kobject 基礎
- 14.1.2. kobject 層次, kset, 和子系統
- 14.2. 低級 sysfs 操作
- 14.1.2. kobject 層次, kset, 和子系統
- 14.2.1. 預設屬性
- 14.2.2. 非預設屬性
- 14.2.3. 二進製屬性
- 14.2.4. 符號連接
- 14.3. 熱插拔事件產生
- 14.2.2. 非預設屬性
- 14.4. 匯流排, 設備, 和驅動
- 14.4.1. 匯流排
- 14.4.2. 設備
- 14.4.3. 設備驅動
- 14.5. 類
- 14.4.2. 設備
- 14.5.1. class_simple 界面
- 14.5.2. 完整的類界面
- 14.6. 集成起來
- 14.5.2. 完整的類界面
- 14.6.1. 添加一個設備
- 14.6.2. 去除一個設備
- 14.6.3. 添加一個驅動
- 14.6.4. 去除一個驅動
- 14.7. 熱插拔
- 14.6.2. 去除一個設備
- 14.7.1. 動態設備
- 14.7.2. /sbin/hotplug 工具
- 14.7.3. 使用 /sbin/hotplug
- 14.8. 處理固件
- 14.7.2. /sbin/hotplug 工具
- 14.8.1. 核心固件界面
- 14.8.2. 它如何工作
- 14.9. 快速參考
- 14.8.2. 它如何工作
- 14.9.1. Kobjects架構
- 14.9.2. sysfs 操作
- 14.9.3. 匯流排, 設備, 和驅動
- 14.9.4. 類
- 14.9.5. 固件
- 15. 記憶體映射和 DMA
- 14.9.2. sysfs 操作
- 15.1. Linux 中的記憶體管理
- 15.1.1. 位址類型
- 15.1.2. 物理位址和頁
- 15.1.3. 高和低記憶體
- 15.1.4. 記憶體映射和 struct page
- 15.1.5. 頁表
- 15.1.6. 虛擬記憶體區
- 15.1.7. 進程記憶體映射
- 15.2. mmap 設備操作
- 15.1.2. 物理位址和頁
- 15.2.1. 使用 remap_pfn_range
- 15.2.2. 一個簡單的實現
- 15.2.3. 添加 VMA 的操作
- 15.2.4. 使用 nopage 映射記憶體
- 15.2.5. 重新映射特定 I/O 區
- 15.2.6. 重新映射 RAM
- 15.2.7. 重映射核心虛擬位址
- 15.3. 進行直接 I/O
- 15.2.2. 一個簡單的實現
- 15.4. 直接記憶體存取
- 15.4.1. 一個 DMA 數據傳輸的概況
- 15.4.2. 分發 DMA 緩衝
- 15.4.3. 匯流排位址
- 15.4.4. 通用 DMA 層
- 15.4.5. ISA 設備的 DMA
- 15.5. 快速參考
- 15.4.2. 分發 DMA 緩衝
- 15.5.1. 介紹性材料
- 15.5.2. 實現 mmap
- 15.5.3. 實現直接 I/O
- 15.5.4. 直接記憶體存取
- 16. 塊驅動
- 15.5.2. 實現 mmap
- 16.1. 註冊
- 16.1.1. 塊驅動註冊
- 16.1.2. 磁片註冊
- 16.1.3. 在 sbull 中的初始化
- 16.1.4. 注意扇區大小
- 16.2. 塊設備操作
- 16.1.2. 磁片註冊
- 16.2.1. open 和 release 方法
- 16.2.2. 支援可移出的介質
- 16.2.3. ioctl 方法
- 16.3. 請求處理
- 16.2.2. 支援可移出的介質
- 16.3.1. 對請求方法的介紹
- 16.3.2. 一個簡單的請求方法
- 16.3.3. 請求隊列
- 16.3.4. 請求的分析
- 16.3.5. 請求完成函數
- 16.4. 一些其他的細節
- 16.3.2. 一個簡單的請求方法
- 16.4.1. 命令預準備
- 16.4.2. 被標識的命令排隊
- 16.5. 快速參考
- 17. 網路驅動
- 16.4.2. 被標識的命令排隊
- 17.1. snull 是如何設計的
- 17.1.1. 分發 IP 號
- 17.1.2. 報文的物理傳送
- 17.2. 連接到核心
- 17.1.2. 報文的物理傳送
- 17.2.1. 設備註冊
- 17.2.2. 初始化每一個設備
- 17.2.3. 模組卸載
- 17.3. net_device 架構的詳情
- 17.2.2. 初始化每一個設備
- 17.3.1. 全域訊息
- 17.3.2. 硬體訊息
- 17.3.3. 界面訊息
- 17.3.4. 設備方法
- 17.3.5. 公用成員
- 17.4. 打開與關閉
- 17.5. 報文傳送
- 17.3.2. 硬體訊息
- 17.5.1. 控制發送並發
- 17.5.2. 傳送超時
- 17.5.3. 發散/匯聚 I/O
- 17.6. 報文接收
- 17.7. 中斷處理
- 17.8. 接收中斷緩解
- 17.9. 連接狀態的改變
- 17.10. Socket 緩存
- 17.5.2. 傳送超時
- 17.10.1. 重要成員變量
- 17.10.2. 作用於 socket 緩存的函數
- 17.11. MAC 位址解析
- 17.10.2. 作用於 socket 緩存的函數
- 17.10.1. 重要成員變量
- 17.5.1. 控制發送並發
- 17.3.1. 全域訊息
- 17.2.1. 設備註冊
- 17.1.1. 分發 IP 號
- 17.1. snull 是如何設計的
- 16.4.1. 命令預準備
- 16.3.1. 對請求方法的介紹
- 16.2.1. open 和 release 方法
- 16.1.1. 塊驅動註冊
- 16.1. 註冊
- 15.5.1. 介紹性材料
- 15.4.1. 一個 DMA 數據傳輸的概況
- 15.2.1. 使用 remap_pfn_range
- 15.1.1. 位址類型
- 15.1. Linux 中的記憶體管理
- 14.9.1. Kobjects架構
- 14.8.1. 核心固件界面
- 14.7.1. 動態設備
- 14.6.1. 添加一個設備
- 14.5.1. class_simple 界面
- 14.4.1. 匯流排
- 14.2.1. 預設屬性
- 14.1.1. Kobject 基礎
- 14.1. Kobjects, Ksets 和 Subsystems
- 13.5.1. usb_bulk_msg 界面
- 13.4.1. 驅動支援什麼設備
- 13.3.1. 架構 struct urb
- 13.1.1. 端點
- 13.1. USB 設備基礎知識
- 12.4.1. MCA 匯流排
- 12.2.1. 硬體資源
- 12.1.1. PCI 尋址
- 12.1. PCI 界面
- 11.4.1. 時間間隔
- 11.1. 標準 C 類型的使用
- 10.4.1. 安裝一個共享的處理者
- 10.3.1. Tasklet 實現
- 10.2.1. /proc 界面
- 10.1. 準備並口
- 9.4.1. I/O 記憶體分發和映射
- 9.3.1. 並口縱覽
- 9.2.1. I/O 端口分發
- 9.1. I/O 端口和 I/O 記憶體
- 8.3.1. 一個使用整頁的 scull: scullp
- 8.2.1. 一個基於 Slab 緩存的 scull: scullc
- 8.1.1. flags 參數
- 8.1. kmalloc 的真實故事
- 7.7.1. 時間管理
- 7.4.1. 定時器 API
- 7.3.1. 長延時
- 7.1.1. 使用 jiffies 計數器
- 7.1. 測量時間流失
- 6.6.1. 單 open 設備
- 6.3.1. 與 read 和 write 的交互
- 6.2.1. 睡眠的介紹
- 6.1.1. 選擇 ioctl 命令
- 6.1. ioctl 界面
- 5.7.1. 不加鎖算法
- 5.6.1. 模糊的規則
- 5.5.1. 自旋鎖 API 簡介
- 5.3.1. Linux 旗標實現
- 5.1. scull 中的缺陷
- 4.6.1. 使用 gdb
- 4.5.1. oops 消息
- 4.3.1. 使用 /proc 檔案系統
- 4.2.1. printk
- 4.1. 核心中的調試支援
- 3.7.1. read 方法
- 3.5.1. open 方法
- 3.4.1. scull 中的設備註冊
- 3.3.1. 檔案操作
- 3.2.1. 設備編號的內部表示
- 3.1. scull 的設計
- 2.7.1. 清理函數
- 2.4.1. 編譯模組
- 2.3.1. 用戶空間和核心空間
- 2.1. 設定你的測試系統
- 1.1. 驅動程式的角色
全站熱搜
留言列表