本書對早期的Linux操作系統(tǒng)內(nèi)核(v0.11)全部源代碼文件進行了詳細的注釋和說明,旨在讓讀者能夠在短時間內(nèi)對Linux的工作機理獲得全面而深刻的理解,為進一步學(xué)習(xí)和研究Linux系統(tǒng)打下堅實的基礎(chǔ)。書中首先介紹了Linux系統(tǒng)的發(fā)展歷史,著重說明了各個內(nèi)核版本之間的重要區(qū)別,給出了選擇0.11版作為研究對象的原因;然后依據(jù)內(nèi)核源代碼的組織結(jié)構(gòu)對所有代碼進行了詳細注釋。在注釋的同時,還介紹了讀者應(yīng)該了解的相關(guān)知識,并給出了相關(guān)的硬件信息。本書還介紹了內(nèi)核源代碼的組織結(jié)構(gòu)及相互關(guān)系。
趙炯博士的Linux內(nèi)核源碼書系列自從問世以來,在全國乃至世界范圍內(nèi)產(chǎn)生了很大影響。第一批讀者受惠良多,早已成為IT大廠的中堅力量。20年過去了,Linux內(nèi)核的體量發(fā)生了巨大變化,這更加凸顯了“從小內(nèi)核學(xué)起”的理念的正確。閱讀本書,會幫助讀者少走彎路,快速理解Linux的精髓,早日成長為合格的開發(fā)人員和系統(tǒng)架構(gòu)師。
本書是一本有關(guān)Linux操作系統(tǒng)內(nèi)核工作原理的入門讀物,主要目標是使用盡量少的篇幅和有限的學(xué)習(xí)時間,對完整的Linux內(nèi)核源代碼進行解剖,使讀者對操作系統(tǒng)的基本功能和實現(xiàn)方式有一個全面的理解。
目前已有的闡述Linux內(nèi)核的書籍,均盡量選用最新Linux內(nèi)核版本進行描述,但由于這些版本的內(nèi)核源代碼龐大,只能對源代碼進行選擇性的講解,許多實現(xiàn)細節(jié)被忽略。本書則對完整的Linux內(nèi)核源代碼進行了全面解剖。表面看來,本書對Linux早期內(nèi)核版本注釋的內(nèi)容似乎過時,但通過學(xué)習(xí)你會發(fā)現(xiàn),利用本書學(xué)習(xí)Linux內(nèi)核,由于源代碼短小精干,因此會有極高的學(xué)習(xí)效率,能夠做到事半功倍,快速入門,并為進一步選擇新內(nèi)核學(xué)習(xí)打下堅實的基礎(chǔ)。
正如Linux系統(tǒng)的創(chuàng)始人Linus所說,要理解一個系統(tǒng)的真正運行機制,一定要閱讀其源代碼。系統(tǒng)本身是一個整體,具有很多看似不重要的細節(jié)。只有在詳細閱讀過完整的內(nèi)核源代碼之后,才會對整個系統(tǒng)的運作過程有深刻的理解。以后再選擇較新內(nèi)核源代碼進行學(xué)習(xí)時,也不會碰到大問題,基本上都能順利地理解新代碼的內(nèi)容。
為了幫助讀者提高學(xué)習(xí)效率,作者通過對多個Linux內(nèi)核版本進行比較和選擇,最終選擇了與目前Linux內(nèi)核基本功能較為相近,又非常短小的0.11版作為入門學(xué)習(xí)的最佳版本。0.11版內(nèi)核源代碼只有一萬四千行左右(325KB),其中包括的內(nèi)容基本上都是Linux系統(tǒng)的精髓。
在閱讀本書時,讀者應(yīng)該具備基本的有關(guān)80x86處理器編程和相關(guān)外圍硬件的知識,還應(yīng)具備使用Linux系統(tǒng)的初級技能。由于Linux最早是根據(jù)M.J.Bach的《UNIX操作系統(tǒng)設(shè)計》一書的基本原理開發(fā)的,因此若能適當參考該書,則更有利于對源代碼的理解。
在對每個程序進行描述時,我們首先說明程序的主要用途、輸入輸出參數(shù)以及與其他程序的關(guān)系,然后在程序中對代碼進行詳細注釋。注釋時對源代碼和原注釋不作任何改動。在代碼之后是對程序中出現(xiàn)的一些語句或硬件方面的相關(guān)知識進行說明。
本書所需的一些基本概念均分布在各章中,這樣編排主要是為了能夠使讀者方便地找到相關(guān)信息,而且在結(jié)合源代碼閱讀時,對一些基本概念能有更深的理解。另外,由于篇幅所限,我們對內(nèi)核源代碼多數(shù)文件開始處的版權(quán)信息作了省略,但程序中的行號仍然按原來的編號。
最后要說明的是,當你已經(jīng)完全理解了本文解說的一切時,并不代表你已經(jīng)成為一個Linux行家了,你只是剛剛踏上Linux的征途,具有了成為一個Linux高手的初步知識。這時你應(yīng)該去閱讀更多的源代碼。本書讀者群的定位是一些知曉Linux系統(tǒng)一般使用方法或具有一定編程經(jīng)驗,但比較缺乏閱讀目前最新內(nèi)核源代碼的基礎(chǔ),又急切希望能夠進一步理解類UNIX操作系統(tǒng)內(nèi)核工作原理和實際代碼實現(xiàn)的愛好者。在閱讀時可以參考為本書專門開設(shè)的網(wǎng)站www.oldlinux.org。從中可以下載到很多學(xué)習(xí)資料和上機實習(xí)軟件,也可以進行在線討論。
趙炯,工學(xué)博士,計算機專家,Intel公司訪問學(xué)者,國際計算機仿真協(xié)會、上海市通信學(xué)會會員。研究方向為計算機通信。曾經(jīng)為本科、碩士和博士研究生開設(shè)《計算機網(wǎng)絡(luò)》、《計算機通信技術(shù)》、《計算機通信與工控網(wǎng)絡(luò)》、《微型計算機》和《計算機原理》等課程。參與國家自然科學(xué)基金項目“系統(tǒng)芯片在線測試與容錯技術(shù)研究”和上海市自然科學(xué)基金“基于節(jié)點主動控制的大規(guī)模復(fù)雜輸送系統(tǒng)控制模型研究”等工作。
前言
第1章概述1
1.1 Linux的誕生和發(fā)展1
1.1.1 UNIX、MINIX、GNU和POSIX1
1.1.2 Linux操作系統(tǒng)的誕生和版本的變遷1
1.2 內(nèi)容綜述3
1.3 本章小結(jié)5
1.4 習(xí)題6
第2章Linux內(nèi)核體系結(jié)構(gòu)7
2.1 Linux內(nèi)核模式和體系結(jié)構(gòu)7
2.2 Linux中斷機制9
2.3 Linux系統(tǒng)定時10
2.4 Linux內(nèi)核進程控制11
2.4.1 任務(wù)數(shù)據(jù)結(jié)構(gòu)11
2.4.2 進程運行狀態(tài)11
2.4.3 進程初始化12
2.4.4 創(chuàng)建新進程14
2.4.5 進程調(diào)度14
2.4.6 終止進程15
2.5 Linux內(nèi)核對內(nèi)存的使用方法16
2.6 Linux系統(tǒng)中堆棧的使用方法19
2.6.1 初始化階段19
2.6.2 任務(wù)的堆棧20
2.6.3 內(nèi)核態(tài)與用戶態(tài)堆棧之間的切換21
2.7 Linux內(nèi)核源代碼的目錄結(jié)構(gòu)21
2.7.1 引導(dǎo)啟動程序目錄boot22
2.7.2 文件系統(tǒng)目錄fs22
2.7.3 頭文件主目錄include23
2.7.4 內(nèi)核初始化程序目錄init23
2.7.5 內(nèi)核程序主目錄kernel24
2.7.6 內(nèi)核庫函數(shù)目錄lib25
2.7.7 內(nèi)存管理程序目錄mm26
2.7.8 編譯內(nèi)核工具程序目錄tools26
2.8 內(nèi)核系統(tǒng)與用戶程序的關(guān)系26
2.9 Linux內(nèi)核的編譯實驗環(huán)境26
2.10 linux/Makefile文件28
2.11 本章小結(jié)34
2.12 習(xí)題35
第3章內(nèi)核引導(dǎo)啟動程序36
3.1 總體功能描述36
3.2 程序分析37
3.2.1 bootsect.s程序37
3.2.2 setup.s程序44
3.2.3 head.s程序52
3.3 本章小結(jié)60
3.4 習(xí)題60
第4章內(nèi)核初始化過程61
4.1 main.c程序分析61
4.2 本章小結(jié)68
4.3 習(xí)題69
第5章進程調(diào)度與系統(tǒng)調(diào)用70
5.1 總體功能描述70
5.1.1 中斷處理程序70
5.1.2 系統(tǒng)調(diào)用處理相關(guān)程序71
5.2 程序分析72
5.2.1 asm.s程序72
5.2.2 traps.c程序77
5.2.3 systemcall.s程序83
5.2.4 mktime.c程序91
5.2.5 sched.c程序92
5.2.6 signal.c程序103
5.2.7 exit.c程序108
5.2.8 fork.c程序112
5.2.9 sys.c程序117
5.2.10 vsprintf.c程序122
5.2.11 printk.c程序127
5.2.12 panic.c程序128
5.3 本章小結(jié)129
5.4 習(xí)題129
第6章輸入輸出系統(tǒng)——塊設(shè)備驅(qū)動程序130
6.1 總體功能描述130
6.1.1 塊設(shè)備請求項和請求隊列130
6.1.2 塊設(shè)備操作方式132
6.2 程序分析133
6.2.1 blk.h文件133
6.2.2 hd.c程序136
6.2.3 llrwblk.c程序149
6.2.4 ramdisk.c程序154
6.2.5 floppy.c程序157
6.3 本章小結(jié)170
6.4 習(xí)題170
第7章輸入輸出系統(tǒng)——字符設(shè)備驅(qū)動程序171
7.1 總體功能描述171
7.1.1 終端驅(qū)動程序基本原理171
7.1.2 終端基本數(shù)據(jù)結(jié)構(gòu)172
7.1.3 規(guī)范模式和非規(guī)范模式174
7.1.4 控制臺驅(qū)動程序175
7.1.5 串行終端驅(qū)動程序176
7.1.6 終端驅(qū)動程序接口177
7.2 程序分析177
7.2.1 keyboard.S程序177
7.2.2 console.c程序191
7.2.3 serial.c程序210
7.2.4 rsio.s程序213
7.2.5 tty_io.c程序216
7.2.6 tty_ioctl.c程序225
7.3 本章小結(jié)230
7.4 習(xí)題230
第8章數(shù)學(xué)協(xié)處理器231
8.1 mathemulation.c程序分析231
8.2 本章小結(jié)232
8.3 習(xí)題232
第9章文件系統(tǒng)233
9.1 總體功能描述233
9.1.1 MINIX文件系統(tǒng)233
9.1.2 高速緩沖區(qū)237
9.1.3 文件系統(tǒng)底層函數(shù)237
9.1.4 文件中數(shù)據(jù)的訪問操作237
9.2 程序分析239
9.2.1 buffer.c程序239
9.2.2 bitmap.c程序251
9.2.3 inode.c程序255
9.2.4 super.c程序264
9.2.5 namei.c程序272
9.2.6 filetable.c程序292
9.2.7 blockdev.c程序292
9.2.8 filedev.c程序295
9.2.9 pipe.c程序297
9.2.10 chardev.c程序300
9.2.11 readwrite.c程序303
9.2.12 truncate.c程序306
9.2.13 open.c程序307
9.2.14 exec.c程序312
9.2.15 stat.c程序322
9.2.16 fcntl.c程序323
9.2.17 ioctl.c程序325
9.3 本章小結(jié)326
9.4 習(xí)題326
第10章內(nèi)存管理328
10.1 總體功能描述328
10.1.1 內(nèi)存分頁管理機制328
10.1.2 Linux中內(nèi)存的管理和分配331
10.1.3 寫時復(fù)制機制332
10.2 程序分析332
10.2.1 memory.c程序332
10.2.2 page.s程序345
10.3 本章小結(jié)346
10.4 習(xí)題346
第11章包含文件347
11.1 程序分析347
11.1.1 include/目錄下的文件347
11.1.2 a.out.h文件347
11.1.3 const.h文件356
11.1.4 ctype.h文件356
11.1.5 errno.h文件357
11.1.6 fcntl.h文件359
11.1.7 signal.h文件360
11.1.8 stdarg.h文件362
11.1.9 stddef.h文件363
11.1.10 string.h文件363
11.1.11 termios.h文件372
11.1.12 time.h文件379
11.1.13 unistd.h文件380
11.1.14 utime.h文件385
11.1.15 incl