本書是一本有關(guān)Linux操作系統(tǒng)內(nèi)核基本工作原理的入門讀物。
本書的主要目標
本書的主要目標是使用盡量少的篇幅,對完整的Linux內(nèi)核源代碼進行解剖,使讀者對操作系統(tǒng)的基本功能和實際實現(xiàn)方式獲得全方位的理解。
本書讀者應(yīng)是知曉Linux系統(tǒng)的一般使用方法或具有一定的編程基礎(chǔ),但比較缺乏閱讀目前最新內(nèi)核源代碼的基礎(chǔ)知識,又急切希望能夠進一步理解IJNIX類操作系統(tǒng)內(nèi)核工作原理和實際代碼實現(xiàn)的愛好者。這部分讀者的水平應(yīng)該界于初級與中級水平之間。目前,這部分讀者人數(shù)在Linux愛好者中所占的比例是很高的,而面向這部分讀者以比較易懂和有效的手段講解內(nèi)核的書籍資料不多。 現(xiàn)有書籍不足之處 目前已有的描述Linux內(nèi)核的書籍,均盡量選用最新Linux內(nèi)核版本(例如Fedora 8使用的2.6.24穩(wěn)定版等)進行描述,但由于目前Linux內(nèi)核整個源代碼的大小已經(jīng)非常大(例如2.2.20版就已具有268萬行代碼!),因此這些書籍僅能對LJnux內(nèi)核源代碼進行選擇性或原理性的說明,許多系統(tǒng)實現(xiàn)細節(jié)被忽略。因此并不能使讀者對實際L,inux內(nèi)核有清晰而完整的理解。
Scott Maxwell的《Linux內(nèi)核源代碼分析》基本上是面對Linux中、高級水平的讀者,需要較為全面的基礎(chǔ)知識才能完全理解。而且可能是由于篇幅所限,該書并沒有對所有Linux內(nèi)核代碼進行注釋,略去了很多內(nèi)核實現(xiàn)細節(jié),例如內(nèi)核中使用的各個頭文件(*.h)、生成內(nèi)核代碼映像文件的工具程序、各個make文件的作用和實現(xiàn)等均沒有涉及。因此對于處于初、中級水平之間的讀者來說閱讀該書有些困難。
John Lions的《萊昂氏LINIX源代碼分析》雖然是一本學(xué)習(xí)UNIX類操作系統(tǒng)內(nèi)核源代碼很好的書,但是由于其采用的是UNIX V6版,其中系統(tǒng)調(diào)用等部分代碼是用早已廢棄的PDP.11系列機的匯編語言編制的,因此在閱讀和理解與硬件部分相關(guān)的源代碼時就會遇到較大的困難。
A.S.Tanenbaum的《操作系統(tǒng):設(shè)計與實現(xiàn)》是有關(guān)操作系統(tǒng)內(nèi)核實現(xiàn)很好的入門書籍,但該書所敘述的M1NⅨ系統(tǒng)是一種基于消息傳遞的內(nèi)核實現(xiàn)機制,與IAnux內(nèi)核的實現(xiàn)有所區(qū)別。因此在學(xué)習(xí)該書之后,并不能很順利地即刻著手進一步學(xué)習(xí)較新的Linux內(nèi)核源代碼實現(xiàn)。
在使用這些書籍進行學(xué)習(xí)時會有一種“盲人摸象”的感覺,不容易真正理解Linux內(nèi)核系統(tǒng)具體實現(xiàn)的整體概念,尤其是對那些Linux系統(tǒng)初學(xué)者,或剛學(xué)會如何使用Linux系統(tǒng)的人在使用那些書學(xué)習(xí)內(nèi)核原理時,內(nèi)核的整體運作結(jié)構(gòu)并不能清晰地在腦海中形成。這在本人多年的Linux內(nèi)核學(xué)習(xí)過程中也深有體會。在1991年10月,Linux的創(chuàng)始人Linus’Forvalds在開發(fā)出Linux 0.03版后寫的一篇文章中也提到了同樣的問題。在這篇題為《IJnux-aFree unix.386Kernel》目的文章中,他說:“開發(fā)Linux是為了那些操作系統(tǒng)愛好者和計算機科學(xué)系的學(xué)生使用、學(xué)習(xí)和娛樂”!白杂绍浖饡腉N2J Hurd系統(tǒng)如果開發(fā)出來就已經(jīng)顯得太龐大而不適合學(xué)習(xí)和理解!
序
第1章 概述
1.1 Linux的誕生和發(fā)展
1.1.1 UNIX操作系統(tǒng)的誕生
1.1.2 MINIX操作系統(tǒng)
1.1.3 GNU計劃
1.1.4 POSIX標準
1.1.5 Linux操作系統(tǒng)的誕生
1.1.6 Linux操作系統(tǒng)版本的變遷
1.1.7 Linux名稱的由來
1.1.8 早期Linux系統(tǒng)開發(fā)的主要貢獻者
1.2 內(nèi)容綜述
1.3 本章小結(jié)
第2章 微型計算機組成結(jié)構(gòu)
2.1 微型計算機組成原理
2.2 I/O端口尋址和訪問控制方式
2.2.1 I/O端口和尋址
2.2.2 接口訪問控制
2.3 主存儲器、BIOS和CMOS存儲器
2.3.1 主存儲器
2.3.2 基本輸入/輸出程序BIOS
2.3.3 CMOS存儲器
2.4 控制器和控制卡
2.4.1 中斷控制器
2.4.2 DMA控制器
2.4.3 定時/計數(shù)器
2.4.4 鍵盤控制器
2.4.5 串行控制卡
2.4.6 顯示控制
2.4.7 軟盤和硬盤控制器
2.5 本章小結(jié)
第3章 內(nèi)核編程語言和環(huán)境
3.1 as86匯編器
3.1.1 as86匯編語言語法
3.1.2 as86匯編語言程序
3.1.3 as86匯編語言程序的編譯和鏈接
3.1.4 as86和1d86使用方法和選項
3.2 CNU as匯編
3.2.1 編譯as匯編語言程序
3.2.2 as匯編語法
3.2.3 指令語句、操作數(shù)和尋址
3.2.4 區(qū)與重定位
3.2.5 符號
3.2.6 as匯編命令
3.2.7 編寫16位代碼
3.2.8 AS匯編器命令行選項
3.3 C語言程序
3.3.1 C程序編譯和鏈接
3.3.2 嵌入?yún)R編
3.3.3 圓括號中的組合語句
3.3.4 寄存器變量
3.3.5 內(nèi)聯(lián)函數(shù)
3.4 C與匯編程序的相互調(diào)用
3.4.1 C函數(shù)調(diào)用機制
3.4.2 在匯編程序中調(diào)用C函數(shù)
3.4.3 在C程序中調(diào)用匯編函數(shù)
3.5 Linux 0.12目標文件格式
3.5.1 目標文件格式
3.5.2 Linux0.12中的目標文件格式
3.5.3 鏈接程序輸出
3.5.4 鏈接程序預(yù)定義變量一
3.5.5 System.map文件
3.6 Make程序和Makefile文件
3.6.1 Makefite文件內(nèi)容
3.6.2 Makefile文件中的規(guī)則
3.6.3 Makefile文件示例
3.6.4 make處理Makefile文件的方式
3.6.5 Makefile中的變量
3.6.6 讓make自動推斷命令
3.6.7 隱含規(guī)則中的自動變量
3.7本章 小結(jié)
第4章 80x86保護模式及其編程
4.1 80x86系統(tǒng)寄存器和系統(tǒng)指令
4.1.1 標志寄存器
4.1.2 內(nèi)存管理寄存器
4.1.3 控制寄存器
4.1.4 系統(tǒng)指令
4.2 保護模式內(nèi)存管理
4.2.1 內(nèi)存尋址
4.2.2 地址變換
4.2.3 保護
4.3 分段機制
4.3.1 段的定義
4.3.2 段描述符表
4.3.3 段選擇符
4.3.4 段描述符
4.3.5 代碼和數(shù)據(jù)段描述符類型
4.3.6 系統(tǒng)描述符類型
4.4 分頁機制
4.4.1 頁表結(jié)構(gòu)
4.4.2 頁表項格式
4.4.3 虛擬存儲
4.5 保護
4.5.1 段級保護
4.5.2 訪問數(shù)據(jù)段時的特權(quán)級檢查
4.5.3 代碼段之間轉(zhuǎn)移控制時的特權(quán)級檢查
4.5.4 頁級保護
4.5.5 組合頁級和段級保護
4.6 中斷和異常處理
4.6.1 異常和中斷向量
4.6.2 中斷源和異常源
4.6.3 異常分類
4.6.4 程序或任務(wù)的重新執(zhí)行
4.6.5 開啟和禁止中斷
4.6.6 異常和中斷的優(yōu)先級
4.6.7 中斷描述符表
4.6.8 IDT描述符
4.6.9 異常與中斷處理
4.6.10 中斷處理任務(wù)
4.6.11 錯誤碼
4.7 任務(wù)管理
4.7.1 任務(wù)的結(jié)構(gòu)和狀態(tài)
4.7.2 任務(wù)的執(zhí)行
4.7.3 任務(wù)管理數(shù)據(jù)結(jié)構(gòu)
4.7.4 任務(wù)切換
4.7.5 任務(wù)鏈
4.7.6 任務(wù)地址空間
4.8 保護模式編程初始化
4.8.1 進入保護模式時的初始化操作
4.8.2 模式切換
4.9 一個簡單的多任務(wù)內(nèi)核實例
4.9.1 多任務(wù)程序結(jié)構(gòu)和工作原理
4.9.2 引導(dǎo)啟動程序boot.s
4.9.3 多任務(wù)內(nèi)核程序head.s
第5章 Linux內(nèi)核體系結(jié)構(gòu)
5.1 Linux內(nèi)核模式
5.2 Linux內(nèi)核系統(tǒng)體系結(jié)構(gòu)
5.3 Linux內(nèi)核對內(nèi)存的管理和使用
5.3.1 物理內(nèi)存
5.3.2 內(nèi)存地址空間概念
5.3.3 內(nèi)存分段機制
5.3.4 內(nèi)存分頁管理
5.3.5 CPu多任務(wù)和保護方式
5.3.6 虛擬地址、線性地址和物理地址之間的關(guān)系
5.3.7 用戶申請內(nèi)存的動態(tài)分配
5.4 中斷機制
5.4.1 中斷操作原理
5.4.2 80x86微機的中斷子系統(tǒng)
5.4.3 中斷向量表
5.4.4 I.inux內(nèi)核的中斷處理
5.4.5 標志寄存器的中斷標志
5.5 Linux的系統(tǒng)調(diào)用
5.5.1 系統(tǒng)調(diào)用接口
5.5.2 系統(tǒng)調(diào)用處理過程
5.5.3 Linux系統(tǒng)調(diào)用的參數(shù)傳遞方式
5.6 系統(tǒng)時間和定時
5.6.1 系統(tǒng)時間
5.6.2 系統(tǒng)定時
5.7 Linux進程控制
5.7.1 任務(wù)數(shù)據(jù)結(jié)構(gòu)
5.7.2 進程運行狀態(tài)
5.7.3 進程初始化
5.7.4 創(chuàng)建新進程
5.7.5 進程調(diào)度
5.7.6 終止進程
5.8 Linux系統(tǒng)中堆棧的使用方法
5.8.1 初始化階段
5.8.2 任務(wù)的堆棧
5.8.3 任務(wù)內(nèi)核態(tài)堆棧與用戶態(tài)堆棧之間的切換
5.9 Linux0.12采用的文件系統(tǒng)
5.10 Linux內(nèi)核源代碼的目錄結(jié)構(gòu)
5.10.1 內(nèi)核主目錄linux
5.10.2 引導(dǎo)啟動程序目錄boot
5.10.3 文件系統(tǒng)目錄fs
5.10.4 頭文件主目錄include
5.10.5 內(nèi)核初始化程序目錄init
5.10.6 內(nèi)核程序主目錄kernel
5.10.7 內(nèi)核庫函數(shù)目錄lib
5.10.8 內(nèi)存管理程序目錄mm
5.10.9 編譯內(nèi)核工具程序目錄tools
5.1l 內(nèi)核系統(tǒng)與應(yīng)用程序的關(guān)系
5.12 linux/MakeftIe文件
5.12.1 功能描述
5.12.2 代碼注釋
5.13 本章 小結(jié)
第6章 引導(dǎo)啟動程序
6.1 總體功能
6.2 bootsect.S程序
6.2.1 功能描述
6.2.2 代碼注釋
6.2.3 其他信息
6.3 setup.S程序
6.3.1 功能描述
6.3.2 代碼注釋
6.3.3 其他信息
6.4 lead.s程序
6.4.1 功能描述
6.4.2 代碼注釋
6.4.3 其他信息
6.5 本章 小結(jié)
第7章 初始化程序
7.1 main.c程序
7.1.1 功能描述
7.1.2 代碼注釋
7.1.3 其他信息
7.2 環(huán)境初始化工作
7.3 本章 小結(jié)
第8章 內(nèi)核代碼
8.1 總體功能
8.1.1 中斷處理程序
8.1.2 系統(tǒng)調(diào)用處理相關(guān)程序
8.1.3 其他通用類程序
8.2 asm.s程序
8.2.1 功能描述
8.2.2 代碼注釋
8.2.3 Intel保留中斷向量的定義
8.3 traps.c程序
8.3.1 功能描述
8.3.2 代碼注釋
8.4 syscall.s程序
8.4.1 功能描述
8.4.2 代碼注釋
8.4.3 其他信息
8.5 mktime.c程序
8.5.1 功能描述
8.5.2 代碼注釋
8.5.3 閏年的計算方法
8.6 sched.c程序
8.6.1 功能描述
8.6.2 代碼注釋
8.6.3 其他信息
8.7 signal.c程序
8.7.1 功能描述
8.7.2 代碼注釋
8.7.3 進程信號說明
8.8 exit.c程序
8.8.1 功能描述
8.8.2 代碼注釋
8.9 fork.c程序
8.9.1 功能描述
8.9.2 代碼注釋
8.9.3 任務(wù)狀態(tài)段信息
8.10 sys.c程序
8.10.1 功能描述
8.10.2 代碼注釋
8.1l vsprimtfc程序
8.11.1 功能描述
8.11.2 代碼注釋
8.11.3 vsprintf的格式字符串
8.11.4 與當(dāng)前版本的區(qū)別
8.12 printk.c程序
8.12.1 功能描述
8.12.2 代碼注釋
8.13 panic.c程序
8.13.1 功能描述
8.13.2 代碼注釋
8.14 本章 小結(jié)
第9章 塊設(shè)備驅(qū)動程序
9.1 總體功能
9.1.1 塊設(shè)備請求項和請求隊列
9.1.2 塊設(shè)備訪問調(diào)度處理
9.1.3 塊設(shè)備操作方式
9.2 blk.h文件
9.2.1 功能描述
9.2.2 代碼注釋
9.3 hd.c程序
9.3.1 功能描述
9.3.2 代碼注釋
9.3.3 其他信息
9.4 nrwblk.c程序
9.4.1 功能描述
9.4.2 代碼注釋
9.5 ramdisk.c程序
9.5.1 功能描述
9.5.2 代碼注釋
9.6 floppy.c程序
9.6.1 功能描述
9.6.2 代碼注釋
9.6.3 其他信息
第10章 字符設(shè)備驅(qū)動程序
10.1 總體功能
10.1.1 終端驅(qū)動程序基本原理
10.1.2 Linux支持的終端設(shè)備類型
10.1.3 終端基本數(shù)據(jù)結(jié)構(gòu)
lO.1.4 規(guī)范模式和非規(guī)范模式
10.1.5 控制臺終端和串行終端設(shè)備
10.1.6 終端驅(qū)動程序接口
10.2 keyboard.S程序
10.2.1 功能描述
10.2.2 代碼注釋
10.2.3 其他信息
10.3 console.c程序
10.3.1 功能描述
10.3.2 代碼注釋
10.3.3 其他信息
10.4 serial.c程序
10.4.l 功能描述
10.4.2 代碼注釋
lO.4.3 異步串行通信控制器UART
10.5 rsio.s程序
10.5.1 功能描述
10.5.2 代碼注釋
10.6 ttyi0.c程序
10.6.1 功能描述
10.6.2 代碼注釋
10.6.3 控制字符vnME、VMlN
10.7 ttyjoctl.c程序
10.7.1 功能描述
10.7.2 代碼注釋
第11章 數(shù)學(xué)協(xié)處理器
第12章 文件系統(tǒng)
第13章 內(nèi)存管理
第14章 頭文件
第15章 庫文件
第16章 建造工具
第17章 實驗環(huán)境設(shè)置與使用方法
附錄
參考文獻
第1章 概述
本章首先回顧了Linux操作系統(tǒng)的誕生、開發(fā)和成長過程,由此讀者可以理解本書選擇Linux系統(tǒng)早期版本作為學(xué)習(xí)對象的一些原因;然后具體說明了選擇早期Linux內(nèi)核版本進行學(xué)習(xí)的優(yōu)點和不足之處以及如何開始進一步學(xué)習(xí);最后對各章的內(nèi)容進行了簡要介紹。
1.1 Linux的誕生和發(fā)展
Linux操作系統(tǒng)是UNIX操作系統(tǒng)的一種克隆系統(tǒng)。它誕生于1991年10月5日(這是第一次正式向外公布的時間)。此后借助于Internet網(wǎng)絡(luò),經(jīng)過全世界計算機愛好者的共同努力,現(xiàn)已成為當(dāng)今使用最多的一種UNIX類操作系統(tǒng),并且使用人數(shù)還在迅猛增長。
Linux操作系統(tǒng)的誕生、發(fā)展和成長過程依賴于以下五個重要支柱:UNIX操作系統(tǒng)、MINIX操作系統(tǒng)、GNU計劃、POSIX標準和Internet。下面根據(jù)這五個基本線索來回顧一下Linux的醞釀過程、開發(fā)歷程以及最初的發(fā)展。首先分別介紹其中的四個基本要素,然后根據(jù)Linux的創(chuàng)始人Linus Torvalds從對計算機感興趣而自學(xué)計算機知識,到心里開始醞釀編制一個自己的操作系統(tǒng),到最初Linux內(nèi)核0.O1版公布以及從此如何艱難地一步一個腳印地在全世界黑客的幫助下推出比較完善的1.0版本這段經(jīng)過,對Linux的早期發(fā)展歷史進行詳細介紹。
當(dāng)然,目前Linux內(nèi)核版本已經(jīng)開發(fā)到了2.6.X版。而大多數(shù)Linux系統(tǒng)中所用到的內(nèi)核是穩(wěn)定的2.6.12版內(nèi)核(其中第2個數(shù)字若是奇數(shù)則表示正在開發(fā)的版本,不能保證系統(tǒng)的穩(wěn)定性)。對于Linux的一般發(fā)展史,許多文章和書籍都有介紹,這里不再重復(fù)。
1.1.1 UNIX操作系統(tǒng)的誕生
UNIX操作系統(tǒng)最早是美國貝爾實驗室的Ken Thompson于1969年夏在DEC PDP-7小型計算機上開發(fā)的一個分時操作系統(tǒng)。
Ken Thompson為了能在閑置不用的PDP-7計算機上運行他非常喜歡的星際旅行(Star Trek)游戲,于1969年夏天趁他夫人回家鄉(xiāng)加利福尼亞度假期間,在一個月內(nèi)開發(fā)出了UNIX操作系統(tǒng)的原型。當(dāng)時使用的是BCPL語言(基本組合編程語言),后經(jīng)Dennis Ritchie于1972年用移植性很強的C語言進行了改寫,使得UNIX系統(tǒng)在大學(xué)得到了推廣。