UNIX技術內幕

UNIX技術內幕

《UNIX技術內幕》一書,由郝慶豐編著,2010年6月出版。本書詳細闡述作業系統的核心(也包括少量用戶態部分),選擇UNIX第6版的全部核心代碼及少量用戶部分代碼、總計10 000行作為講解對象,由框架到細節、由基礎到高級地進行講述;在此過程中貫穿了作業系統中的各種知識和概念,比如記憶體管理、進程調度、中斷和設備管理以及檔案系統等。本書適用於具有豐富開發經驗的高級軟體工程師,尤其是有志於進行作業系統研究或對作業系統實現感興趣的軟體工程師,也可作為本專科院校計算機及相關專業學生學習作業系統和C語言的參考書。

基本信息

圖書信息

UNIX技術內幕

書名:返璞歸真——UNIX技術內幕

作者:郝慶豐 編著

ISBN 978-7-121-10871-6

出版日期:2010年6月

定價:89.00元(含CD光碟1張)

開本:16開

頁碼:768頁

宣傳語

節選10000行UNIX核心源碼

耳目一新的視角

入木三分的剖析

生動詳盡的圖例

作者實現的執行緒

恰似醍醐灌頂,讓你徹底了解UNIX核心。

內 容 簡 介

作業系統是一種對計算機中各個設備和資源進行管理並給套用軟體提供各種服務的系統軟體,它的實現可分用戶態和核心態兩大部分。一般而言,作業系統的算法和設計的複雜性大多在核心態部分。因此,了解作業系統的核心實現對於了解整個作業系統是非常重要的。

本書內容非常易於讀者理解。選擇UNIX作為講解對象是因為它強大的生命力和套用的廣泛性。在精妙的設計思想下,它具有小巧高效而健壯的核心、豐富的功能、易擴展的架構和良好的開放性。UNIX所定義的很多接口(比如檔案訪問接口)已經成為行業標準。本書在講解時,作者把這10 000行代碼按照不同的功能模組分成不同的章節。每章一般最小以函式為單位,但在講解某個功能或接口時,又會牽涉到很多相關的函式,並其中揭示了很多優秀的設計思想、數據結構和算法。

初級軟體開發人員在閱讀本書時可能會碰到一些困難,但如能堅持研究,它也會是你提高編程水平的一個很好的選擇。

序 一

作業系統作為計算機中核心的系統軟體,直接決定了計算機系統的整體性能。學習作業系統的過程中,理解所有作業系統設計背後的原理是非常重要的,但如果能夠把這些原理和真實的作業系統實現結合起來,則可以更加深刻地理解作業系統的本質所在。

美國貝爾實驗室的丹尼斯·里奇(Dennis Mac Alistair Ritchie)和肯尼思·湯普森(Kenneth lane·Thompson)共同開發的C和UNIX是本領域最重要的成果之一,對整個計算機產業產生了深遠的影響。因此,通過深入分析閱讀UNIX這一經典系統的原始碼實現來學習作業系統是非常有價值的途徑。UNIX 第6版(UNIX V6)是現代各類UNIX作業系統的源頭,它具備了現代作業系統的絕大部分特徵:進程管理和調度、記憶體管理、檔案系統和I/O設備管理等。在此之後,UNIX分為眾多不同流派,但它們基本上都秉承了UNIX V6的設計思想。

作者郝慶豐曾在朗訊、摩托羅拉等公司從事多年的軟體開發工作,參與過多個UNIX及Linux下大型軟體項目的設計和開發,有著數十萬行代碼的開發經驗。基於這些基礎,他編寫了這本講解UNIX的書籍,針對PDP-11處理器,給出UNIX V6近萬行源碼的詳細解析,其中也包含了很多作者自己的開發經驗和理解。在寫作過程中,作者翻閱了大量資料,做了很多實驗。因此,書中深入淺出、詳略得當的講解使得某些原本艱澀難懂的代碼變得生動活潑,甚至妙趣橫生。對於重點章節或很艱深的部分,作者則不吝筆墨、列舉多個例子闡明;在每章結束還有針對性地提出一些思考題,讓讀者進一步鞏固本章內容。

