Linux設備驅動開發(第2版)

[法]約翰·馬迪厄(John Madieu)

  • 出版商: 人民郵電
  • 出版日期: 2025-10-01
  • 售價: $1,019
  • 語言: 簡體中文
  • 頁數: 524
  • ISBN: 7115663858
  • ISBN-13: 9787115663856
  • 相關分類: Linux
  • 下單後立即進貨 (約4週~6週)

  • Linux設備驅動開發(第2版)-preview-1
  • Linux設備驅動開發(第2版)-preview-2
Linux設備驅動開發(第2版)-preview-1

商品描述

本書講解了Linux設備驅動開發的基礎知識以及所用到的開發環境。全書分為17章,內容涵蓋了各種Linux子系統、內存管理、RTC、IIO和IRQ管理等,還講解了DMA和部分設備驅動程序的使用方法。在學完本書之後,讀者將掌握Linux設備驅動開發過程中涉及的各種概念,並可以從零開始為嵌入式設備編寫驅動程序。

閱讀本書需要具備基本的C語言編程能力,且熟悉Linux基本命令。

作者簡介

約翰·馬迪厄是一位生活在法國巴黎的嵌入式Linux及內核工程師。他的主要工作是為物聯網、交通、醫療、能源和軍事等領域的企業開發設備驅動和板級支持包。他是LABCSMART公司的創始人兼首席顧問,該公司專註於提供嵌入式Linux和Linux內核工程方面的培訓和服務。他還是一位開源和嵌入式系統愛好者,相信通過分享知識才能學到

更多。他對拳擊運動充滿熱情,已經專業練習了 6 年,現在仍通過誌願執教的方式延續著這份熱情。

目錄大綱

第 1篇 Linux內核開發基礎

第 1章 內核開發簡介 3

1.1 設置開發環境 3

1.1.1 設置宿主機 4

1.1.2 獲取Linux內核源代碼 7

1.2 配置和構建Linux內核 10

1.2.1 指定編譯選項 10

1.2.2 理解內核配置過程 11

1.2.3 構建Linux內核 15

第 2章 Linux內核模塊的基本概念 17

2.1 模塊概念的介紹 17

2.2 構建Linux內核模塊 21

2.2.1 理解Linux內核構建系統 22

2.2.2 樹外構建 25

2.2.3 樹內構建 27

2.3 處理模塊參數 28

2.4 處理符號導出和模塊依賴 30

2.5 學習Linux內核編程技巧 34

2.5.1 錯誤處理 34

2.5.2 消息打印 38

2.6 總結 40

第3章 處理內核的核心輔助函數 41

3.1 Linux內核加鎖機制和共享資源 41

3.1.1 自旋鎖 42

3.1.2 互斥鎖 46

3.1.3 trylock方法 48

3.2 處理內核等待、睡眠和延遲機制 50

3.2.1 等待隊列 50

3.2.2 內核中的簡單睡眠 54

3.2.3 內核延遲或忙等待 54

3.3 深入理解Linux內核時間管理 55

3.3.1 時鐘源、時鐘事件和節拍設備的概念 55

3.3.2 使用標準內核低精度(low-res)定時器 67

3.3.3 高精度定時器(hrtimer) 73

3.4 實現工作延遲機制 77

3.4.1 軟中斷(softirq) 78

3.4.2 任務微調度(tasklet) 82

3.4.3 工作隊列(workqueue) 86

3.4.4 新一代的工作隊列 90

3.5 內核中斷處理 93

3.6 總結 109

第4章 編寫字符設備驅動程序 110

4.1 主設備號和次設備號的概念 110

4.2 字符設備數據結構介紹 111

4.2.1 設備文件操作介紹 112

4.2.2 內核中文件的表示 114

4.3 創建設備節點 115

4.3.1 設備識別 115

4.3.2 字符設備號的註冊和分配 115

4.3.3 在系統中初始化和註冊字符設備 116

4.4 實現文件操作 119

4.4.1 在內核空間和用戶空間之間交換數據 119

4.4.2 實現打開文件操作 120

4.4.3 實現釋放文件操作 121

4.4.4 實現寫文件操作 122

4.4.5 實現讀取文件操作 124

4.4.6 實現llseek文件操作 126

4.5 總結 135

第 2篇 Linux內核平臺抽象和設備驅動程序

第5章 理解和利用設備樹 139

5.1 設備樹機制的基本概念 139

5.1.1 設備樹命名約定 140

