《作業系統真象還原》作者鄭鋼,畢業於北京大學,百度運維高級工程師。
本書講解了開發一個作業系統需要的技術和知識,主要內容有:作業系統基礎、部署工作環境、編寫MBR主引導記錄、完善MBR錯誤、保護模式入門、保護模式進階和向核心邁進、中斷、記憶體管理系統、執行緒、輸入輸出系統、用戶進程、完善核心、編寫硬碟驅動程式、檔案系統、系統互動等核心技術。本書適合程式設計師、系統底層開發人員、作業系統愛好者閱讀,也可作為大專院校相關專業師生用書和培訓學校的教材。
基本介紹
- 書名:作業系統真象還原
- 又名:大象書
- 作者:鄭鋼
- 原版名稱:作業系統真象還原
- ISBN:978-7-115-41434-2
- 類別:作業系統
- 頁數:759
- 定價:108元
- 出版社:人民郵電出版社
- 出版時間:2016-03
- 裝幀:簡裝
- 開本:16開
目錄,主要內容,
目錄
著作權
作者簡介
內容提要
前言
第0章 一些你可能正感到迷惑的問題
第1章 部署工作環境
第2章 編寫MBR主引導記錄,讓我們開始 掌權
第3章 完善MBR
第4章 保護模式入門
第5章 保護模式進階,向核心邁進
第6章 完善核心
第7章 中斷
第8章 記憶體管理系統
第9章 執行緒
第10章 輸入輸出系統
第11章 用戶進程
第12章 進一步完善核心
第13章 編寫硬碟驅動程式
第14章 檔案系統
第15章 系統互動
參考文獻
主要內容
第0章 一些你可能正感到迷惑的問題 1
0.1 作業系統是什麼 1
0.2 你想研究到什麼程度 2
0.3 寫作業系統,哪些需要我來做 2
0.4 軟體是如何訪問硬體的 2
0.5 應用程式是什麼,和作業系統是如何配合到一起的 3
0.6 為什麼稱為“陷入”核心 4
0.7 記憶體訪問為什麼要分段 4
0.8 代碼中為什麼分為代碼段、數據段?這和記憶體訪問機制中的段是一回事嗎 6
0.9 物理地址、邏輯地址、有效地址、線性地址、虛擬地址的區別 11
0.10 什麼是段重疊 12
0.11 什麼是平坦模型 12
0.12 cs、ds這類sreg段暫存器,位寬是多少 12
0.13 什麼是工程,什麼是協定 13
0.14 為什麼Linux系統下的應用程式不能在Windows系統下運行 14
0.15 局部變數和函式參數為什麼要放在棧中 14
0.16 為什麼說彙編語言比C語言快 15
0.17 先有的語言,還是先有的編譯器,第1個編譯器是怎么產生的 16
0.18 編譯型程式與解釋型程式的區別 19
0.19 什麼是大端位元組序、小端位元組序 19
0.20 BIOS中斷、DOS中斷、Linux中斷的區別 21
0.21 Section和Segment的區別 25
0.22 什麼是魔數 29
0.23 作業系統是如何識別檔案系統的 30
0.24 如何控制CPU的下一條指令 30
0.25 指令集、體系結構、微架構、程式語言 30
0.26 庫函式是用戶進程與核心的橋樑 33
0.27 轉義字元與ASCII碼 37
0.28 MBR、EBR、DBR和OBR各是什麼 39
第1章 部署工作環境 42
1.1 工欲善其事,必先利其器 42
1.2 我們需要哪些編譯器 42
1.2.1 世界頂級編譯器GCC 42
1.2.2 彙編語言編譯器新貴NASM 43
1.3 作業系統的宿主環境 43
1.3.1 什麼是虛擬機 44
1.3.2 盜夢空間般的開發環境,虛擬機中再裝一個虛擬機 45
1.3.3 virtualBox下載,安裝 46
1.3.4 Linux發行版下載 46
1.3.5 Bochs下載安裝 46
1.4 配置bochs 48
1.5 運行bochs 49
第2章 編寫MBR主引導記錄,讓我們開始掌權 52
2.1 計算機的啟動過程 52
2.2 軟體接力第一棒,BIOS 52
2.2.1 實模式下的1MB記憶體布局 52
2.2.2 BIOS是如何甦醒的 54
2.2.3 為什麼是0x7c00 56
2.3 讓MBR先飛一會兒 58
2.3.1 神奇好用的$和$$,令人迷惑的section 58
2.3.2 NASM簡單用法 60
2.3.3 請下一位選手MBR同學做準備 60
第3章 完善MBR 65
3.1 地址、section、vstart淺嘗輒止 65
3.1.1 什麼是地址 65
3.1.2 什麼是section 67
3.1.3 什麼是vstart 68
3.2 CPU的實模式 70
3.2.1 CPU的工作原理 71
3.2.2 實模式下的暫存器 72
3.2.3 實模式下記憶體分段由來 76
3.2.4 實模式下CPU記憶體定址方式 78
3.2.5 棧到底是什麼玩意兒 81
3.2.6 實模式下的ret 84
3.2.7 實模式下的call 85
3.2.8 實模式下的jmp 92
3.2.9 標誌暫存器flags 97
3.2.10 有條件轉移 99
3.2.11 實模式小結 101
3.3 讓我們直接對顯示器說點什麼吧 101
3.3.1 CPU如何與外設通信—IO接口 101
3.3.2 顯示卡概述 105
3.3.3 顯存、顯示卡、顯示器 106
3.3.4 改進MBR,直接操作顯示卡 110
3.4 bochs調試方法 112
3.4.1 bochs一般用法 113
3.4.2 bochs調試實例 118
3.5 硬碟介紹 122
3.5.1 硬碟發展簡史 122
3.5.2 硬碟工作原理 123
3.5.3 硬碟控制器連線埠 126
3.5.4 常用的硬碟操作方法 128
3.6 讓MBR使用硬碟 129
3.6.1 改造MBR 130
3.6.2 實現核心載入器 134
第4章 保護模式入門 136
4.1 保護模式概述 136
4.1.1 為什麼要有保護模式 136
4.1.2 實模式不是32位CPU,變成了16位 137
4.2 初見保護模式 137
4.2.1 保護模式之暫存器擴展 137
4.2.2 保護模式之定址擴展 140
4.2.3 保護模式之運行模式反轉 141
4.2.4 保護模式之指令擴展 145
4.3 全局描述符表 150
4.3.1 段描述符 150
4.3.2 全局描述符表GDT、局部描述符表LDT及選擇子 155
4.3.3 打開A20地址線 157
4.3.4 保護模式的開關,CR0暫存器的PE位 158
4.3.5 讓我們進入保護模式 158
4.4 處理器微架構簡介 165
4.4.1 流水線 166
4.4.2 亂序執行 168
4.4.3 快取 168
4.4.4 分支預測 169
4.5 使用遠跳轉指令清空流水線,更新段描述符緩衝暫存器 172
4.6 保護模式之記憶體段的保護 173
4.6.1 向段暫存器載入選擇子時的保護 173
4.6.2 代碼段和數據段的保護 174
4.6.3 棧段的保護 175
第5章 保護模式進階,向核心邁進 177
5.1 獲取物理記憶體容量 177
5.1.1 學習Linux獲取記憶體的方法 177
5.1.2 利用BIOS中斷0x15子功能0xe820獲取記憶體 177
5.1.3 利用BIOS中斷0x15子功能0xe801獲取記憶體 179
5.1.4 利用BIOS中斷0x15子功能0x88獲取記憶體 180
5.1.5 實戰記憶體容量檢測 181
5.2 啟用記憶體分頁機制,暢遊虛擬空間 186
5.2.1 記憶體為什麼要分頁 186
5.2.2 一級頁表 188
5.2.3 二級頁表 192
5.2.4 規劃頁表之作業系統與用戶進程的關係 197
5.2.5 啟用分頁機制 198
5.2.6 用虛擬地址訪問頁表 204
5.2.7 快表TLB(Translation LookasideBuffer)簡介 206
5.3 載入核心 207
5.3.1 用C語言寫核心 207
5.3.2 二進制程式的運行方法 211
5.3.3 elf格式的二進制檔案 213
5.3.4 elf檔案實例分析 218
5.3.5 將核心載入記憶體 222
5.4 特權級深入淺出 229
5.4.1 特權級那點事 229
5.4.2 TSS簡介 230
5.4.3 CPL和DPL入門 232
5.4.4 門、調用門與RPL序 235
5.4.5 調用門的過程保護 240
5.4.6 RPL的前世今生 243
5.4.7 IO特權級 248
第6章 完善核心 252
6.1 函式調用約定簡介 252
6.2 彙編語言和C語言混合編程 256
6.2.1 淺析C庫函式與系統調用 256
6.2.2 彙編語言和C語言共同協作 259
6.3 實現自己的列印函式 261
6.3.1 顯示卡的連線埠控制 261
6.3.2 實現單個字元列印 265
6.3.3 實現字元串列印 275
6.3.4 實現整數列印 277
6.4 內聯彙編 281
6.4.1 什麼是內聯彙編 281
6.4.2 彙編語言AT&T語法簡介 281
6.4.3 基本內聯彙編 283
6.4.4 擴展內聯彙編 284
6.4.5 擴展內聯彙編之機器模式簡介 294
第7章 中斷 298
7.1 中斷是什麼,為什麼要有中斷 298
7.2 作業系統是中斷驅動的 299
7.3 中斷分類 299
7.3.1 外部中斷 299
7.3.2 內部中斷 301
7.4 中斷描述符表 304
7.4.1 中斷處理過程及保護 306
7.4.2 中斷髮生時的壓棧 308
7.4.3 中斷錯誤碼 310
7.5 可程式中斷控制器8259A 311
7.5.1 8259A介紹 311
7.5.2 8259A的編程 314
7.6 編寫中斷處理程式 319
7.6.1 從最簡單的中斷處理程式開始 319
7.6.2 改進中斷處理程式 335
7.6.3 調試實戰:處理器進入中斷時壓棧出棧完整過程 339
7.7 可程式計數器/定時器8253簡介 346
7.7.1 時鐘—給設備打拍子 346
7.7.2 8253入門 348
7.7.3 8253控制字 349
7.7.4 8253工作方式 350
7.7.5 8253初始化步驟 353
7.8 提高時鐘中斷的頻率,讓中斷來得更猛烈一些 354
第8章 記憶體管理系統 357
8.1 makefile簡介 357
8.1.1 makefile是什麼 357
8.1.2 makefile基本語法 358
8.1.3 跳到目標處執行 360
8.1.4 偽目標 361
8.1.5 make:遞歸式推導目標 362
8.1.6 自定義變數與系統變數 363
8.1.7 隱含規則 365
8.1.8 自動化變數 366
8.1.9 模式規則 367
8.2 實現assert斷言 367
8.2.1 實現開、關中斷的函式 367
8.2.2 實現ASSERT 370
8.2.3 通過makefile來編譯 372
8.3 實現字元串操作函式 374
8.4 點陣圖bitmap及其函式的實現 377
8.4.1 點陣圖簡介 377
8.4.2 點陣圖的定義與實現 378
8.5 記憶體管理系統 381
8.5.1 記憶體池規劃 381
8.5.2 記憶體管理系統第一步,分配頁記憶體 388
第9章 執行緒 398
9.1 實現核心執行緒 398
9.1.1 執行流 398
9.1.2 執行緒到底是什麼 399
9.1.3 進程與執行緒的關係、區別簡述 402
9.1.4 進程、執行緒的狀態 405
9.1.5 進程的身份證—PCB 405
9.1.6 實現執行緒的兩種方式—核心或用戶進程 406
9.2 在核心空間實現執行緒 409
9.2.1 簡單的PCB及執行緒棧的實現 409
9.2.2 執行緒的實現 413
9.3 核心數據結構,雙向鍊表 417
9.4 多執行緒調度 421
9.4.1 簡單優先權調度的基礎 421
9.4.2 任務調度器和任務切換 425
第10章 輸入輸出系統 439
10.1 同步機制——鎖 439
10.1.1 排查GP異常,理解原子操作 439
10.1.2 找出代碼中的臨界區、互斥、競爭條件 444
10.1.3 信號量 445
10.1.4 執行緒的阻塞與喚醒 447
10.1.5 鎖的實現 449
10.2 用鎖實現終端輸出 452
10.3 從鍵盤獲取輸入 456
10.3.1 鍵盤輸入原理簡介 456
10.3.2 鍵盤掃描碼 457
10.3.3 8042簡介 463
10.3.4 測試鍵盤中斷處理程式 465
10.4 編寫鍵盤驅動 468
10.4.1 轉義字元介紹 468
10.4.2 處理掃描碼 469
10.5 環形輸入緩衝區 476
10.5.1 生產者與消費者問題簡述 476
10.5.2 環形緩衝區的實現 478
10.5.3 添加鍵盤輸入緩衝區 481
10.5.4 生產者與消費者實例測試 482
第11章 用戶進程 485
11.1 為什麼要有任務狀態段TSS 485
11.1.1 多任務的起源,很久很久以前…… 485
11.1.2 LDT簡介 486
11.1.3 TSS的作用 488
11.1.4 CPU原生支持的任務切換方式 492
11.1.5 現代作業系統採用的任務切換方式 495
11.2 定義並初始化TSS 497
11.3 實現用戶進程 501
11.3.1 實現用戶進程的原理 501
11.3.2 用戶進程的虛擬地址空間 501
11.3.3 為進程創建頁表和3特權級棧 502
11.3.4 進入特權級3 505
11.3.5 用戶進程創建的流程 506
11.3.6 實現用戶進程—上 507
11.3.7 bss簡介 513
11.3.8 實現用戶進程—下 515
11.3.9 讓進程跑起來—用戶進程的調度 519
11.3.10 測試用戶進程 520
第12章 進一步完善核心 523
12.1 Linux系統調用淺析 523
12.2 系統調用的實現 527
12.2.1 系統調用實現框架 527
12.2.2 增加0x80號中斷描述符 527
12.2.3 實現系統調用接口 528
12.2.4 增加0x80號中斷處理例程 528
12.2.5 初始化系統調用和實現sys_getpid 530
12.2.6 添加系統調用getpid 531
12.2.7 在用戶進程中的系統調用 532
12.2.8 系統調用之棧傳遞參數 534
12.3 讓用戶進程“說話” 536
12.3.1 可變參數的原理 536
12.3.2 實現系統調用write 538
12.3.3 實現printf 539
12.3.4 完善printf 542
12.4 完善堆記憶體管理 545
12.4.1 malloc底層原理 545
12.4.2 底層初始化 548
12.4.3 實現sys_malloc 550
12.4.4 記憶體的釋放 555
12.4.5 實現sys_free 558
12.4.6 實現系統調用malloc和free 562
第13章 編寫硬碟驅動程式 566
13.1 硬碟及分區表 566
13.1.1 創建從盤及獲取安裝的磁碟數 566
13.1.2 創建磁碟分區表 567
13.1.3 磁碟分區表淺析 571
13.2 編寫硬碟驅動程式 578
13.2.1 硬碟初始化 578
13.2.2 實現thread_yield和idle執行緒 582
13.2.3 實現簡單的休眠函式 584
13.2.4 完善硬碟驅動程式 585
13.2.5 獲取硬碟信息,掃描分區表 590
第14章 檔案系統 595
14.1 檔案系統概念簡介 595
14.1.1 inode、間接塊索引表、檔案控制塊FCB簡介 595
14.1.2 項與簡介 597
14.1.3 超級塊與檔案系統布局 599
14.2 創建檔案系統 601
14.2.1 創建超級塊、i結點、項 601
14.2.2 創建檔案系統 603
14.2.3 掛載分區 609
14.3 檔案描述符簡介 612
14.3.1 檔案描述符原理 612
14.3.2 檔案描述符的實現 614
14.4 檔案操作相關的基礎函式 615
14.4.1 inode操作有關的函式 616
14.4.2 檔案相關的函式 620
14.4.3 相關的函式 623
14.4.4 路徑解析相關的函式 628
14.4.5 實現檔案檢索功能 630
14.5 創建檔案 633
14.5.1 實現file_create 633
14.5.2 實現sys_open 636
14.5.3 在檔案系統上創建第1個檔案 639
14.6 檔案的打開與關閉 640
14.6.1 檔案的打開 640
14.6.2 檔案的關閉 642
14.7 實現檔案寫入 643
14.7.1 實現file_write 643
14.7.2 改進sys_write及write系統調用 648
14.7.3 把數據寫入檔案 650
14.8 讀取檔案 651
14.8.1 實現file_read 651
14.8.2 實現sys_read與功能驗證 653
14.9 實現檔案讀寫指針定位功能 655
14.10 實現檔案刪除功能 657
14.10.1 回收inode 657
14.10.2 刪除項 660
14.10.3 實現sys_unlink與功能驗證 663
14.11 創建 665
14.11.1 實現sys_mkdir創建 666
14.11.2 創建功能驗證 669
14.12 遍歷 671
14.12.1 打開和關閉 671
14.12.2 讀取1個項 673
14.12.3 實現sys_readdir及sys_rewinddir 674
14.13 刪除 676
14.13.1 刪除與判斷空 676
14.13.2 實現sys_rmdir及功能驗證 677
14.14 任務的工作 679
14.14.1 顯示當前工作的原理及基礎代碼 679
14.14.2 實現sys_getcwd 681
14.14.3 實現sys_chdir改變工作 683
14.15 獲得檔案屬性 684
14.15.1 ls命令的幕後功臣 684
14.15.2 實現sys_stat 685
第15章 系統互動 687
15.1 fork的原理與實現 687
15.1.1 什麼是fork 687
15.1.2 fork的實現 689
15.1.3 添加fork系統調用與實現init進程 695
15.2 添加read系統調用,獲取鍵盤輸入 696
15.3 添加putchar、clear系統調用 697
15.4 實現一個簡單的shell 699
15.4.1 shell雛形 699
15.4.2 添加Ctrl+u和Ctrl+l快捷鍵 701
15.4.3 解析鍵入的字元 703
15.4.4 添加系統調用 705
15.4.5 路徑解析轉換 708
15.4.6 實現ls、cd、mkdir、ps、rm等命令 712
15.5 載入用戶進程 717
15.5.1 實現exec 717
15.5.2 讓shell支持外部命令 723
15.5.3 載入硬碟上的用戶程式執行 724
15.5.4 使用戶進程支持參數 727
15.6 實現系統調用wait和exit 731
15.6.1 wait和exit的作用 731
15.6.2 孤兒進程和殭屍進程 732
15.6.3 一些基礎代碼 733
15.6.4 實現wait和exit 737
15.6.5 實現cat命令 741
15.7 管道 745
15.7.1 管道的原理 745
15.7.2 管道的設計 747
15.7.3 管道的實現 748
15.7.4 利用管道實現進程間通信 752
15.7.5 在shell中支持管道 754
參考文獻 760