全書共分15章。第1章主要講述UNIX誕生的經過、流派和它的特點。第2章主要講述UNIX框架及其運行的硬體平台。第3章講述虛擬記憶體的主要功能及UNIX虛擬記憶體的實現原理。第4章主要講述啟動過程。第5章主要講述進程管理和調度的實現。第6章是對中斷處理過程的講解,而第7章講述和中斷類似的自陷的處理過程。第8章講解檔案系統,其實是檔案系統的核心實現,而用戶實現部分在第12章講述。第9章講解UNIX是如何管理I/O(輸入/輸出)設備的。第10章在第4章的基礎上更全面地闡述UNIX的交換過程,因為交換是進程管理中一個很重要的概念。第11章講述UNIX執行檔的格式。第12章講述UNIX系統調用的實現過程,包括了檔案系統、進程和信號等部分。第13章不僅講解已有的各種進程間通信的方式(信號、檔案、管道),而且還給出其他多種進程間通信方式(信號量、互斥體、訊息等)的示例實現。第14章給出現代作業系統才有的執行緒的示例實現。最後第15章講述UNIX的登錄過程和20世紀80年代出現的網路檔案系統NFS,進而體現其對網路多用戶的支持。

本書適用於具有豐富開發經驗特別是想了解作業系統實現或對其感興趣的軟體工程師。

對於初級軟體工程師,只要能認真研習,它也將是你提高軟體開發水平的一個很好的選擇。

清華大學計算機系教授、博士生導師 鄭緯民

2010年4月15日於北京清華園

序 二

UNIX作業系統,誕生於四十餘年前,作為一種革命性的軟體產品,一直標示著軟體業的頂尖水準。而UNIX 第6版,作為UNIX最後一個開放源碼版本,歷來是學習UNIX的最佳起點——這是中科院的必修課程,是麻省理工研究生院的必修課程。本書就是這樣一本闡述其實現結構的巨著,它選擇了UNIX第6版作為講解對象,由框架到細節、由基礎到高級,細述了各部分的實現和代碼組成。

本書作者曾在朗訊、摩托羅拉等公司從事多年的軟體開發工作,在UNIX及Linux平台下下有著非常豐富的開發經驗,並對作業系統有著深入的研究。本書是作者在對UNIX第6版的每一行代碼做了精心研究後所得出的理解和體會,是翻閱參考大量資料和實驗驗證的產物。正因為如此,本書中那些深入淺出、詳略得當的講解使得原本艱澀難懂的代碼變得生動,甚至拍案叫絕。對於重點章節或晦澀的部分,作者不吝筆墨、列舉多個例子予以闡明,例如第12章中對ptrace系統調用的解釋,甚至給出了一個簡單調試器(Debugger)的實現。而對於相對次要或容易理解的部分,則一帶而過,點到為止。值得稱道的是,某些章節還例舉大眾熟知的Windows作業系統作為對比,以起到舉一反三、融會貫通的效果。比如第8章就把UNIX檔案系統實現和Windows FAT16做了比較,列舉了各自的優劣所在。

作為本書的技術審校者,我是以學習的態度來閱讀本書的。雖然我有著近二十年的作業系統與資料庫工作經驗,也常被封為所謂“技術專家”,但本書作者對UNIX入木三分的觀點闡明使我受益頗深。更使我感動的是,作為一個真正的技術專家,作者對細節的處理態度——字字點到,句句說明!我們如何能不受益於這本書?

十年磨一劍,這是我對這本書的最真實感受!

不忍釋手,一氣讀完,抬首看窗外,夜幕正在散去,黎明正在到來。回想我讀的這本UNIX 6,正像是早晨的絲絲光線,它帶我們穿越了繁雜的代碼黑幕,揭示了UNIX的內部結構和來龍去脈,帶給我們清晰的思想和邏輯!它能讓我們擁有自信來掌握它、控制它,而不僅僅是對UNIX的順從!

在Linux火熱的今天,在UNIX大行其道的今天,讓我們再上一步,給自己做一次“升級”,從一個低層次的代碼堆砌者,成為一個有自己獨立思想的系統架構師!

如果這樣的程式設計師多了,中國怎能長時間地跟隨歐美的腳步?更如何能走在印度後面?

感謝作者!

UNIX與資料庫技術專家侯文平

2010年4月於北京

前 言

自計算機誕生以來,產生了數以百計的作業系統,但這其中,無疑以UNIX最具有生命力,流派也最廣。雖然在個人電腦上,Windows占據了絕大多數用戶,但在伺服器領域,UNIX依然是一枝獨秀。Linux作為UNIX一個傑出的分支,已異軍突起,不僅在伺服器行業占有重要地位,而且在個人電腦上也越來越多地看到它的身影。

為什麼UNIX具有如此強大的生命力?原因就在於它精妙的設計思想、小巧高效而又健壯的核心、豐富的功能、易擴展的架構和良好的開放性。UNIX所定義的很多接口(比如檔案訪問)已經成為行業標準,而它的分支也十分眾多,如Unixware、AIX、Solaris、BSD UNIX等。