5.1.2 認識別名、標簽、phandle和路徑 141

5.1.3 理解節點和屬性的覆蓋 144

5.1.4 設備樹源代碼和編譯器 145

5.2 如何表示和尋址設備 151

5.2.1 如何處理SPI和I2C設備尋址 152

5.2.2 內存映射設備和設備尋址 153

5.3 處理資源 155

5.3.1 resource結構體 155

5.3.2 提取應用程序的特定數據 158

5.4 總結 162

第6章 設備、驅動程序和平臺抽象簡介 163

6.1 Linux內核平臺抽象和數據結構 163

6.1.1 device結構體 163

6.1.2 device_driver結構體 165

6.1.3 設備/驅動程序匹配和模塊(自動)加載 170

6.1.4 設備聲明—填充設備 172

6.2 設備與驅動程序匹配機制詳解 173

6.3 總結 176

第7章 平臺設備和驅動程序的概念 177

7.1 Linux內核中的平臺核心抽象 178

7.2 處理平臺設備 180

7.2.1 分配和註冊平臺設備 180

7.2.2 在代碼中如何避免分配平臺設備 182

7.2.3 使用平臺資源 183

7.3 平臺驅動程序抽象和架構 188

7.3.1 探測和釋放平臺設備 188

7.3.2 在驅動程序中對它所支持的設備進行配置 189

7.3.3 驅動程序的初始化和註冊 191

7.4 從零開始編寫平臺驅動程序 193

7.5 總結 198

第8章 編寫I2C設備驅動程序 199

8.1 Linux內核中的I2C框架抽象 200

8.1.1 struct i2c_adapter簡介 200

8.1.2 I2C客戶端和驅動程序數據結構 202

8.1.3 I2C通信接口 204

8.2 I2C設備驅動程序抽象和架構 208

8.2.1 探測I2C設備 208

8.2.2 實現i2c_driver.remove回調函數 209

8.2.3 驅動程序的初始化和註冊 210

8.2.4 在驅動程序中配置設備 211

8.2.5 實例化I2C設備 212

8.3 如何避免編寫I2C設備驅動程序 213

8.4 總結 216

第9章 編寫SPI設備驅動程序 217

9.1 Linux內核中的SPI框架抽象 218

9.1.1 struct spi_controller簡介 218

9.1.2 struct spi_device簡介 222

9.1.3 struct spi_driver簡介 224

9.1.4 消息傳輸數據結構 224

9.1.5 訪問SPI設備 227

9.2 SPI設備驅動程序抽象和架構 231

9.2.1 探測SPI設備 231

9.2.2 在驅動程序中提供設備信息 233

9.2.3 實現spi_driver.remove回調函數 234

9.2.4 驅動程序的初始化和註冊 235

9.2.5 實例化SPI設備 236

9.3 如何避免編寫SPI設備驅動程序 237

9.4 總結 242

第3篇 充分發揮硬件的潛力

第 10章 深入理解Linux內核內存分配 245

10.1 Linux內核內存相關術語簡介 245

10.1.1 32位系統中的內核地址空間布局:低端內存和高端內存的概念 247

10.1.2 低端內存的細節 248

10.1.3 理解高端內存 249

10.2 揭開地址轉換和MMU的神秘面紗 255

10.2.1 頁查找和TLB 259

10.2.2 TLB如何運作 260

10.3 內存分配機制及其API 261

10.3.1 頁分配器 262

10.3.2 Slab分配器 263

10.3.3 kmalloc分配器 267

10.3.4 vmalloc分配器 270

10.3.5 關於進程內存分配的幕後短故事 272

10.4 使用I/O內存與硬件通信 274

10.4.1 PIO設備訪問 275

10.4.2 MMIO 設備訪問 276

10.5 內存(重)映射 278

10.5.1 了解kmap()的用法 278

10.5.2 將內核內存映射到用戶空間 280

10.6 總結 286

第 11章 實現DMA支持 287

11.1 設置DMA映射 288

11.1.1 緩存一致性和DMA的概念 288

11.1.2 DMA的內存映射 288

11.1.3 創建一致性DMA映射 290

11.1.4 創建流DMA映射 290

11.1.5 單緩沖區映射 291

11.1.6 分散/聚集映射 292

11.1.7 流DMA映射的隱式和顯式緩存一致性 294

11.2 完成(completion)的概念 295

11.3 DMA引擎API 296

11.3.1 DMA控制器接口簡介 297

