作業系統並不深奧,本書給予權威解讀
.用6000多行程式碼建立一個完整的作業系統。
.徹底剖析作業系統的原理,實現核心執行緒、特權等級變換、使用者處理程序、系統呼叫、檔案系統等作業系統基本的組成單元。
.用實際程式碼解釋了鎖、號誌、生產者消費者問題。
.實現一個簡單的shell,幫助大家理解內部命令、外部命令、管線等操作。
作業系統是一切電腦運作的基礎,不管是你我熟悉的Windows、伺服器用的Linux,綜合兩者的Mac OS,當然還有手機上的iOS或是Android,甚至是車載、機載的系統,都是作業系統的一種。
一般認為作業系統是最複雜的軟體,但隨著工具的進步,再加上資訊的流通,作業系統的底層運作方式也不再是祕密。本書使用C語言及少量的組合語言,用最簡單易懂的方式,讓你建立一個自己的作業系統,解說清楚,程式碼詳盡,從前視為巨型公司的頂尖工程團隊才能完成的艱鉅任務,現在由大師帶你動手,撰寫自己的作業系統!
適用:程式師、系統底層開發人員、作業系統愛好者。
作者簡介:
鄭鋼
畢業於北京大學,前百度運維高級工程師,對作業系統有深入的研究。愛運動,喜鑽研,熱衷於嘗試前沿技術,樂於分享學習成果。
作者序
本書針對的讀者,是作業系統基礎知識薄弱,但又想把作業系統弄清楚、喜歡追根究底的技術人,在此向你們致敬,本書用詼諧幽默的語言,把深奧的作業系統儘量說明清楚,讓讀者在輕鬆閱讀中學通深奧的知識。
多數學習作業系統的讀者都會有這樣的感受:
(1) 「 太難了,對於作業系統這個龐然大物我簡直無從下手」;
(2) 「 很後悔選了這門課(大學一些科系中作業系統是選修課),甚至不想學習電腦了」;
(3) 「 上課完全聽不懂,我都不想繼續聽下去了」;
(4) 「 即使實驗做出來了,由於只是完成了局部功能,我依然不明白作業系統是怎樣執行起來的,甚至不知道自己在做什麼」。
以上的感受我都有過,坦白說,這門課並不是很難,但想完全明白這門課真不容易。我是個喜歡追根究底的人,為了弄清楚這背後的真相,我花大量時間學習課程之外的內容,甚至付出慘痛的代價-- 大學中第一次考試不及格,作業系統這門課我是第二次才考過的。這確實很「諷刺」-- 作業系統不及格的人在寫作業系統書籍!但轉念一想,考試過了的同學並不代表能夠寫出作業系統,因為考卷上並不是在考如何寫一個作業系統。和技術能力相比,考試成績並不重要。
想像一下,如果是愛因斯坦那樣的天才為我們講解物理知識,我們會覺得物理更容易了解嗎?一定是不會的,因為在愛因斯坦眼中比較容易的內容也許對我們來說非常深奧,他用B 解釋A 的時候也許會讓我們更迷惑,因為B 我們也不懂,這就是基礎的問題了。幸運的是閱讀本書時讀者只要有C 語言和部分組合語言的基礎即可,相關的其他方面知識我都會詳細介紹,並以更容易的方式去解釋技術難點,讀者不必擔心看不懂本書。
回憶一下學車的經歷:教練讓學員先踩離合器再入檔,然後再踩油門,車子就開動啦。如果學員總是學不會這些,有可能是學員根本不知道什麼是離合器,或不知道離合器的作用是什麼。即使把這些操作背下來,也會對駕車感到心有餘而力不足,可見,只有了解背後的原理,才會知道自己在做什麼,駕車才變得遊刃有餘。
以上情況對我們學習作業系統來說也同樣存在,例如當老師介紹中斷發生時的上下文保護時,我們更多的疑問不是如何儲存CPU 的上下文資料,而是想知道為什麼在不同的特權等級下會使用不同的堆疊,這背後的原理是什麼,並且這是如何做到的。
諸如這種的疑問需要了解硬體原生支援的執行機制,因為很多操作都是硬體自動完成的,例如處理器進入0 特權等級時,會自動在工作狀態段TSS 中獲得0 特權等級的堆疊位址,這不需要人工干涉,完全由處理器維護。我們想知道的是,硬體在背後自動完成了哪些工作,這樣才便於我們了解作業系統的全貌。
作業系統受制於硬體的支援,它的能力取決於硬體的能力,因此,要想全面了解作業系統,不僅需要了解上層軟體的演算法、原理、實現,還要了解很多硬體底層的內容。和硬體相關的知識是在微機介面電路中說明的,而絕大多數讀者在學習這門課時,根本不知道它有何用,只有學習作業系統課程時才用到它,因此,本書內容兼顧相關的硬體知識。
除硬體外,本書還把作業系統中的理論付諸於實作,讓讀者真正學到包含在作業系統中的實實在在的技術,例如在程式中實現了著名的生產者消費者問題,還有處理程序、線性、阻塞、號誌、鎖、檔案系統、目錄、shell、管線等。各個章節的程式都可獨立執行,方便偵錯,本書更讓讀者有成就感的是,我們最後完成的作業系統總共程式量只有幾千行左右,相當大地減少了作業系統原始程式閱讀的工作量。
作業系統還是比較龐大的,因此,大部分介紹作業系統原理的書中,對各個部分都是分拆出來介紹的,這導致我們學習作業系統時猶如瞎子摸象、管中窺豹。本書內容不再局部學習,而是把所有局部還原成一個整體,做出一個真正的作業系統。
為了讓讀者不再懼怕作業系統,同時也為了完成我自己的心願,我辭職專心進行本書的撰寫,在此期間也曾拒絕了多份回報豐厚的工作,現在想想真是瘋狂⋯⋯苦了我的父母和女朋友,在這裡跟你們說聲抱歉,你們「縱容」我的偏執,真心不容易,辛苦啦,我愛你們!
感謝我在北京大學就讀期間的Linux 核心課程老師(同時也是我的所究所學生導師)荊琦教授和作業系統課程老師陳向群教授,很榮幸能夠成為您們的學生,時至今日我常常回想起課堂上您們言傳身教並為我解答問題的身影,您們淵博的知識和教學上嚴謹的態度深深影響了我,僅以此書向我這兩位恩師致謝。
感謝父母給予我的了解和寬容,以後我一定加倍努力回報您們的養育之恩!
最後,感謝女朋友給予我的陪伴和照顧,在寫此書的過程中我深深體會到:愛並不僅表現在相信對方一定能成功,更多是表現在支援對方去做想做的事,即使失敗了也不會嫌棄。儘管在這漫長枯燥的19 個月當中,如果沒有妳的「嘮嘮叨叨」本書早就寫完了,但剛好是這種「嘮嘮叨叨」下的不離不棄讓我相信這世上還有真愛。
本書讀者交流QQ 群為:148177180。
作者
於北京大學圖書館
本書針對的讀者,是作業系統基礎知識薄弱,但又想把作業系統弄清楚、喜歡追根究底的技術人,在此向你們致敬,本書用詼諧幽默的語言,把深奧的作業系統儘量說明清楚,讓讀者在輕鬆閱讀中學通深奧的知識。
多數學習作業系統的讀者都會有這樣的感受:
(1) 「 太難了,對於作業系統這個龐然大物我簡直無從下手」;
(2) 「 很後悔選了這門課(大學一些科系中作業系統是選修課),甚至不想學習電腦了」;
(3) 「 上課完全聽不懂,我都不想繼續聽下去了」;
(4) 「 即使實驗做出來了,由於只是完成了局部功能,我依然不明白作業系統是怎樣執行起來...
目錄
前言
Chapter 00 一些你可能正感到迷惑的問題
0.1 作業系統是什麼
0.2 你想研究到什麼程度
0.3 撰寫作業系統,哪些需要我來做
0.4 軟體是如何存取硬體的
0.5 應用程式是什麼,和作業系統是如何配合到一起的
0.6 為什麼稱為「陷入」核心
0.7 記憶體存取為什麼要分段
0.8 程式中為什麼分為程式碼片段、資料段?這和記憶體存取機制
中的段是一回事嗎
0.9 實體位址、邏輯位址、有效位址、線性位址、虛擬位址的區別
0.10 什麼是段重疊
0.11 什麼是平坦模型
0.12 cs、ds 這種sreg 段暫存器,位寬是多少
0.13 什麼是專案,什麼是協定
0.14 為什麼Linux 系統下的應用程式不能在Windows 系統下執行
0.15 區域變數和函數參數為什麼要放在堆疊中
0.16 為什麼說組合語言比C 語言快
0.17 先有的語言,還是先有的編譯器,第1 個編譯器是怎麼產生的
0.18 編譯型程式與直譯型程式的區別
0.19 什麼是大端位元組序、小端位元組序
0.20 BIOS 中斷、DOS 中斷、Linux 中斷的區別
0.21 Section 和Segment 的區別
0.22 什麼是魔術參數
0.23 作業系統是如何識別檔案系統的
0.24 如何控制CPU 的下一行指令
0.25 指令集、系統結構、微架構、程式語言
0.26 函數庫函數是使用者處理程序與核心的橋樑
0.27 逸出字元與ASCII 碼
0.28 MBR、EBR、DBR 和OBR各是什麼
Chapter 01 部署工作環境
1.1 工欲善其事,必先利其器
1.2 我們需要哪些編譯器
1.3 作業系統的宿主環境
1.4 設定bochs
1.5 執行bochs
Chapter 02 撰寫MBR 主啟動記錄,讓我們開始掌權
2.1 電腦的啟動過程
2.2 軟體接力第一棒,BIOS
2.3 讓MBR 先飛一會兒
Chapter 03 增強MBR
3.1 地址、section、vstart 淺嘗即止
3.2 CPU 的真實模式
3.3 讓我們直接對顯示器說點什麼吧
3.4 bochs 偵錯方法
3.5 硬碟介紹
3.6 讓MBR 使用硬碟
Chapter 04 保護模式入門
4.1 保護模式概述CPU,變成了16 位元
4.2 初見保護模式
4.3 通用描述元表
4.4 處理器微架構簡介
4.5 使用遠跳躍指令清空管線,更新段描述符號緩衝暫存器
4.6 保護模式之記憶體段的保護
Chapter 05 保護模式進階,向核心邁進
5.1 取得實體記憶體容量
5.2 啟用記憶體分頁機制,暢遊虛擬空間
5.3 載入核心
5.4 特權等級深入淺出
Chapter 06 增強核心
6.1 函數呼叫約定簡介
6.2 組合語言和C 語言混合程式設計
6.3 實現自己的列印函數
6.4 內聯組合語言
Chapter 07 中斷
7.1 中斷是什麼,為什麼要有中斷
7.2 作業系統是中斷驅動的
7.3 中斷分類
7.4 中斷描述符號表
7.5 可程式化中斷控制器8259A
7.6 撰寫中斷處理常式
7.7 可程式化計數器/計時器8253 簡介
7.8 加強時脈中斷的頻率,讓中斷來得更猛烈一些
Chapter 08 記憶體管理系統
8.1 makefile 簡介
8.2 實現assert 斷言
8.3 實現字串操作函數
8.4 點陣圖bitmap 及其函數的實現
8.5 記憶體管理系統
Chapter 09 執行緒
9.1 實現核心執行緒
9.2 在核心空間實現執行緒
9.3 核心資料結構,雙向鏈結串列
9.4 多執行緒排程
Chapter 10 輸入輸出系統
10.1 同步機制——鎖
10.2 用鎖實現終端輸出
10.3 從鍵盤取得輸入
10.4 撰寫鍵盤驅動
10.5 環狀輸入緩衝區
Chapter 11 使用者處理程序
11.1 為什麼要有工作狀態段TSS
11.2 定義並初始化TSS
11.3 實現使用者處理程序
11.3 執行時期註釋
Chapter 12 進一步增強核心
12.1 Linux 系統呼叫淺析.
12.2 系統呼叫的實現
12.3 讓使用者處理程序「說話」
12.4 增強堆積記憶體管理
Chapter 13 撰寫硬碟驅動程式
13.1 硬碟及分區表
13.2 撰寫硬碟驅動程式
Chapter 14 檔案系統
14.1 檔案系統概念簡介
14.2 建立檔案系統
14.3 檔案描述符號簡介
14.4 檔案操作相關的基礎函數
14.5 建立檔案
14.6 檔案的開啟與關閉
14.7 實現檔案寫入
14.8 讀取檔案
14.9 實現檔案讀寫指標定位功能
14.10 實現檔案刪除功能
14.11 建立目錄
14.12 檢查目錄
14.13 刪除目錄
14.14 工作的工作目錄
14.15 獲得檔案屬性
Chapter 15 系統互動
15.1 fork 的原理與實現
15.2 增加read 系統呼叫,取得鍵盤輸入
15.3 增加putchar、clear 系統呼叫
15.4 實現一個簡單的shell
15.5 載入使用者處理程序
15.6 實現系統呼叫wait 和exit
15.7 管線
前言
Chapter 00 一些你可能正感到迷惑的問題
0.1 作業系統是什麼
0.2 你想研究到什麼程度
0.3 撰寫作業系統,哪些需要我來做
0.4 軟體是如何存取硬體的
0.5 應用程式是什麼,和作業系統是如何配合到一起的
0.6 為什麼稱為「陷入」核心
0.7 記憶體存取為什麼要分段
0.8 程式中為什麼分為程式碼片段、資料段?這和記憶體存取機制
中的段是一回事嗎
0.9 實體位址、邏輯位址、有效位址、線性位址、虛擬位址的區別
0.10 什麼是段重疊
0.11 什麼是平坦模型
0.12 cs、ds 這種sreg 段暫存器,位寬是多少
0.13 什麼是專案,什麼是協定
0.14 為什麼Linux 系...