UNIX最早是由貝爾實驗室(Bell Labs)的Kenneth Thompson (肯尼思·湯普森)和 Dennis Ritchie(丹尼斯·里奇)開發的,在此過程中,他們還發明了C語言。在1972年他們推出了UNIX版本6(UNIX 6 Edition),這也是本書所要講述的版本。

本書內容

本書節選了UNIX版本6的全部核心代碼及少量用戶部分代碼,總計在10 000行左右。之所以選擇它是因為這是貝爾實驗室所開放的最後一版UNIX,而且相對於前幾版,它更貼近於現代作業系統,幾乎具備了現代作業系統的所有概念:如中斷和自陷管理、進程調度、記憶體管理、檔案系統、I/O設備管理等。而且,很多現在的常用命令當時也已實現,比如mkdir、ls、cd、exec、find、grep、cron等。另外,本版90%代碼都使用C語言編寫,代碼量也不大,這就使得閱讀更加方便,適合講解。

作者在講述代碼時,不僅儘量忠於和體現原來的設計思想,而且對於某些可能不太完美的實現部分還相應指出並給出改進的意見。此外,對於UNIX版本6不具備的某些功能,比如進程間互斥、訊息通信和執行緒功能,作者還在第13章、第14章給出了簡單的示例實現。另外,作者在列舉原始碼時,都在之前指明其所在檔案,個別地方未指明的,在最近一次所指明的檔案中。

本書讀者

本書適用於有志於作業系統研究或對作業系統實現感興趣的軟體工程師,也可作為本專科院校計算機及相關專業學生學習作業系統和C語言的參考書。而對於其他軟體人員,本書也將是你提高編程水平的一個很好的選擇,書中揭示了很多優秀的設計思想、數據結構和算法,相信它們能給你以不少啟示,在此過程中你還能看到C語言所展示出的精練高效的強大魅力!書中的很多代碼後來也成為C程式標本式的實現和風格。

本書光碟

本書附有光碟,光碟不僅包含書中所列代碼(包括作者自己實現的部分),還包含其他很多代碼,比如init進程、shell進程等的實現。此外,還包括shell所支持的各個命令的實現代碼,甚至還包含了當時所用的編譯器。

讀者可以直接閱讀本書,也可以打開光碟中的代碼,對照本書閱讀。另外,在閱讀時,有些章節如果聯繫起來看效果會更好,比如第4章和第5章、第6章和第9章。

著作權聲明

第13章和第14章中作者所實現部分的代碼,由於環境限制,並未經過實際測試,對它們所造成任何可能的損壞性後果,作者在此聲明並不對此負責,敬請諒解。另外,該部分代碼只限於個人學習研究使用,作者保留對該部分代碼的一切發布、發行、使用、修改及拷貝的權利,如有任何個人或組織要將其用於商業目的,請和作者聯繫並支付相應費用。

聯繫方式

由於作者水平所限,書中難免存在不當甚至錯誤之處,敬請批評指正。同時,非常歡迎讀者提問、評論、批評和建議,可以和我聯繫。

IBM高級軟體開發工程師 郝慶豐

2009年8月於北京

目 錄

第1章 概論 1

1.1 歷史背景 1

1.2 UNIX誕生的經過 1

1.3 UNIX版本6 2

1.4 各流派一覽 2

1.5 為什麼取得成功 3

1.5.1 簡潔高效 3

1.5.2 健壯性 3

1.5.3 功能豐富 3

1.5.4 移植性 3

1.5.5 開放性 4

1.6 縮寫及術語說明 4

第2章 UNIX綜述 6

2.1 硬體平台 6

2.1.1 中斷和自陷(Trap) 7

2.1.2 兩種處理器模式 9

2.1.3 通用暫存器 10

2.1.4 I/O設備管理 10

2.1.5 棧(Stack) 11

2.1.6 常用指令 11

2.1.7 備註 19

2.2 UNIX核心綜述 20

2.2.1 模組分類 20

2.2.2 各模組間的通信 20

2.2.3 源檔案 21

2.2.4 語法規則和編碼風格說明 23

2.3 思考題 27

第3章 虛擬記憶體 28

3.1 簡介 28

3.2 虛擬記憶體的優點 29

3.2.1 安全性 29

3.2.2 提高空間利用率 30

3.2.3 多進程的支持 30

3.3 PDP11/40的虛擬記憶體機制 30

3.3.1 頁地址暫存器(PAR) 32

3.3.2 頁描述暫存器(PDR) 32

3.3.3 活動頁暫存器地址 33

3.3.4 虛擬地址向物理地址的映射過程 33

