本書是一本為渴望深入理解計算機操作系統(tǒng)設(shè)計與實現(xiàn)的讀者量身打造的實踐指南。全書共18章,涵蓋了諸多關(guān)鍵主題,包括如何啟動操作系統(tǒng),管理內(nèi)存和異常,創(chuàng)建進(jìn)程并實現(xiàn)進(jìn)程的協(xié)作,開發(fā)設(shè)備驅(qū)動程序,構(gòu)建文件系統(tǒng)從而讀寫文件等內(nèi)容,并以此為基礎(chǔ)構(gòu)建出可供用戶程序使用的系統(tǒng)調(diào)用接口。通過這些接口,創(chuàng)建出小型的命令行解析器,它可根據(jù)用戶輸入的命令動態(tài)加載硬盤上的程序執(zhí)行。為降低學(xué)習(xí)難度,盡可能地減少匯編代碼的使用,并且向讀者提供了一套簡單易用的開發(fā)環(huán)境。通過翔實的原理分析和示例代碼,讀者能夠清楚地看到一個小型的操作系統(tǒng)是如何一步步構(gòu)建出來的。通過本書,讀者不僅能夠掌握操作系統(tǒng)的設(shè)計原理,還能親自動手實踐,構(gòu)建屬于自己的操作系統(tǒng)。無論你是計算機專業(yè)的學(xué)生,還是希望擴展技術(shù)深度的開發(fā)者,本書都能為你提供豐富的學(xué)習(xí)資源和實踐指導(dǎo)。通過本書,你將不僅僅了解操作系統(tǒng)“是什么”,更會明白它“為什么這么做”以及“如何實現(xiàn)”。
通過翔實的原理分析和示例代碼,讓讀者能夠清楚地看到一個小型的操作系統(tǒng)是如何一步步構(gòu)建出來的,還能親自動手實踐。
前言
本書介紹
記得很多年前,我在學(xué)校的圖書館書架上發(fā)現(xiàn)了一本厚厚的關(guān)于Linux 0.11內(nèi)核源碼分析的書籍。不過,由于該書僅從源碼分析的角度介紹操作系統(tǒng)的實現(xiàn),再加之自己的編程水平有限,因此最終僅閱讀了一小部分章節(jié)。后來,偶爾也能找到介紹手寫操作系統(tǒng)的書籍,不過,書中充斥著大量的匯編代碼、復(fù)雜的設(shè)計算法且代碼難于調(diào)試,這也導(dǎo)致我很難讀完這些書。
手寫操作系統(tǒng)是一件非常令人興奮的事情,上述因素不應(yīng)當(dāng)成為前進(jìn)之路上的障礙。能不能將這個事情變得簡單一些,使得初學(xué)者能夠更容易地學(xué)習(xí)?
在經(jīng)過一系列的摸索之后,我找到了一種解決方案,并以此為基礎(chǔ)做出了一套介紹操作系統(tǒng)實現(xiàn)的課程,最終完成此書。在書中,我盡可能地簡化了操作系統(tǒng)的實現(xiàn)過程,從而讓初學(xué)者能夠更專注于操作系統(tǒng)的實現(xiàn)。
例如,該操作系統(tǒng)既不支持64位架構(gòu),也不支持多核,內(nèi)部設(shè)計算法也盡可能簡單且易于理解。對于初學(xué)者而言,這些內(nèi)容并不特別重要。盡管如此,這個操作系統(tǒng)仍然具備了一個操作系統(tǒng)應(yīng)當(dāng)具備的功能,如進(jìn)程管理、虛擬內(nèi)存、文件系統(tǒng)、系統(tǒng)調(diào)用和設(shè)備管理等。更重要的是,本書提供了一套簡易的開發(fā)環(huán)境,學(xué)習(xí)者可以很方便地對代碼進(jìn)行調(diào)試。
本書特點
相比市面上已有的同類書籍,本書具備如下特點:
整體共6000余行代碼,匯編代碼僅約100行,其余均為可讀性好的C代碼。
無論是操作系統(tǒng)還是應(yīng)用程序,所有代碼均可一鍵編譯和調(diào)試。
盡可能采用簡單易懂而非復(fù)雜的設(shè)計算法降低學(xué)習(xí)難度。
各章節(jié)內(nèi)容緊密聯(lián)系,循序漸進(jìn)地展示了操作系統(tǒng)的實現(xiàn)過程。
內(nèi)容安排
對于大多數(shù)初學(xué)者而言,操作系統(tǒng)設(shè)計是一項復(fù)雜且煩瑣的工作。同時,由于操作系統(tǒng)各模塊之間存在復(fù)雜的關(guān)聯(lián); 因此,要采用一種簡單且易于理解的方式將其設(shè)計過程展示出來并非一件易事。
本書針對初學(xué)者的學(xué)習(xí)方式,對各章節(jié)的安排如下表所示。
章節(jié)
功 能 模 塊
主 要 內(nèi) 容
第1章設(shè)計目標(biāo)無了解目標(biāo)操作系統(tǒng)運行的硬件環(huán)境及設(shè)計目標(biāo)
第2章配置開發(fā)環(huán)境無分別介紹如何在Windows和Linux系統(tǒng)中安裝開發(fā)所需的各項工具,從而構(gòu)建開發(fā)操作系統(tǒng)所需的環(huán)境
第3章啟動操作系統(tǒng)無完成操作系統(tǒng)最基本的初始化和自加載工作,進(jìn)入C環(huán)境運行,實現(xiàn)簡單的日志打印接口
第4章內(nèi)存管理內(nèi)存管理實現(xiàn)位圖算法用于管理物理內(nèi)存的分配和釋放,創(chuàng)建頁表并啟用虛擬內(nèi)存
第5章異常管理
第6章實現(xiàn)多進(jìn)程運行
第7章進(jìn)程的同步與互斥
進(jìn)程管理
創(chuàng)建系統(tǒng)中優(yōu)質(zhì)個進(jìn)程first,構(gòu)建就緒列表和延時列表,實現(xiàn)進(jìn)程的有序運行以及進(jìn)程睡眠等功能,實現(xiàn)互斥鎖和信號量
第8章屏幕顯示與鍵盤讀取
第9章讀寫硬盤
第10章統(tǒng)一管理設(shè)備
設(shè)備管理
為鍵盤、屏幕以及硬盤設(shè)計驅(qū)動程序,抽象出一套簡單易用、統(tǒng)一的接口用于對這些設(shè)備進(jìn)行訪問
第11章讀寫設(shè)備文件
第12章讀寫普通文件
第13章文件系統(tǒng)的實現(xiàn)
文件系統(tǒng)
將硬件設(shè)備視作設(shè)備文件,抽象出相應(yīng)的文件訪問接口; 支持對硬盤上FAT16分區(qū)中普通文件的讀寫; 實現(xiàn)文件系統(tǒng)模塊,提供統(tǒng)一接口用于訪問設(shè)備文件和普通文件
第14章從硬盤加載程序執(zhí)行
內(nèi)存管理
進(jìn)程管理
將位于硬盤上的shell可執(zhí)行程序加載到內(nèi)存中執(zhí)行,并為其創(chuàng)建進(jìn)程地址空間
第15章實現(xiàn)系統(tǒng)調(diào)用
第16章支持內(nèi)存分配和printf()打印
第17章實現(xiàn)命令行解釋器
第18章進(jìn)程的創(chuàng)建與退出
進(jìn)程管理
系統(tǒng)調(diào)用
實現(xiàn)系統(tǒng)調(diào)用機制,使得shell能夠請求操作系統(tǒng)完成某些工作; 引入C語言標(biāo)準(zhǔn)庫,豐富shell可直接使用的功能接口; 實現(xiàn)fork()、execve()等系統(tǒng)調(diào)用接口
每個章節(jié)首先結(jié)合當(dāng)前設(shè)計目標(biāo)介紹設(shè)計原理; 之后再介紹如何用代碼實現(xiàn)。在閱讀本書時,請注意參考上表,以明確當(dāng)前所讀的內(nèi)容在整個系統(tǒng)設(shè)計中所處的位置。
學(xué)習(xí)基礎(chǔ)和方法
閱讀本書的讀者應(yīng)當(dāng)具備一定的編程基礎(chǔ),如熟練使用C語言、了解匯編語言編程(無須熟練)、對計算機組成原理和操作系統(tǒng)工作原理有初步的了解。能有Linux系統(tǒng)編程的經(jīng)驗。
在學(xué)習(xí)過程中,可能會遇到很多問題和挑戰(zhàn)。為此,給出相關(guān)建議供參考:
不要僅停留于閱讀本書,多參考書中內(nèi)容動手實踐。
對于與硬件設(shè)備相關(guān)的控制代碼,可以先不求甚解,直接引用書中的代碼。
閱讀每章時,可先嘗試自行思考如何設(shè)計,再與書中介紹的設(shè)計方法進(jìn)行對比。
以完成系統(tǒng)設(shè)計為首要目標(biāo),代碼優(yōu)化和功能增強等在完成本書學(xué)習(xí)后再進(jìn)行。
使用git等版本管理工具保存每一步的開發(fā)成果,以筆記形式記錄學(xué)習(xí)過程。
由于篇幅有限,對于一些不太重要的代碼,本書不會全部列出。請參考本書提供的配套源碼進(jìn)行理解。
在閱讀完本書之后,強烈建議讀者嘗試在該操作系統(tǒng)上進(jìn)行功能擴展或算法優(yōu)化,甚至從頭設(shè)計一個完整的操作系統(tǒng)。通過這種方式,你對相關(guān)內(nèi)容的掌握將會變得更為深入。
參考資料
在操作系統(tǒng)的開發(fā)過程中,涉及很多軟硬件方面的知識。本書僅給出部分較為核心的內(nèi)容介紹。更為詳細(xì)的介紹,可以從以下渠道獲。
維基網(wǎng)站給出了操作系統(tǒng)開發(fā)時所需要的硬件參考文檔、示例代碼及資料鏈接。請在閱讀本書時,參考該網(wǎng)站的內(nèi)容。
Intel 64 and IA32 Architectures Software Developers Manual: 該文檔共3卷,由Intel公司編寫。其中,第三卷介紹CPU系統(tǒng)編程相關(guān)的內(nèi)容,與操作系統(tǒng)開發(fā)密切相關(guān)。
此外,本書還提供了各章節(jié)的配套代碼、開發(fā)工具和相關(guān)文檔。請讀者掃描書后二維碼下載并適時參考,從而獲取更多有用信息。
作者2025年9月
李述銅畢業(yè)于四川大學(xué),嵌入式系統(tǒng)工程師,長期從事嵌入式軟件與底層系統(tǒng)開發(fā)工作,具備扎實的底層原理功底與豐富的實踐經(jīng)驗。多年來致力于將復(fù)雜的技術(shù)講解結(jié)構(gòu)化、通俗化,創(chuàng)作了一系列深入淺出的技術(shù)視頻與實戰(zhàn)課程,如《從0手寫嵌入式操作系統(tǒng)》《從0手寫TCP/IP協(xié)議!返。累計學(xué)員超過5萬人,收獲業(yè)內(nèi)廣泛好評,幫助眾多初學(xué)者和工程師建立系統(tǒng)性的嵌入式思維。
目錄
第1章設(shè)計目標(biāo)
1.1運行環(huán)境
1.2設(shè)計目標(biāo)
1.2.1系統(tǒng)功能
1.2.2設(shè)計成果
1.2.3系統(tǒng)結(jié)構(gòu)
1.3本章小結(jié)
第2章配置開發(fā)環(huán)境
2.1考慮因素
2.2所需工具
2.3安裝開發(fā)工具
2.3.1為Windows安裝開發(fā)工具
2.3.2為Linux安裝開發(fā)工具
2.4配置VSCode
2.5整體測試
2.6本章小結(jié)
第3章啟動操作系統(tǒng)
3.1設(shè)計目標(biāo)
3.2加載操作系統(tǒng)到內(nèi)存
3.2.1實模式
3.2.2啟動流程
3.2.3最小的操作系統(tǒng)
3.2.4加載操作系統(tǒng)的其余部分
3.3檢查系統(tǒng)內(nèi)存大小
3.4進(jìn)入保護(hù)模式
3.4.1保護(hù)模式
3.4.2分段機制
3.4.3段描述符
3.4.4段描述符表
3.4.5進(jìn)入保護(hù)模式
3.5讓內(nèi)核打印啟動信息
3.5.1解析可變參數(shù)
3.5.2格式化生成字符串
3.5.3打印輸出
3.6本章小結(jié)
第4章內(nèi)存管理
4.1管理物理內(nèi)存
4.1.1選擇內(nèi)存區(qū)域
4.1.2定義位圖結(jié)構(gòu)
4.1.3實現(xiàn)相關(guān)接口
4.1.4開關(guān)中斷保護(hù)
4.1.5初始化內(nèi)存管理
4.2開啟分頁機制
4.2.1工作原理
4.2.2創(chuàng)建頁表并啟用
4.3頁的分配與釋放
4.3.1開啟效果
4.3.2分配虛擬頁
4.3.3釋放虛擬頁
4.4測試效果
4.4.1內(nèi)存映射分析
4.4.2權(quán)限分析
4.5本章小結(jié)
第5章異常管理
5.1異常簡介
5.1.1什么是異常
5.1.2處理流程
5.2捕獲除0異常
5.2.1異常類型
5.2.2初始化異常系統(tǒng)
5.3解析異常棧幀信息
5.3.1壓棧過程
5.3.2手動壓棧
5.3.3解析壓棧內(nèi)容
5.4解析錯誤碼
5.4.1選擇子相關(guān)錯誤碼
5.4.2頁異常錯誤碼
5.4.3運行效果
5.5本章小結(jié)
第6章實現(xiàn)多進(jìn)程運行
6.1實現(xiàn)內(nèi)核鏈表
6.1.1定義結(jié)點
6.1.2定義鏈表
6.1.3鏈表操作
6.2創(chuàng)建進(jìn)程
6.2.1進(jìn)程簡介
6.2.2進(jìn)程與TSS
6.2.3創(chuàng)建優(yōu)質(zhì)個進(jìn)程
6.3實現(xiàn)進(jìn)程切換
6.3.1進(jìn)程切換效果
6.3.2sys_yield實現(xiàn)
6.3.3配置TSS
6.3.4深入分析切換過程
6.4讓進(jìn)程能夠睡眠
6.4.1睡眠效果
6.4.2讓進(jìn)程進(jìn)入睡眠
6.4.3創(chuàng)建空閑進(jìn)程
6.4.4讓進(jìn)程從睡眠中喚醒
6.5進(jìn)程調(diào)度算法
6.5.1問題現(xiàn)象
6.5.2時間片輪轉(zhuǎn)
6.5.3調(diào)度算法的實現(xiàn)
6.5.4運行效果
6.6本章小結(jié)
第7章進(jìn)程的同步與互斥
7.1互斥鎖
7.1.1實現(xiàn)原理
7.1.2實現(xiàn)互斥鎖
7.1.3應(yīng)用示例
7.2信號量
7.2.1實現(xiàn)原理
7.2.2實現(xiàn)信號量
7.2.3應(yīng)用示例
7.3本章小結(jié)
第8章屏幕顯示與鍵盤讀取
8.1屏幕顯示
8.1.1顯示原理
8.1.2驅(qū)動程序?qū)崿F(xiàn)
8.2讀取鍵盤
8.2.1實現(xiàn)原理
8.2.2驅(qū)動程序?qū)崿F(xiàn)
8.3構(gòu)造tty
8.3.1實現(xiàn)原理
8.3.2設(shè)備緩存
8.3.3驅(qū)動程序?qū)崿F(xiàn)
8.3.4運行效果
8.4改進(jìn)日志輸出
8.5本章小結(jié)
第9章讀寫硬盤
9.1工作原理
9.1.1硬盤連接
9.1.2邏輯結(jié)構(gòu)
9.1.3LBA尋址
9.1.4分區(qū)表
9.2驅(qū)動程序?qū)崿F(xiàn)
9.2.1基本交互接口
9.2.2硬盤初始化
9.2.3中斷配置
9.2.4讀寫硬盤
9.2.5其他接口
9.3運行效果
9.4互斥問題
9.5本章小結(jié)
第10章統(tǒng)一管理設(shè)備
10.1實現(xiàn)原理
10.1.1問題分析
10.1.2實現(xiàn)原理
10.2接口層實現(xiàn)
10.2.1定義設(shè)備結(jié)構(gòu)
10.2.2實現(xiàn)轉(zhuǎn)換層
10.2.3導(dǎo)入設(shè)備驅(qū)動
10.3運行效果
10.4修改日志輸出
10.5本章小結(jié)
第11章讀寫設(shè)備文件
11.1實現(xiàn)原理
11.1.1設(shè)備命名
11.1.2轉(zhuǎn)換實現(xiàn)
11.2設(shè)計實現(xiàn)
11.2.1定義文件結(jié)構(gòu)
11.2.2接口實現(xiàn)
11.2.3效果分析
11.3運行效果
11.4本章小結(jié)
第12章讀寫普通文件
12.1基本概念
12.1.1文件
12.1.2文件系統(tǒng)
12.2FAT文件系統(tǒng)
12.2.1鏈?zhǔn)酱鎯?br />
12.2.2存儲結(jié)構(gòu)
12.3接口實現(xiàn)
12.3.1掛載文件系統(tǒng)
12.3.2遍歷目錄
12.3.3刪除文件
12.3.4打開和關(guān)閉文件
12.3.5讀取和寫入文件
12.4多級目錄
12.5本章小結(jié)
第13章文件系統(tǒng)的實現(xiàn)
13.1讓進(jìn)程管理自己的文件
13.1.1實現(xiàn)原理
13.1.2具體實現(xiàn)
13.2提供統(tǒng)一的文件訪問接口
13.2.1實現(xiàn)原理
13.2.2具體實現(xiàn)
13.3運行效果
13.4本章小結(jié)
第14章從硬盤加載程序執(zhí)行
14.1構(gòu)建應(yīng)用程序
14.1.1構(gòu)建流程
14.1.2創(chuàng)建工程
14.1.3構(gòu)建結(jié)果
14.2加載應(yīng)用程序
14.2.1進(jìn)程地址空間
14.2.2ELF文件格式
14.2.3加載過程實現(xiàn)
14.2.4運行效果
14.3向進(jìn)程傳遞參數(shù)
14.3.1參數(shù)傳遞原理
14.3.2參數(shù)傳遞實現(xiàn)
14.3.3運行效果
14.4本章小結(jié)
第15章實現(xiàn)系統(tǒng)調(diào)用
15.1基本概念
15.1.1系統(tǒng)調(diào)用
15.1.2用戶態(tài)與內(nèi)核態(tài)
15.2特權(quán)級設(shè)置
15.2.1特權(quán)級劃分
15.2.2特權(quán)級機制
15.2.3特權(quán)級配置
15.2.4保護(hù)機制
15.3實現(xiàn)原理
15.4添加msleep()
15.4.1構(gòu)造系統(tǒng)調(diào)用函數(shù)
15.4.2執(zhí)行Trap指令
15.4.3執(zhí)行系統(tǒng)調(diào)用
15.4.4運行效果
15.5添加更多系統(tǒng)調(diào)用
15.5.1添加方法
15.5.2運行效果
15.6本章小結(jié)
第16章支持內(nèi)存分配和printf()打印
16.1Newlib的底層依賴
16.1.1什么是C語言標(biāo)準(zhǔn)庫
16.1.2樁函數(shù)
16.2支持動態(tài)內(nèi)存分配
16.2.1基本原理
16.2.2實現(xiàn)sbrk()系統(tǒng)調(diào)用
16.2.3運行效果
16.3支持printf()打印
16.3.1基本原理
16.3.2具體實現(xiàn)
16.3.3運行效果
16.4本章小結(jié)
第17章實現(xiàn)命令行解釋器
17.1shell的功能
17.2實現(xiàn)原理
17.3具體實現(xiàn)
17.3.1打開文件描述符
17.3.2讀取命令行
17.3.3解析命令
17.3.4判斷是否是內(nèi)置命令
17.3.5執(zhí)行內(nèi)置命令
17.4運行效果
17.5本章小結(jié)
第18章進(jìn)程的創(chuàng)建與退出
18.1創(chuàng)建測試工程
18.1.1創(chuàng)建工程結(jié)構(gòu)
18.1.2編譯結(jié)果分析
18.2利用fork()創(chuàng)建子進(jìn)程
18.2.1fork()簡介
18.2.2實現(xiàn)原理
18.2.3實現(xiàn)fork()系統(tǒng)調(diào)用
18.2.4實現(xiàn)getpid()系統(tǒng)調(diào)用
18.2.5運行效果
18.3利用execve()加載可執(zhí)行程序
18.3.1execve簡介
18.3.2實現(xiàn)原理
18.3.3實現(xiàn)execve()系統(tǒng)調(diào)用
18.3.4實現(xiàn)sys_execve()
18.3.5execve()執(zhí)行流程
18.3.6運行效果
18.4進(jìn)程退出
18.4.1相關(guān)系統(tǒng)調(diào)用
18.4.2實現(xiàn)_exit()系統(tǒng)調(diào)用
18.4.3實現(xiàn)wait()系統(tǒng)調(diào)用
18.4.4設(shè)置root_task
18.4.5運行效果
18.5支持加載程序運行
18.6進(jìn)程異常退出
18.7多個shell同時運行
18.8本章小結(jié)