11.3.2 處理設備DMA尋址能力 302

11.3.3 請求DMA通道 304

11.3.4 配置DMA通道 305

11.3.5 配置DMA傳輸 307

11.3.6 提交DMA傳輸 308

11.3.7 發出待處理的DMA請求並等待回調通知 309

11.4 綜合實例——單緩沖區的DMA映射 310

11.5 關於循環DMA的說明 317

11.6 了解DMA和設備樹綁定 321

11.7 總結 322

第 12章 內存訪問抽象化——Regmap API簡介:寄存器映射抽象化 323

12.1 初識Regmap 324

12.2 Regmap初始化 329

12.3 使用Regmap寄存器訪問函數 330

12.3.1 批量和多寄存器讀寫函數 331

12.3.2 理解Regmap緩存系統 332

12.4 將所有內容整合在一起—基於Regmap的SPI設備驅動程序示例 334

12.5 從用戶空間利用Regmap 337

12.6 總結 340

第 13章 揭秘內核IRQ框架 341

13.1 中斷的簡要介紹 341

13.2 理解中斷控制器和中斷多路復用 342

13.3 深入研究高級外設IRQ管理 351

13.3.1 了解IRQ及其傳播 353

13.3.2 鏈式IRQ 354

13.4 揭秘per-CPU中斷 355

13.5 總結 359

第 14章 LDM簡介 360

14.1 LDM數據結構簡介 360

14.1.1 總線 361

14.1.2 驅動程序數據結構 367

14.1.3 設備驅動程序註冊 368

14.1.4 設備數據結構 369

14.1.5 設備註冊 370

14.2 深入理解LDM 371

14.2.1 了解kobject結構體 371

14.2.2 了解kobj_type 375

14.2.3 了解kset結構體 376

14.2.4 使用非默認屬性 377

14.2.5 使用二進制屬性 382

14.3 sysfs中的設備模型概述 388

14.3.1 創建設備、驅動程序、總線和類相關屬性 389

14.3.2 使sysfs屬性poll和select兼容 394

14.4 總結 395

第4篇 嵌入式領域內的多種內核子系統

第 15章 深入了解IIO框架 399

15.1 IIO數據結構簡介 401

15.1.1 了解struct iio_dev 401

15.1.2 了解struct iio_info 405

15.1.3 IIO通道的概念 407

15.1.4 區分通道 411

15.1.5 將所有內容整合在一起——編寫一個虛擬IIO驅動程序 413

15.2 集成IIO觸發緩沖區支持 417

15.2.1 IIO觸發器和sysfs(用戶空間) 420

15.2.2 IIO緩沖區 424

15.2.3 將所有內容整合在一起 426

15.3 訪問IIO數據 432

15.3.1 單次數據采集 432

15.3.2 訪問數據緩沖區 433

15.4 內核中的IIO消費者接口 436

15.5 編寫用戶空間的IIO應用程序 439

15.5.1 掃描和創建IIO上下文 441

15.5.2 遍歷和管理IIO設備 445

15.5.3 遍歷和管理IIO通道 445

15.5.4 使用觸發器進行工作 447

15.5.5 創建緩沖區並讀取數據樣本 448

15.6 遍歷用戶空間IIO工具 455

15.7 總結 455

第 16章 充分利用引腳控制器和GPIO子系統 456

16.1 硬件術語介紹 456

16.2 引腳控制子系統介紹 458

16.3 利用GPIO控制器接口 464

16.3.1 編寫GPIO控制器驅動程序 468

16.3.2 在GPIO控制器中啟用IRQ芯片 470

16.3.3 在GPIO芯片中添加IRQ芯片支持 474

16.3.4 GPIO控制器綁定方式 477

16.4 充分利用GPIO子系統 482

16.4.1 基於整數的GPIO接口(現已棄用) 483

16.4.2 基於描述符的GPIO接口(推薦方式) 486

16.5 學習如何避免編寫GPIO客戶端驅動程序 494

16.5.1 告別舊的sysfs接口 494

16.5.2 歡迎使用GPIO庫libgpiod 495

16.5.3 GPIO聚合器 504

16.6 總結 509

第 17章 利用Linux內核輸入子系統 510

17.1 Linux內核輸入子系統簡介 510

17.2 分配和註冊輸入設備 513

17.3 使用輪詢輸入設備 514

17.4 生成和報告輸入事件 518

17.5 處理來自用戶空間的輸入設備 520

17.6 總結 524