3.3.5 異常處理 35

3.3.6 和現代頁式虛存的比較 36

3.4 UNIX的虛存實現 36

3.4.1 進程空間分布 36

3.4.2 用戶活動頁暫存器設定函式estabur 37

3.4.3 用戶空間映射函式sureg 41

3.5 記憶體管理 42

3.5.1 核心記憶體管理 42

3.5.2 用戶記憶體管理 47

3.6 思考題 56

第4章 啟動模組 57

4.1 操作流程 57

4.2 中斷向量 58

4.3 啟動函式start 60

4.4 備註 65

4.4.1 為什麼需要引導程式和裝入程式 65

4.4.2 0地址處指令分析 65

4.4.3 為什麼要使用彙編語言 66

4.4.4 Windows啟動過程淺析 66

4.5 思考題 67

第5章 進程管理和調度 68

5.1 程式設計師眼中的虛擬機 68

5.2 系統資源 68

5.3進程上下文70

5.4 進程調度 72

5.5 UNIX實現 73

5.5.1 進程上下文 73

5.5.2 進程的兩種狀態 80

5.5.3 調度過程 82

5.5.4 備註 128

5.6 思考題 134

第6章 中斷處理過程 136

6.1 PSW暫存器 136

6.2 中斷處理流程 136

6.3 中斷向量 138

6.4 PDP 11/40的中斷類型 139

6.4.1 電傳終端接口輸入中斷 139

6.4.2 電傳終端接口輸出中斷 140

6.4.3 紙帶打孔機輸入中斷 140

6.4.4 紙帶打孔機輸出中斷 140

6.4.5時鐘中斷140

6.4.6 行印表機中斷 140

6.4.7 磁碟讀寫中斷 140

6.5 一些常用函式 140

6.5.1 特殊指令 140

6.5.2 fubyte(fuibyte) 141

6.5.3 fuword(fuiword) 143

6.5.4 subyte(suibyte) 143

6.5.5 suword(suiword) 144

6.5.6 clearseg 144

6.5.7 copyseg 145

6.5.8 copyin/copyout 146

6.5.9 dpadd 148

6.5.10 ldiv/lrem/lshift 148

6.6 call函式 149

6.7 時鐘中斷 151

6.7.1 基本概念 151

6.7.2 處理過程 152

6.8 call函式調用分派切換器的理由 163

6.9 核心定時器 164

6.9.1 數據結構 164

6.9.2 定時器的創建 165

6.9.3 定時器的觸發 167

6.10 一些例子 168

6.10.1 進程優先權的調整 168

6.10.2 進程分派切換實例 174

6.11 備註 178

6.11.1 中斷服務函式中為什麼不使用互斥鎖 178

6.11.2 中斷服務函式中為什麼不訪問u變數 178

6.11.3 關於記憶體管理違例自陷的處理過程 179

6.11.4 調度標誌runrun和runin 179

6.12 思考題 179

第7章 自陷 180

7.1 自陷原理 180

7.2 自陷向量 180

7.3 PDP11/40的自陷類型180

7.3.1 系統出錯自陷 180

7.3.2 系統調用自陷 182

7.3.3 調試自陷 182

7.3.4 自陷優先權 183

7.4 自陷處理過程 184

7.4.1 彙編函式_trap 184

7.4.2 C函式trap 186

7.4.3 backup函式 191

第8章 檔案系統 211

8.1 概述 211

8.2 框架 212

8.2.1 檔案存儲的實現 212

8.2.2 UNIX檔案系統 219

8.2.3 UNIX檔案系統的詳細實現 224

8.3 檔案訪問接口 229

8.3.1 檔案創建接口creat 230

8.3.2 檔案打開接口open 235

8.3.3 檔案關閉接口close 236

8.3.4 檔案讀接口read 237

8.3.5 檔案寫接口write 238

8.3.6 檔案定位接口seek 239

8.3.7 特殊檔案創建接口mknod242

8.3.8 檔案連結接口link 244

8.3.9 取消檔案連結接口unlink246

8.3.10 設備載入接口smount 248

8.3.11 設備卸載接口sumount 251

8.4 節點和塊管理 253

8.4.1 節點快取 253

8.4.2 塊快取 255

8.4.3 塊訪問接口 263

8.4.4 節點訪問接口 294

8.5 塊設備驅動 322

8.5.1 概述 322

8.5.2 根設備——rk11磁碟 326

8.6 備註 335

8.6.1 FAT16檔案系統 335

8.6.2 多進程訪問檔案的問題 338

8.6.3 進程間同步 339

