精通嵌入式 Linux 編程, 3/e Mastering Embedded Linux Programming, 3/e
[美]弗蘭克·瓦斯奎茲 等著 陳會翔 譯
- 出版商: 清華大學
- 出版日期: 2023-06-01
- 定價: $954
- 售價: 8.5 折 $811
- 語言: 簡體中文
- ISBN: 7302635633
- ISBN-13: 9787302635635
-
相關分類:
嵌入式系統、Linux
- 此書翻譯自: Mastering Embedded Linux Programming, 3/e (Paperback)
-
相關翻譯:
精通嵌入式 Linux 程式設計, 3/e (上) (繁中版)
精通嵌入式 Linux 程式設計, 3/e (下) (繁中版)
下單後立即進貨 (約4週~6週)
買這商品的人也買了...
-
$1,350Exploring Raspberry Pi: Interfacing to the Real World with Embedded Linux (Paperback)
-
$380$300 -
$407使用 Raspberry Pi 學習電腦體系結構 (Learning Computer Architecture with Raspberry Pi)
-
$356Linux 系統編程, 2/e
-
$1,470$1,397 -
$390$371 -
$153數據結構與算法
-
$439STM32 自學筆記, 3/e
-
$228$217 -
$602嵌入式 C語言自我修養 — 從芯片、編譯器到操作系統
-
$600$468 -
$2,200$2,090 -
$407用 Python 動手學統計學
-
$620$465 -
$305數據結構與算法(C語言篇)
-
$539$512 -
$1,080$853 -
$602$566 -
$479$455 -
$750$585 -
$450$351 -
$479$455 -
$760細說 Python 編程:從入門到科學計算
-
$700$546 -
$580$435
相關主題
商品描述
《精通嵌入式Linux編程》詳細闡述了與嵌入式Linux開發相關的基本解決方案,主要包括初識嵌入式Linux開發、關於工具鏈、引導加載程序詳解、配置和構建內核、構建根文件系統、選擇構建系統、使用Yocto進行開發、Yocto技術內幕、創建存儲策略、現場更新軟件、連接設備驅動程序、使用分線板進行原型設計、init程序、使用BusyBox runit啟動、管理電源、打包Python程序、瞭解進程和線程、管理內存、使用GDB進行調試、性能分析和跟蹤、實時編程等內容。此外,本書還提供了相應的示例、代碼,以幫助讀者進一步理解相關方案的實現過程。 本書適合作為高等院校電腦及相關專業的教材和教學參考書,也可作為相關開發人員的自學用書和參考手冊。
目錄大綱
目 錄
第1篇 嵌入式Linux的要素
第1章 初識嵌入式Linux開發 3
1.1 選擇Linux的原因 4
1.2 不選擇Linux的原因 5
1.3 找到合適的玩家 5
1.4 穿越項目生命周期 7
1.4.1 篇章內容概述 7
1.4.2 嵌入式Linux的4個基本要素 7
1.5 開源的意義 8
1.5.1 開源和免費有區別 8
1.5.2 開源許可機制 8
1.6 為嵌入式Linux開發選擇硬件 10
1.7 獲取本書所需硬件 11
1.7.1 Raspberry Pi 4 11
1.7.2 BeagleBone Black 12
1.7.3 QEMU 13
1.8 配置開發環境 15
1.9 小結 15
第2章 關於工具鏈 17
2.1 技術要求 17
2.2 工具鏈簡介 18
2.2.1 工具鏈的類型 20
2.2.2 CPU架構 21
2.2.3 選擇C庫 22
2.3 尋找工具鏈 24
2.4 使用crosstool-NG構建工具鏈 26
2.4.1 安裝crosstool-NG 26
2.4.2 為BeagleBone Black構建工具鏈 27
2.4.3 為QEMU構建工具鏈 28
2.5 工具鏈剖析 29
2.5.1 瞭解你的交叉編譯器 30
2.5.2 sysroot、庫和頭文件 31
2.5.3 工具鏈中的其他工具 32
2.5.4 查看C庫的組件 33
2.6 與庫鏈接—靜態和動態鏈接 34
2.6.1 靜態庫 34
2.6.2 共享庫 35
2.6.3 瞭解共享庫版本號 36
2.7 交叉編譯的技巧 37
2.7.1 相對簡單的makefile 38
2.7.2 Autotools 38
2.7.3 編譯示例—SQLite 40
2.7.4 包配置 42
2.7.5 交叉編譯帶來的問題 43
2.7.6 CMake 44
2.8 小結 46
2.9 延伸閱讀 46
第3章 引導加載程序詳解 47
3.1 技術要求 47
3.2 引導加載程序的作用 48
3.3 引導順序 48
3.3.1 階段1—ROM代碼 49
3.3.2 階段2—SPL 51
3.3.3 階段3—TPL 52
3.4 從引導加載程序轉移到內核中 53
3.5 設備樹簡介 54
3.5.1 有關設備樹的基礎知識 54
3.5.2 reg屬性 55
3.5.3 標簽和中斷 56
3.5.4 設備樹包含文件 57
3.5.5 編譯設備樹 59
3.6 U-Boot 60
3.6.1 構建U-Boot 60
3.6.2 安裝U-Boot 62
3.6.3 使用U-Boot 64
3.6.4 環境變量 65
3.6.5 引導鏡像格式 65
3.6.6 加載鏡像 67
3.6.7 引導Linux 69
3.6.8 使用U-Boot腳本自動化引導過程 69
3.6.9 將U-Boot移植到新板上 69
3.6.10 與特定開發板相關的文件 71
3.6.11 配置頭文件 73
3.6.12 構建和測試 74
3.6.13 Falcon模式 75
3.7 小結 76
第4章 配置和構建內核 77
4.1 技術要求 77
4.2 內核的作用 78
4.3 選擇內核 80
4.3.1 內核開發周期 80
4.3.2 穩定和長期支持版本 81
4.3.3 供應商支持 82
4.3.4 許可機制 82
4.4 構建內核 83
4.4.1 獲取源 83
4.4.2 瞭解內核配置—Kconfig 84
4.4.3 使用LOCALVERSION識別內核 88
4.4.4 使用內核模塊的時機 89
4.5 編譯—Kbuild 90
4.5.1 找出要構建的內核目標 90
4.5.2 構建工件 91
4.5.3 編譯設備樹 93
4.5.4 編譯模塊 93
4.5.5 清理內核源 94
4.5.6 為Raspberry Pi 4構建64位內核 94
4.5.7 為BeagleBone Black構建內核 96
4.5.8 為QEMU構建內核 97
4.6 引導內核 97
4.6.1 引導Raspberry Pi 4 97
4.6.2 引導BeagleBone Black 98
4.6.3 引導QEMU 99
4.6.4 內核恐慌 100
4.6.5 早期用戶空間 100
4.6.6 內核消息 101
4.6.7 內核命令行 101
4.7 將Linux移植到新板上 102
4.7.1 新的設備樹 103
4.7.2 設置開發板的兼容屬性 104
4.8 小結 106
4.9 延伸閱讀 107
第5章 構建根文件系統 109
5.1 技術要求 110
5.2 根文件系統中應該包含的東西 110
5.3 目錄佈局 111
5.3.1 暫存目錄 112
5.3.2 POSIX文件訪問權限 113
5.3.3 暫存目錄中的文件所有權權限 115
5.4 根文件系統的程序 115
5.4.1 init程序 115
5.4.2 shell 115
5.4.3 實用程序 116
5.4.4 關於BusyBox 116
5.4.5 構建BusyBox 117
5.4.6 ToyBox—BusyBox的替代品 118
5.5 根文件系統的庫 119
5.5.1 選擇需要的庫 119
5.5.2 通過剝離減小尺寸 120
5.6 設備節點 121
5.7 proc和sysfs文件系統 122
5.7.1 proc和sysfs文件系統的功能 123
5.7.2 掛載文件系統 123
5.7.3 內核模塊 124
5.8 將根文件系統傳輸到目標 124
5.9 創建引導initramfs 125
5.9.1 獨立的initramfs 126
5.9.2 引導initramfs 126
5.9.3 使用QEMU引導 126
5.9.4 引導BeagleBone Black 127
5.9.5 掛載proc 127
5.9.6 將initramfs構建到內核鏡像中 128
5.9.7 使用設備表構建initramfs 129
5.9.8 舊的initrd格式 130
5.10 init程序 130
5.10.1 BusyBox的init程序 131
5.10.2 啟動守護進程 132
5.11 配置用戶賬戶 132
5.11.1 配置賬戶 132
5.11.2 將用戶賬戶添加到根文件系統中 134
5.12 管理設備節點的更好方法 134
5.12.1 使用devtmpfs的示例 135
5.12.2 使用mdev的示例 135
5.12.3 靜態設備節點的優劣 136
5.13 配置網絡 136
5.13.1 BusyBox中的網絡配置 136
5.13.2 glibc的網絡組件 137
5.14 使用設備表創建文件系統鏡像 138
5.14.1 安裝和使用genext2fs工具 138
5.14.2 引導BeagleBone Black 139
5.15 使用NFS掛載根文件系統 140
5.15.1 使用QEMU進行測試 141
5.15.2 使用BeagleBone Black進行測試 142
5.15.3 文件權限問題 142
5.16 使用TFTP加載內核 143
5.17 小結 144
5.18 延伸閱讀 144
第6章 選擇構建系統 145
6.1 技術要求 145
6.2 比較構建系統 146
6.3 分發二進制文件 148
6.4 Buildroot簡介 148
6.4.1 Buildroot的背景知識 149
6.4.2 穩定版本和長期支持版本 149
6.4.3 安裝Buildroot 149
6.4.4 配置Buildroot 150
6.4.5 運行 151
6.4.6 以真實硬件為目標 153
6.4.7 創建自定義BSP 154
6.4.8 U-Boot配置 154
6.4.9 Linux配置 155
6.4.10 構建系統鏡像 157
6.4.11 添加自己的代碼 159
6.4.12 覆蓋層 160
6.4.13 添加包 160
6.4.14 許可合規性 162
6.5 Yocto Project簡介 162
6.5.1 Yocto Project的背景知識 163
6.5.2 穩定版本和支持 164
6.5.3 安裝Yocto Project 165
6.5.4 配置 165
6.5.5 構建 166
6.5.6 運行QEMU目標 167
6.5.7 元層 167
6.5.8 BitBake和配方 170
6.5.9 通過local.conf自定義鏡像 172
6.5.10 編寫鏡像配方 173
6.5.11 創建SDK 174
6.5.12 許可證審核 176
6.6 小結 176
6.7 延伸閱讀 177
第7章 使用Yocto進行開發 179
7.1 技術要求 179
7.2 在現有BSP之上構建鏡像 180
7.2.1 構建現有的BSP 180
7.2.2 控制Wi-Fi 186
7.2.3 控制藍牙 189
7.2.4 添加自定義層 192
7.3 使用devtool捕獲更改 195
7.3.1 開發工作流程 195
7.3.2 創建新配方 197
7.3.3 修改由配方構建的源 198
7.3.4 將配方升級到較新版本 200
7.4 構建自己的發行版 203
7.4.1 推出發行版的合適時機 203
7.4.2 創建一個新的發行層 203
7.4.3 配置發行版 204
7.4.4 向發行版添加更多配方 205
7.4.5 運行時包管理 205
7.5 配置遠程包服務器 207
7.5.1 配置包服務器 207
7.5.2 配置目標客戶端 208
7.6 小結 209
7.7 延伸閱讀 209
第8章 Yocto技術內幕 211
8.1 技術要求 211
8.2 Yocto架構和工作流程分解 212
8.2.1 元數據 214
8.2.2 構建任務 215
8.2.3 鏡像生成 217
8.3 將元數據分層 218
8.4 構建失敗故障排除 220
8.4.1 隔離錯誤 220
8.4.2 檢查和轉儲環境值 221
8.4.3 讀取任務日誌 222
8.4.4 添加更多日誌記錄 222
8.4.5 從devshell中運行命令 223
8.4.6 查看包的依賴關系 224
8.5 瞭解BitBake語法和語義 225
8.5.1 任務 225
8.5.2 依賴項 226
8.5.3 任務間依賴項 226
8.5.4 構建時依賴項 226
8.5.5 運行時依賴項 227
8.5.6 變量 228
8.5.7 賦值和擴展 228
8.5.8 附加和前置 229
8.5.9 覆蓋 229
8.5.10 內聯Python 230
8.5.11 函數 231
8.5.12 shell 231
8.5.13 Python 231
8.5.14 純Python函數 232
8.5.15 BitBake風格的Python函數 232
8.5.16 匿名Python函數 233
8.5.17 RDEPENDS 234
8.6 小結 235
8.7 延伸閱讀 235
第2篇 系統架構和設計決策
第9章 創建存儲策略 239
9.1 技術要求 239
9.2 存儲選項 240
9.2.1 NOR快閃內存 241
9.2.2 NAND快閃內存 241
9.2.3 托管快閃內存 243
9.2.4 多媒體卡和安全數字卡 244
9.2.5 eMMC 245
9.2.6 其他類型的托管快閃內存 245
9.3 從引導加載程序中訪問快閃內存 245
9.3.1 U-Boot和NOR快閃內存 246
9.3.2 U-Boot和NAND快閃內存 246
9.3.3 U-Boot和MMC、SD和eMMC 246
9.4 從Linux中訪問快閃內存 247
9.4.1 內存技術設備子系統 247
9.4.2 MTD分區 248
9.4.3 MTD設備驅動程序 251
9.4.4 MTD字符設備 251
9.4.5 MTD塊設備mtdblock 252
9.4.6 將內核錯誤記錄到MTD上 253
9.4.7 模擬NAND存儲器 253
9.4.8 MMC塊驅動程序 253
9.5 快閃內存文件系統 254
9.5.1 快閃內存轉換層的特點 254
9.5.2 快閃內存轉換層的部署方式 255
9.6 NOR和NAND快閃內存的文件系統 255
9.6.1 JFFS2 256
9.6.2 摘要節點 257
9.6.3 乾凈標記 257
9.6.4 創建JFFS2文件系統 257
9.6.5 YAFFS2 258
9.6.6 創建YAFFS2文件系統 259
9.6.7 UBI和UBIFS 260
9.6.8 UBI 260
9.6.9 UBIFS 263
9.7 托管快閃內存的文件系統 264
9.7.1 Flashbench 265
9.7.2 丟棄和修剪 266
9.7.3 Ext4 267
9.7.4 F2FS 268
9.7.5 FAT16/32 268
9.8 只讀壓縮文件系統 269
9.8.1 SquashFS 269
9.8.2 在NAND快閃內存上使用SquashFS 269
9.9 臨時文件系統 270
9.10 將根文件系統設為只讀 271
9.11 文件系統選擇 272
9.12 小結 273
9.13 延伸閱讀 273
第10章 現場更新軟件 275
10.1 技術要求 275
10.2 啟動更新的方法 276
10.3 更新的內容 276
10.3.1 引導加載程序 277
10.3.2 內核 277
10.3.3 根文件系統 278
10.3.4 系統應用程序 278
10.3.5 與特定設備相關的數據 278
10.3.6 需要更新的組件 279
10.4 有關軟件更新的基礎知識 279
10.4.1 使更新穩定可靠 279
10.4.2 使更新不受故障影響 280
10.4.3 確保更新安全 282
10.5 更新機制的類型 283
10.5.1 對稱鏡像更新 283
10.5.2 非對稱鏡像更新 285
10.5.3 原子文件更新 286
10.6 OTA更新 288
10.7 使用Mender進行本地更新 288
10.7.1 構建Mender客戶端 289
10.7.2 安裝更新 291
10.8 使用Mender進行OTA更新 294
10.8.1 設置更新服務器 294
10.8.2 上傳工件 297
10.8.3 部署更新 299
10.9 使用balena進行本地更新 301
10.9.1 創建一個賬戶 302
10.9.2 創建應用程序 303
10.9.3 添加設備 304
10.9.4 啟用本地模式 306
10.9.5 安裝CLI 307
10.9.6 推送一個項目 309
10.9.7 修改和更新項目 310
10.10 小結 311
第11章 連接設備驅動程序 313
11.1 技術要求 313
11.2 設備驅動程序的作用 314
11.3 字符設備 315
11.4 塊設備 317
11.5 網絡設備 318
11.6 在運行時查找驅動程序 320
11.6.1 從sysfs中獲取信息 322
11.6.2 設備 322
11.6.3 驅動程序 323
11.6.4 塊驅動程序 324
11.7 尋找合適的設備驅動程序 325
11.8 用戶空間中的設備驅動程序 325
11.8.1 通用輸入/輸出接口 326
11.8.2 處理來自GPIO的中斷 327
11.8.3 LED 329
11.8.4 I2C 330
11.8.5 SPI 332
11.9 編寫內核設備驅動程序 333
11.9.1 設計字符設備驅動程序接口 333
11.9.2 對於設備驅動程序的剖析 335
11.9.3 編譯內核模塊 338
11.9.4 加載內核模塊 339
11.10 發現硬件配置 339
11.10.1 設備樹 340
11.10.2 平臺數據 340
11.10.3 將硬件與設備驅動程序鏈接在一起 341
11.11 小結 343
11.12 延伸閱讀 344
第12章 使用分線板進行原型設計 345
12.1 技術要求 345
12.2 將原理圖映射到設備樹的源中 346
12.2.1 閱讀原理圖和數據表 347
12.2.2 在BeagleBone Black上安裝Debian 352
12.2.3 啟用spidev 353
12.2.4 自定義設備樹 359
12.3 使用分線板進行原型設計 367
12.3.1 閉合SPI跳線 368
12.3.2 安裝GNSS天線 370
12.3.3 附加SPI接頭 370
12.3.4 連接SPI跳線 371
12.4 使用邏輯分析儀探測SPI信號 375
12.4.1 連接邏輯分析儀 376
12.4.2 配置Logic 8 377
12.5 通過SPI接收NMEA消息 383
12.6 小結 387
12.7 延伸閱讀 387
第13章 init程序 389
13.1 技術要求 389
13.2 內核引導後的操作 390
13.3 init程序簡介 391
13.4 BusyBox init 392
13.4.1 BusyBox init解析 392
13.4.2 Buildroot init腳本 393
13.5 System V init 393
13.5.1 inittab 395
13.5.2 init.d腳本 397
13.5.3 添加新的守護進程 398
13.5.4 啟動和停止服務 399
13.6 systemd 400
13.6.1 使用Yocto Project和Buildroot構建systemd 400
13.6.2 關於目標、服務和單元 401
13.6.3 單元 401
13.6.4 服務 402
13.6.5 目標 402
13.6.6 systemd引導系統的方式 403
13.6.7 添加自己的服務 404
13.6.8 添加看門狗 405
13.6.9 對嵌入式Linux的影響 406
13.7 小結 406
13.8 延伸閱讀 407
第14章 使用BusyBox runit啟動 409
14.1 技術要求 409
14.2 獲取BusyBox runit 410
14.3 創建服務目錄和文件 416
14.3.1 服務目錄佈局 417
14.3.2 服務配置 418
14.4 服務監督 425
14.4.1 runsv腳本運行的服務 425
14.4.2 控制服務 427
14.5 服務依賴 429
14.5.1 啟動依賴項 429
14.5.2 自定義啟動依賴項 431
14.5.3 簡單總結 431
14.6 專用服務日誌記錄 432
14.6.1 專用日誌記錄器的工作方式 432
14.6.2 向服務中添加專用日誌記錄 433
14.6.3 日誌輪轉 434
14.7 發出服務信號 435
14.8 小結 436
14.9 延伸閱讀 437
第15章 管理電源 439
15.1 技術要求 439
15.2 測量用電量 440
15.3 調整時鐘頻率 443
15.3.1 CPUFreq驅動程序 444
15.3.2 使用CPUFreq 446
15.4 選擇最佳空閑狀態 448
15.4.1 CPUIdle驅動程序 449
15.4.2 無滴答操作 452
15.5 關閉外圍設備 452
15.6 使系統進入休眠狀態 454
15.6.1 電源狀態 454
15.6.2 喚醒事件 455
15.6.3 從實時時鐘定時喚醒 456
15.7 小結 458
15.8 延伸閱讀 458
第3篇 編寫嵌入式應用程序
第16章 打包Python程序 461
16.1 技術要求 461
16.1.1 安裝venv 462
16.1.2 安裝Docker 462
16.2 追溯Python打包的起源 463
16.2.1 distutils 463
16.2.2 setuptools 463
16.2.3 setup.py 464
16.3 使用pip安裝Python包 466
16.3.1 pip和pip3 466
16.3.2 requirements.txt 469
16.4 使用venv管理Python虛擬環境 471
16.4.1 venv 472
16.4.2 創建虛擬環境 473
16.4.3 激活和驗證虛擬環境 473
16.4.4 在虛擬環境中安裝測試庫 474
16.5 使用conda安裝預編譯的二進制文件 475
16.5.1 環境管理 475
16.5.2 驗證根環境 476
16.5.3 創建conda環境 477
16.5.4 包管理 478
16.5.5 導出虛擬環境 479
16.6 使用Docker部署Python應用程序 480
16.6.1 Dockerfile解析 481
16.6.2 構建Docker鏡像 483
16.6.3 運行Docker鏡像 484
16.6.4 提取Docker鏡像 485
16.6.5 發布Docker鏡像 485
16.6.6 刪除Docker容器 486
16.6.7 刪除Docker鏡像 487
16.6.8 Docker應用總結 487
16.7 小結 488
16.8 延伸閱讀 488
第17章 瞭解進程和線程 489
17.1 技術要求 489
17.2 進程和線程的抉擇 490
17.3 進程 492
17.3.1 創建新進程 492
17.3.2 終止進程 493
17.3.3 運行不同的程序 494
17.3.4 守護進程 497
17.3.5 進程間通信 497
17.3.6 基於消息的IPC 498
17.3.7 UNIX套接字 498
17.3.8 FIFO和命名管道 499
17.3.9 POSIX消息隊列 499
17.3.10 基於消息的IPC總結 499
17.3.11 基於共享內存的IPC 500
17.3.12 POSIX共享內存 500
17.4 線程 503
17.4.1 創建一個新線程 503
17.4.2 終止線程 505
17.4.3 用線程編譯程序 505
17.4.4 線程間通信 505
17.4.5 互斥鎖 506
17.4.6 不斷變化的條件 506
17.4.7 進程和線程應用規則 508
17.5 ZeroMQ 509
17.5.1 獲取pyzmq 510
17.5.2 進程之間的消息傳遞 510
17.5.3 進程內的消息傳遞 512
17.6 調度 514
17.6.1 公平與確定性 514
17.6.2 分時策略 515
17.6.3 nice值 516
17.6.4 實時策略 516
17.6.5 選擇策略 517
17.6.6 選擇實時優先級 518
17.7 小結 518
17.8 延伸閱讀 518
第18章 管理內存 521
18.1 技術要求 521
18.2 虛擬內存基礎知識 522
18.3 內核空間內存佈局 523
18.3.1 內核日誌消息分析 523
18.3.2 內核的內存使用情況 524
18.4 用戶空間內存佈局 526
18.5 進程內存映射 528
18.6 交換 529
18.6.1 交換的利弊 529
18.6.2 交換到壓縮內存 530
18.7 使用mmap映射內存 530
18.7.1 使用mmap分配私有內存 531
18.7.2 使用mmap共享內存 531
18.7.3 使用mmap訪問設備內存 532
18.8 應用程序的內存使用情況 532
18.9 每個進程的內存使用情況 533
18.9.1 使用top和ps 534
18.9.2 使用smem 534
18.9.3 其他工具 536
18.10 識別內存泄漏 537
18.10.1 mtrace 537
18.10.2 Valgrind 538
18.11 內存不足 540
18.12 小結 541
18.13 延伸閱讀 542
第4篇 調試和優化性能
第19章 使用GDB進行調試 545
19.1 技術要求 545
19.2 GNU調試器 546
19.3 準備調試 547
19.4 調試應用程序 547
19.4.1 使用gdbserver進行遠程調試 548
19.4.2 設置Yocto Project以進行遠程調試 549
19.4.3 為遠程調試設置Buildroot 550
19.5 啟動調試 550
19.5.1 連接GDB和gdbserver 550
19.5.2 設置sysroot 551
19.5.3 GDB命令文件 553
19.5.4 GDB命令概述 554
19.5.5 運行到斷點 555
19.5.6 用Python擴展GDB 556
19.5.7 構建包含Python支持的GDB 556
19.5.8 使用GDB遠程調試bsdiff 559
19.6 本機調試 560
19.6.1 Yocto Project 560
19.6.2 Buildroot 561
19.7 即時調試 561
19.8 調試分叉和線程 562
19.9 核心文件 562
19.9.1 觀察核心文件 563
19.9.2 使用GDB查看核心文件 564
19.10 GDB用戶界面 565
19.10.1 終端用戶界面 565
19.10.2 數據顯示調試器 566
19.11 Visual Studio Code 567
19.11.1 安裝Visual Studio Code 567
19.11.2 安裝工具鏈 567
19.11.3 安裝CMake 569
19.11.4 創建一個Visual Studio Code項目 569
19.11.5 安裝Visual Studio Code擴展 569
19.11.6 配置CMake 570
19.11.7 配置項目設置 571
19.11.8 配置遠程調試的啟動設置 573
19.12 調試內核代碼 574
19.12.1 使用kgdb調試內核代碼 575
19.12.2 調試會話示例 576
19.12.3 調試早期代碼 577
19.12.4 調試模塊 578
19.12.5 使用kdb調試內核代碼 579
19.12.6 查看內核Oops消息 580
19.12.7 保存Oops消息 583
19.13 小結 584
19.14 延伸閱讀 585
第20章 性能分析和跟蹤 587
20.1 技術要求 588
20.2 觀察者效應 588
20.2.1 關於觀察者效應 588
20.2.2 符號表和編譯標志 589
20.3 開始性能分析 589
20.4 使用top進行性能分析 590
20.5 窮人的性能分析器 591
20.6 perf簡介 592
20.6.1 為perf配置內核 593
20.6.2 使用Yocto Project構建perf 593
20.6.3 使用Buildroot構建perf 594
20.6.4 使用perf進行性能分析 594
20.6.5 調用圖 596
20.6.6 perf annotate 597
20.7 跟蹤事件 598
20.8 Ftrace簡介 599
20.8.1 準備使用Ftrace 599
20.8.2 使用Ftrace 600
20.8.3 動態Ftrace和跟蹤過濾器 602
20.8.4 跟蹤事件 603
20.9 使用LTTng 604
20.9.1 LTTng和Yocto Project 605
20.9.2 LTTng和Buildroot 605
20.9.3 使用LTTng進行內核跟蹤 606
20.10 使用BPF 608
20.10.1 為BPF配置內核 608
20.10.2 使用Buildroot構建BCC工具包 611
20.10.3 使用BPF跟蹤工具 612
20.11 使用Valgrind 615
20.11.1 Callgrind 615
20.11.2 Helgrind 616
20.12 使用strace 616
20.13 小結 619
20.14 延伸閱讀 619
第21章 實時編程 621
21.1 技術要求 621
21.2 關於實時 622
21.3 識別非確定性的來源 624
21.4 瞭解調度延遲 625
21.5 內核搶占 626
21.5.1 實時Linux內核(PREEMPT_RT) 627
21.5.2 線程化中斷處理程序 628
21.6 可搶占內核鎖 630
21.6.1 獲取PREEMPT_RT補丁 631
21.6.2 Yocto Project和PREEMPT_RT 632
21.7 高分辨率定時器 632
21.8 避免頁面錯誤 633
21.9 中斷屏蔽 634
21.10 測量調度延遲 634
21.10.1 cyclictest 635
21.10.2 使用Ftrace 638
21.10.3 結合cyclictest和Ftrace 639
21.11 小結 640
21.12 延伸閱讀 641