8.6.4 檔案的刪除 340

8.6.5 設備驅動的擴展 340

8.7 總結 341

8.8 思考題 341

第9章字元設備驅動 342

9.1 互動終端——電傳打字機(teletypewriter) 342

9.1.1 設備特性 343

9.1.2 操作暫存器 343

9.1.3 驅動框架 345

9.1.4 驅動函式 351

9.1.5 shell套用舉例 378

9.1.6 核心列印接口 379

9.2 PC-11紙帶打孔機 383

9.2.1 設備特性 383

9.2.2 操作暫存器 384

9.2.3 驅動框架 385

9.2.4 驅動函式 387

9.2.5 讀取器狀態轉換圖392

9.3 LP-11行印表機 393

9.3.1 設備特性 393

9.3.2 操作暫存器 393

9.3.3 驅動框架 394

9.3.4 驅動函式 396

9.4 現代印表機 401

9.4.1 並口 401

9.4.2 和核心掛接 403

9.4.3 簡單的列印程式 406

9.4.4 CUPS 408

9.5 其他字元設備 408

9.5.1 記憶體 409

9.5.2 磁碟 411

9.6 網路驅動程式 415

9.7 綜合示例 416

9.8 總結 417

9.9 思考題 418

第10章 進程交換過程 419

10.1 概述 419

10.2 具體實現 421

10.2.1 進程換出函式xswap 422

10.2.2 程式段記憶體釋放函式xccdec 423

10.2.3 交換函式swap 424

10.2.4 調用實例 425

10.3 綜合示例 426

10.4 思考題 430

第11章 UNIX執行檔 431

11.1 .out檔案 431

11.1.1 可執行頭 431

11.1.2 程式段 432

11.1.3 數據段 432

11.1.4 程式和數據重定向表 432

11.1.5 符號表 434

11.1.6 示例 437

11.2 動態連結過程* 442

11.2.1 靜態共享 443

11.2.2 動態共享 446

11.2.3 GOT/PLT表和位置無關代碼(PIC) 446

11.2.4 動態載入過程分析 450

第12章 系統調用 457

12.1 概述 457

12.2 系統調用的實現 457

12.2.1 用戶實現 459

12.2.2 系統調用表和trap自陷 459

12.2.3 核心實現 469

12.3 各系統調用的實現 469

12.3.1 檔案相關調用 471

12.3.2 進程相關調用 491

12.3.3 信號相關調用 538

12.3.4 調試功能調用 558

12.3.5 用戶/組ID調用 586

12.3.6 時間相關調用 589

12.3.7 終端相關調用 591

第13章 進程間通信 596

13.1 概述 596

13.2 管道 596

13.2.1 相關係統調用 596

13.2.2 管道實現過程分析 602

13.2.3 套用示例 603

13.2.4 採用記憶體檔案實現管道 608

13.2.5 思考題 610

13.3 檔案 610

13.4 有名管道 611

13.5 進程間同步 611

13.5.1 信號量 612

13.5.2 互斥體 621

13.5.3 事件 622

13.6 死鎖 634

13.7 其他進程間數據傳輸方式 636

13.7.1 訊息(message) 636

13.7.2 信箱(mailbox) 648

13.7.3 共享記憶體 671

第14章 多執行緒的實現 686

14.1 概述 686

14.2 執行緒和經典進程的比較 686

14.3 執行緒的示例實現 686

14.3.1 相關數據結構 686

14.3.2 實現方案 689

14.3.3 執行緒創建調用CreateThread 691

14.3.4 核心改動 695

14.3.5 執行緒退出調用ExitThread 711

14.3.6 執行緒id獲得調用gettid 712

14.3.7 執行緒掛起調用SuspendThread 712

14.3.8 執行緒恢復調用ResumeThread 714

14.3.9 執行緒終止調用TerminateThread 715

14.3.10 執行緒ID查詢調用GetThreadID 719

14.3.11 執行緒名查詢調用GetThreadName 720

14.3.12 使用示例 721

14.3.13 思考題 723

第15章 網路多用戶 724

15.1 系統初始化過程 724

15.1.1 init進程 724

15.1.2 getty程式 725

15.1.3 login程式 725

15.2 telnet程式 730

15.2.1 工作原理 730

15.2.2 常用配置 731

15.3 NFS(網路檔案系統) 732

15.3.1 基本原理 733

15.3.2 RPC(遠程過程調用) 734

15.3.3 各過程的實現 737

15.3.4 簡單示例 741

附錄A 參考書目及資源 742

附錄B 思考題答案 743

相關詞條

相關搜尋

熱門詞條

聯絡我們