版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
本書(shū)對(duì)Linux早期操作系統(tǒng)內(nèi)核(v0.11)全部代碼文件進(jìn)行了詳細(xì)全面的注釋和說(shuō)明,旨在使讀者能夠在盡量短的時(shí)間LINUX工作原理的精髓,通過(guò)閱讀其源代碼能快速地完全理解內(nèi)核的運(yùn)作的重要區(qū)別和改進(jìn)方面,給出了選擇0.11(0.95)版作為研究的對(duì)象的原因。另外介紹了內(nèi)核源代碼的組織結(jié)構(gòu)及相互關(guān)系,版本的主要區(qū)別等部分。最后一章內(nèi)容總結(jié)性地介紹了繼續(xù)研究Linux系統(tǒng)的方法和著手點(diǎn)。作者保留本籍的修改和正式的所利.讀者可以自由本書(shū)全部和部分章節(jié)的內(nèi)容,但需要注明出處.由于目前本書(shū)尚為草稿階段,因此存在許多錯(cuò)誤和不足之處,希望讀者能踴躍給予批評(píng)指正或建議.(息:gohigh@sh163net,或直接來(lái)信至:同濟(jì)大學(xué)機(jī)械電子工 (?2002,2003,2004byZhao?2002,2003,2004趙炯“RTFSC–ReadTheF**kingSourceCode–LinusBenedict序 EXT2文件系統(tǒng)與MINIX文件系 第1章概 第2章LINUX內(nèi)核體系結(jié) 第3章引導(dǎo)啟動(dòng)程序 第4章初始化程序 第5章內(nèi)核代碼
第6章塊設(shè)備驅(qū)動(dòng)程序(BLOCK 第7章字符設(shè)備驅(qū)動(dòng)程序(CHAR 第8章數(shù)學(xué)協(xié)處理器 第9章文件系統(tǒng) 第10章內(nèi)存管理 第11章頭文件
第12章庫(kù)文件 第13章建造工具 第14章實(shí)驗(yàn)環(huán)境設(shè)置與使用方 附 附錄1內(nèi)核主要常 附錄2內(nèi)核數(shù)據(jù)結(jié) 索 Linux內(nèi)核源代碼進(jìn)行解剖,以linux內(nèi)核有一個(gè)完整而深刻的理解,對(duì)linux操作系統(tǒng)的基本工作原理真正理解和。Linux系統(tǒng)的一般使用方法或具有一定的編程基礎(chǔ),但比較缺乏閱讀目前內(nèi)核源代碼的基礎(chǔ)知識(shí),又急切希望能夠進(jìn)一步理解UNIX類(lèi)操作系統(tǒng)內(nèi)核工作原理和實(shí)際代碼實(shí)現(xiàn)的者。這部分讀者的水平應(yīng)該界于初級(jí)與中級(jí)水平之間。目前,這部分讀者人數(shù)在Linux愛(ài)好者中所占的比例是很高的,而面向這部分讀者以比較易懂和有效的講解內(nèi)核的書(shū)籍資料不多。穩(wěn)定版等)Linux內(nèi)核整個(gè)源代碼的大小已經(jīng)非常得大(2.2.20268萬(wàn)行代碼!被忽略。因此并不能給予讀者對(duì)實(shí)際Linux內(nèi)核有清晰而完整的理解。Linux內(nèi)核文件的工具程序、各個(gè)make文件的作用等均沒(méi)有涉及。因此對(duì)于處于初中級(jí)水平之間的讀者來(lái)說(shuō)閱讀該書(shū)有些。浙江大學(xué)的《Linux內(nèi)核源代碼情景分析》一書(shū),也基本有這些不足之處。甚至對(duì)于一些具有Linux系統(tǒng)應(yīng)用水平的計(jì)算機(jī)本科高年級(jí)學(xué)生,由于該書(shū)篇幅問(wèn)題以及僅僅選擇性地講解內(nèi)核源代都會(huì)出現(xiàn)這個(gè)問(wèn)題。該書(shū)剛面市時(shí),本人曾極力勸說(shuō)學(xué)生購(gòu)之閱讀,并在二個(gè)月后閱讀學(xué)習(xí)情況,JohnLionsUNIXUNIX類(lèi)操作系統(tǒng)內(nèi)核源代碼很UNIXV6版,其中系統(tǒng)調(diào)用等部分代碼是用早已過(guò)時(shí)的PDP-11系列機(jī)的匯編語(yǔ)言編制的,因此在閱讀與硬件部分相關(guān)的源代碼時(shí)就會(huì)遇到較大的。A.S.Tanenbaum的書(shū)《操作系統(tǒng):設(shè)計(jì)與實(shí)現(xiàn)》是一本有關(guān)操作系統(tǒng)內(nèi)核實(shí)現(xiàn)很好的書(shū)籍,但學(xué)習(xí)該書(shū)之后,并不能很順利地即刻著手進(jìn)一步學(xué)習(xí)較新的Linux內(nèi)核源代碼實(shí)現(xiàn)。Linux內(nèi)核系統(tǒng)具體實(shí)現(xiàn)LinuxLinux系統(tǒng)的人在使用那些書(shū)學(xué)習(xí)內(nèi)核原理時(shí),內(nèi)核的整體運(yùn)作結(jié)構(gòu)并不能清晰地在腦海中形成。這在本人多年的Linux內(nèi)核學(xué)習(xí)過(guò)程中也深199110月份,LinuxLinusToravldsLinux0.03版后寫(xiě)的一篇文章中也提到了同樣的問(wèn)題。在這篇題為“LINUX--aunix-386kernelLinux是為了那些操作系統(tǒng)者和計(jì)算機(jī)科學(xué)系的學(xué)生使用、學(xué)習(xí)和。...自由軟件的GNUHurd系統(tǒng)如果開(kāi)發(fā)出來(lái)就已經(jīng)顯得太龐大而不適合學(xué)習(xí)和理解?!盠inuxGNUHurd系統(tǒng)更為L(zhǎng)inux內(nèi)核Linux內(nèi)核有一個(gè)完整而深刻的理解,對(duì)Linux操作系統(tǒng)的基本工作原理真正理解和。目前,已經(jīng)出現(xiàn)不少基于Linux早期內(nèi)核而開(kāi)發(fā)的專(zhuān)門(mén)用于嵌入式系統(tǒng)的內(nèi)核版本,如DJJ的x86操作系統(tǒng)、Uclinux等(在 上有專(zhuān)門(mén)),世界上也有許多人認(rèn)識(shí)到通過(guò)早期Linux內(nèi)核早期內(nèi)核版本的源代碼,的確是學(xué)習(xí)Linux系統(tǒng)的一種行之有效的途徑,并且對(duì)研究和應(yīng)用Linux嵌入.計(jì)算機(jī)(SIC)系統(tǒng)來(lái)說(shuō)明所有系統(tǒng)程序的設(shè)計(jì)原理,從而既避免了實(shí)際計(jì)算機(jī)系統(tǒng)的復(fù)雜性,又能Linux早期內(nèi)核版本不包含對(duì)虛擬文VFSa.out執(zhí)行文件和對(duì)其它一些現(xiàn)有內(nèi)核中復(fù)雜子系統(tǒng)的說(shuō)明。但由于本書(shū)是作為L(zhǎng)inux內(nèi)核工作機(jī)理實(shí)現(xiàn)的,因此這也正是選擇早期內(nèi)核版本的優(yōu)點(diǎn)正如Linux系統(tǒng)的創(chuàng)始人在一篇組投稿上所說(shuō)的,要理解一個(gè)軟件系統(tǒng)的真正運(yùn)行機(jī)制,一定不重要的細(xì)節(jié)存在,但是若忽略這些細(xì)節(jié),就會(huì)對(duì)整個(gè)系統(tǒng)的理解帶來(lái),并且不能真正了解一個(gè)實(shí)際系統(tǒng)的實(shí)現(xiàn)方法和。法耗費(fèi)大量的時(shí)間和篇幅而完全忽略I/O,其實(shí),前者通常不足一頁(yè)代碼,而后者往往要占到整個(gè)系統(tǒng)那么,如何選擇既能達(dá)到上述要求,又不被太多的內(nèi)容而頭腦,選擇一個(gè)適合的Linux內(nèi)核版核基本功能較為相近,又非常短小的0.11版內(nèi)核作為學(xué)習(xí)的最佳版本。下圖是對(duì)一些主要Linux內(nèi)Linux內(nèi)核源代碼量都在幾百萬(wàn)行的數(shù)量上,極其龐大,對(duì)這些版本進(jìn)行完全注釋和說(shuō)明幾文件系統(tǒng)VFS、ext2或ext3文件系統(tǒng)、網(wǎng)絡(luò)子系統(tǒng)、新的復(fù)雜的內(nèi)存管理機(jī)制等。理器結(jié)構(gòu)和編程的知識(shí)或資料。例如可以從網(wǎng)上的80x86編程手冊(cè)(IN80386Programmer'sManual其三還應(yīng)具備初級(jí)使用Linux系統(tǒng)的簡(jiǎn)單技能。LinusLinuxMINIXLinux內(nèi)核版本完全MINIX1.0文件系統(tǒng)。因此,在閱讀本書(shū)時(shí),A.S.Tanenbaum的書(shū)《操作系統(tǒng):設(shè)計(jì)與實(shí)現(xiàn)》也已經(jīng)過(guò)時(shí)的(Linuxisobsolete)Linux內(nèi)Linux操作系統(tǒng)上默認(rèn)的標(biāo)準(zhǔn)文件系統(tǒng)。但是,作為對(duì)Linux操作系統(tǒng)完整工作原理學(xué)習(xí)所使用的部分,原則上是越精簡(jiǎn)越好。為了達(dá)到對(duì)一個(gè)操作系Linux0.11MINIX1.0文件系統(tǒng),對(duì)于理解一個(gè)操作系統(tǒng)中文件系統(tǒng)的實(shí)際組成和工作原理已經(jīng)足夠。這也是選擇Linux早期內(nèi)核版本進(jìn)行學(xué)習(xí)的主要原因之一。此時(shí),您應(yīng)該有十分的把握去進(jìn)一步學(xué)習(xí)Linux內(nèi)核中各部分的工作原理和過(guò)程了。第1LinuxLinuxLinux內(nèi)核版本進(jìn)行學(xué)習(xí)的優(yōu)點(diǎn)和不LinuxUNIX1991105日(這是第一次正式向外公布的時(shí)間。此后借助于Internet網(wǎng)絡(luò),經(jīng)過(guò)全世界各地計(jì)算機(jī)者的共同努力,現(xiàn)已成為當(dāng)今世界上使用最多的一種UNIX類(lèi)操作系統(tǒng),并且使用人數(shù)還在迅猛增長(zhǎng)。Linux操作系統(tǒng)的誕生、發(fā)展和成長(zhǎng)過(guò)程依賴(lài)于以下五個(gè)重要支柱:UNIX操作系統(tǒng)、MINIX操作0.01hacker1.0版本這段時(shí)間的發(fā)展經(jīng)過(guò),也即對(duì)Linux的早期發(fā)展歷史進(jìn)行詳細(xì)介紹。Linux操作系統(tǒng)是UNIX操作系統(tǒng)的一個(gè)克隆版本。UNIX操作系統(tǒng)是貝爾KenThompsonPDP-7計(jì)算機(jī)上運(yùn)行他非常喜歡的星際旅行(Spacetravel)游BCPL語(yǔ)言(基本組合編程語(yǔ)言DennisRitchie1972C語(yǔ)言進(jìn)行了改寫(xiě),使得UNIX系統(tǒng)在大專(zhuān)院校得到了推廣。了100多篇文章,5本計(jì)算機(jī)書(shū)籍。AST雖出生在紐約,但卻是荷蘭僑民(1914年他的祖輩來(lái)到)。他在紐約上的中學(xué)、M.I.T上的大學(xué)、加洲大學(xué)Berkeley分校念的博士。由于讀博士后的緣故,他來(lái)到了家鄉(xiāng)荷蘭。從此就與家鄉(xiāng)一直有來(lái)往。后來(lái)就在Vrije大學(xué)開(kāi)始教書(shū)、帶。荷蘭首都Amsterdam是個(gè)常年陰雨綿綿的MINIX198719911.5。目前主要LinuxLinusLinux的發(fā)展很大原因是由于MINIXMINIX一直守護(hù)著的。GNU計(jì)劃和自由軟件FSF(theSoftwareFoundation)是由RichardM.Stallman于1984年一UNIX并且是自由軟件的完整操作系統(tǒng):GNU系統(tǒng)(GNU是"GNU'sNotNEW"用。雖然這些系統(tǒng)通常被稱(chēng)作"Linux"StallmanGNU/Linux系90年代初,GNUemacs編輯系統(tǒng)、bashs程序、gcc系列編譯程序、gdbLinux操作系統(tǒng)的開(kāi)發(fā)創(chuàng)造了一個(gè)合適的環(huán)境。這是Linux能夠誕生的基礎(chǔ)之一,以至于目前許多人都將Linux操作系統(tǒng)稱(chēng)為POSIX(PortableOperatingSystemInterfaceforComputingSystems)IEEEISO/IEC開(kāi)發(fā)的一UNIX實(shí)踐和經(jīng)驗(yàn),描述了操作系統(tǒng)的調(diào)用服務(wù)接口。用于保證編制的應(yīng)用程序可以在源代碼一級(jí)上在多種操作系統(tǒng)上移植和運(yùn)行。它是在1980年早期一個(gè)UNIX用戶(hù)組CSRG的BSD操作系統(tǒng)的調(diào)用接口之間的區(qū)別重新調(diào)和集成。并于1984年定制出了/usr/group標(biāo)準(zhǔn)。1985年,IEEE操作系統(tǒng)技術(shù)標(biāo)準(zhǔn)小組(TCOS-SS)開(kāi)始在ANSI的支持下責(zé)成IEEE標(biāo)準(zhǔn)制定有關(guān)程序源代碼可移植性操作系統(tǒng)服務(wù)接口正式標(biāo)準(zhǔn)。到了1986年4月,IEEE制定出19889月份批準(zhǔn)的(IEEE1003.1-1988),也既以后經(jīng)常提到的POSIX.1標(biāo)準(zhǔn)。9945-1:1990標(biāo)準(zhǔn)。(API,IEEEPOSIX的工作就開(kāi)始展開(kāi)了。剛開(kāi)始有十個(gè)批準(zhǔn)的計(jì)(POSIX.3UNIXLinuxLinux能夠在標(biāo)準(zhǔn)的指導(dǎo)下進(jìn)UNIXLinux內(nèi)核源代碼中(0.01版、0.11版)就了他正在著手一個(gè)操作系統(tǒng)的開(kāi)發(fā),并且在開(kāi)發(fā)之初已經(jīng)想到要實(shí)現(xiàn)與POSIX相兼容的問(wèn)題了。在1981年,IBM公司推出了享譽(yù)全球的微型計(jì)算機(jī)IBMPC。在1981-1991,MS-DOS操作系當(dāng)時(shí)Apple的MACs操作系統(tǒng)可以說(shuō)是性能最好的,但是其天價(jià)使得沒(méi)人能夠輕易靠近。而能在大學(xué)中用于教學(xué)的UNIX源代碼也一直被地守衛(wèi)著不許公開(kāi)。對(duì)于廣大的PC用戶(hù),軟正在此時(shí),出現(xiàn)了MINIX操作系統(tǒng),并且有一本描述其設(shè)計(jì)實(shí)現(xiàn)原理的書(shū)同時(shí)。由于AST的這本書(shū)寫(xiě)的非常詳細(xì),并且敘述得有條有理,于是幾乎全世界的計(jì)算機(jī)者都開(kāi)始看這本書(shū),以期能理解操作系統(tǒng)的工作原理。其中也包括Linux系統(tǒng)的創(chuàng)始者LinusBenedictTorvalds。當(dāng)時(shí)(1991年),LinusBenedictTorvalds是赫爾辛基大學(xué)計(jì)算機(jī)科學(xué)系的二年級(jí)學(xué)生,也是一個(gè)在同一,GNU計(jì)劃已經(jīng)開(kāi)發(fā)出了許多工具軟件。其中最受期盼的GNUC編譯器已經(jīng)出現(xiàn),但能得到源代碼。雖然GNU的操作系統(tǒng)HURD一直在開(kāi)發(fā)之中,但在當(dāng)時(shí)看來(lái)不能在幾年內(nèi)完成。為了能更好地學(xué)習(xí)計(jì)算機(jī)知識(shí)(或許也只是為了?,Linus使用圣誕節(jié)的壓歲錢(qián)和了一臺(tái)386兼容電腦,并從郵購(gòu)了一套MINIX系統(tǒng)軟件。就在等待MINIX軟件期間,Linus認(rèn)真學(xué)習(xí)了有關(guān)In80386的硬件知識(shí)。為了能通過(guò)Modem撥號(hào)連接到學(xué)校的主機(jī)上,他使用匯編語(yǔ)言并利用80386CPU的多任務(wù)特性編制出一個(gè)終端仿真程序。此后為了將自己一臺(tái)老式電腦上的軟件到新MINIX系統(tǒng)的諸多限制(MINIX雖然很好,但只是一個(gè)用GNU計(jì)正在開(kāi)發(fā)中。但Linus已經(jīng)等不急了。習(xí)MINIX系統(tǒng)階段發(fā)展到開(kāi)發(fā)自己的Linux系統(tǒng)的過(guò)程。doesn'toptimize”,gccMINIX-386系統(tǒng)上運(yùn)行優(yōu)化的問(wèn)題(MINIX-386Bruce這個(gè)想法逐步演變成想重新設(shè)計(jì)一個(gè)基于In80386體系結(jié)構(gòu)的新操作系統(tǒng)的構(gòu)思。(“RTFSC(19914月份開(kāi)始,LinusMINIX-386系統(tǒng)(Hackingthekernel),并且GNU的軟件到該系統(tǒng)上(GNUgcc、bash、gdb等)413comp.os.minix上發(fā)布說(shuō)自己已經(jīng)成功地將bashMINIX上,而且已經(jīng)愛(ài)不釋手、不能離開(kāi)這個(gè)s軟件了。Linux199173comp.os.minix上發(fā)布的(當(dāng)然,那時(shí)還不存在LinuxLinusFREAX?,F(xiàn)REAX的英文含義是怪誕的、怪物、在Linus另一個(gè)發(fā)布的消息中(1991825日comp.os.minix),他向所有MINIX用戶(hù)詢(xún)問(wèn)“Whatwouldyouliketoseeinminix?”(MINIX系統(tǒng)中見(jiàn)到什么?”),在該消息中他首次透露出正在版)和gcc(1.40版)移植到了新系統(tǒng)上,而且在過(guò)幾個(gè)月就可以實(shí)用了。最后,LinusMINIX386的任務(wù)切Linus當(dāng)時(shí)并沒(méi)有考慮。但是目前Linux幾乎可以運(yùn)行在任何一種硬件體系結(jié)構(gòu)上。到了1991年的10月5日,Linus在comp.os.minix組上發(fā)布消息,正式向外宣布Linux內(nèi)核系統(tǒng)的誕生(minix-likekernelsourcesfor386-AT。這段消息可以稱(chēng)為L(zhǎng)inux的誕生,并且一直廣這個(gè)日子。所以RedHat公司選擇這個(gè)日子發(fā)布它的新系統(tǒng)也不是偶然的。Linux0.130.95版,Linus1.0版還很遙遠(yuǎn)。同0.95版開(kāi)始,對(duì)內(nèi)核的許多改進(jìn)之處(補(bǔ)丁程序的提供)Linus的主要任務(wù)現(xiàn)在為止,版見(jiàn)表1–2所示。源代碼大小(gz壓縮后很不喜歡這個(gè)名稱(chēng)。他認(rèn)為既然是LinusLinux作為該操作系統(tǒng)的吧,于是Linux這個(gè)名稱(chēng)就開(kāi)始流傳下來(lái)。在Linus的自傳《JustforFun》一書(shū)中,Linus解釋說(shuō)Linux這個(gè)名稱(chēng)發(fā)布這個(gè)操作系統(tǒng),因?yàn)檫@個(gè)名字有些太自負(fù)了。而我為最終發(fā)布版準(zhǔn)備的是什么名字呢?FreaxMakefile用于描-文件中就已經(jīng)包含有“Freax”這個(gè)名字了,大約存在了半年左右。但其實(shí)這可以光明正大地說(shuō)我并不自負(fù),或者部分坦白地說(shuō)我并沒(méi)有本位。但好吧,這也是個(gè)好名從Linux早期源代碼中可以看出,LinuxLinus本人以外,最著名的人HackingonLinux。后來(lái)他開(kāi)始作、銷(xiāo)售和研究者開(kāi)放團(tuán)體IETF成員。LinuxLinux操作系統(tǒng)剛問(wèn)世時(shí),他就懷著極大的熱linuxMaillistLinuxLinux做出貢獻(xiàn)。他11.又推出了ext3文件系統(tǒng)。該系統(tǒng)大大提高了文件系統(tǒng)的穩(wěn)定性和效率。作為對(duì)他的推崇,第97期1LinusTorvalds《Justforfun84-88Linux社區(qū)中另一位著名人物是AlanCox。他原工作于英國(guó)威爾士斯旺西大學(xué)(SwanseaUniversityCollege)MUD(Multi-UserDungeonorDimension,多用戶(hù)網(wǎng)絡(luò)游戲。在90年代早期games.mud組的posts中你可以找到他的大量帖子。他甚至為此還寫(xiě)了一篇MUD的發(fā)展史(rec.games.mud組,1992年3月9日,AhistoryofMUD)。MUD游戲與網(wǎng)絡(luò)密切相關(guān),慢慢地他開(kāi)始對(duì)計(jì)算機(jī)網(wǎng)絡(luò)著迷起來(lái)。為了玩游戲并提高電腦運(yùn)386SX386BSDIn386SXCPU的電腦是不帶系統(tǒng)產(chǎn)生了,尤其是有關(guān)網(wǎng)絡(luò)方面的實(shí)現(xiàn)。在關(guān)于Linux單用戶(hù)運(yùn)行模式問(wèn)題的討論中,他甚至贊嘆Linux實(shí)現(xiàn)得巧妙(beautifully)。Linux0.95Linux系統(tǒng)編寫(xiě)補(bǔ)丁程序(修改程序記得他最早的兩個(gè)補(bǔ)丁程Linus采納LinuxTCP/IP網(wǎng)絡(luò)代碼的最早使用人之一。后來(lái)他逐漸加入了Linux的開(kāi)發(fā)隊(duì)伍,并成為L(zhǎng)inux內(nèi)核源代碼的主要之一,也可以說(shuō)成為L(zhǎng)inux社團(tuán)中繼他負(fù)責(zé)Linux內(nèi)核2.4.x的代碼。而Linus主要負(fù)責(zé)開(kāi)發(fā)開(kāi)發(fā)版內(nèi)核的研制(奇數(shù)版,比如2.5.x《內(nèi)核手冊(cè)》(TheLinuxKernelHackers'Guide)一書(shū)的作者M(jìn)ichaelK.Johnson也是最早接觸Linux操作系統(tǒng)的人之一(從0.97版)。他還是著名Linux文檔計(jì)劃(LinuxProject-LDP)的發(fā)起者之一。曾經(jīng)在LinuxJournel工作,現(xiàn)在RedHat公司工作。Linux系統(tǒng)并不是僅有這些中堅(jiān)力量就能發(fā)展成今天這個(gè)樣子的,還有許多計(jì)算機(jī)高手對(duì)Linux做其中以字母順序列出了對(duì)Linux做出較大貢獻(xiàn)的近400人的列表,包括他們的地址和通信地UNIX操作系統(tǒng)--UNIX于1969年誕生在Bell。Linux就是UNIX的一種克隆系統(tǒng)。UNIXMINIX--MINIXUNIX1987年由著名計(jì)算機(jī)教授AndrewS.TanenbaumMINIX系統(tǒng)的出現(xiàn)并且提供源代碼(只能免費(fèi)用于大學(xué)內(nèi))在全世界的大學(xué)中刮起了學(xué)習(xí)UNIX系統(tǒng)旋風(fēng)。Linux剛開(kāi)始就是參照MINIX1991年才開(kāi)始開(kāi)發(fā)。GNU計(jì)劃--LinuxLinuxGNU計(jì)劃。Linux只是操作系統(tǒng)的一個(gè)內(nèi)核,沒(méi)有GNU軟件環(huán)境(比如說(shuō)bashs),則Linux將寸步難行。POSIX標(biāo)準(zhǔn)--該標(biāo)準(zhǔn)在推動(dòng)Linux操作系統(tǒng)以后朝著正規(guī)發(fā)展起著重要的作用。是Linux前只能發(fā)展到0.13(0.95)版的水平。-具 1200kBlinux-0.11.tar.Z-內(nèi)核源代碼文件。大小為94KB,展開(kāi)后也僅有325KB; -BruceEvans'二進(jìn)制執(zhí)行文件。是16位的匯編程序和裝入程序; -更新過(guò)的安裝信息文件。Linux0.11rootimage-0.110.11上。linux-0.11內(nèi)核中的所有源代碼程序,對(duì)每個(gè)源程序文件都進(jìn)行了詳細(xì)注釋?zhuān)麮GNUC語(yǔ)言的內(nèi)嵌匯編語(yǔ)言進(jìn)行較為詳細(xì)的介并列出使用令和方法。這樣做有助于加深對(duì)代碼的理解,又能更好的了解所用硬件的使用方法,作188兆字節(jié),即使你花一生的經(jīng)歷來(lái)閱讀也未必能全部都看完。也許你要問(wèn)“既然要從簡(jiǎn)Linux0.01240K0.01核映像文件(bootimage),可以用來(lái)進(jìn)行引導(dǎo)演示。如果再配上簡(jiǎn)單的根文件系統(tǒng)映像文件(rootimage),拿Linux0.11版進(jìn)行學(xué)習(xí)也有不足之處。比如該內(nèi)核版本中尚不包括有關(guān)專(zhuān)門(mén)的進(jìn)程等待隊(duì)列、LinuxLinux工作Linux內(nèi)核中所有的代碼都進(jìn)行了說(shuō)明。為了保持結(jié)構(gòu)的完整性,對(duì)代碼的說(shuō)明是以?xún)?nèi)核中源代碼的組成結(jié)構(gòu)來(lái)進(jìn)行的,基本上是以每個(gè)源代碼中的為一章內(nèi)容進(jìn)行介紹。介紹的源程序文件的次序可參見(jiàn)前面的文件列表索引。整個(gè)Linux內(nèi)核源代碼的結(jié)構(gòu)如下列表1.1所示。所有結(jié)構(gòu)均是以linux為當(dāng)前。1-1名 大 最后修改日期 說(shuō)boot/ 2887bytes1991-12-062Linux操作系統(tǒng)的體系結(jié)構(gòu)、內(nèi)核源代碼文件放置的組織結(jié)構(gòu)以及每個(gè)文件大致功能。還介紹了Linux對(duì)物理內(nèi)存的使用分配方式、內(nèi)核的幾種堆棧及其使用方式和虛擬線性地址的使用分配。最后開(kāi)始注釋內(nèi)核程序包中Linux/下的所看到的第一個(gè)文件,也即內(nèi)核代碼的總體Makefilemake使用。3boot/bootsect.sBIOS中參setup.s32head.s。這三個(gè)匯編程序完成了把內(nèi)核從塊設(shè)備上引導(dǎo)4init/main.c。它是內(nèi)核完成所有初始化工作并進(jìn)入正程序時(shí),你應(yīng)該已經(jīng)對(duì)Linux內(nèi)核有了一定的了解,可以說(shuō)已經(jīng)有一半了?,但你還需要對(duì)文件系/6kernel/dev_blk/中的塊設(shè)備程序進(jìn)行了注釋說(shuō)明。該章主要含有硬盤(pán)、軟盤(pán)等塊設(shè)備7kernel/dev_chr/中的字符設(shè)備驅(qū)動(dòng)程序進(jìn)行注釋說(shuō)明。這一章中主要涉及串行線路驅(qū)8kernel/math/中的數(shù)學(xué)協(xié)處理器的仿真程序。由于本書(shū)所注釋的內(nèi)核版本,還沒(méi)有真第9章介紹內(nèi)核源代碼fs/中的文件系統(tǒng)程序,在看這章內(nèi)容時(shí)建議你能夠暫停一下而去閱讀系統(tǒng)是只支持MINIX一種文件系統(tǒng),Linux0.11版也不例外。10mm/In80X86微處理行方式的說(shuō)明,這些知識(shí)基本上都可以參考In80386程序員編程手冊(cè)(In80386Programmer'sReferenceManual)。但在此章中,以源代碼中的運(yùn)用實(shí)例為對(duì)象進(jìn)行解說(shuō),應(yīng)該可以更好地理解它的工Linux內(nèi)核分析書(shū)籍都缺乏對(duì)內(nèi)核頭文件的描述,因此對(duì)于一個(gè)初學(xué)者來(lái)講,在閱讀內(nèi)核程序時(shí)會(huì)碰到許多。本書(shū)的第11章對(duì)include/中的所有頭文件進(jìn)行了詳細(xì)說(shuō)明,基本上對(duì)每一個(gè)12Linux0.11lib/中的所有文件。這些庫(kù)函數(shù)文件主要向編譯系統(tǒng)等并不是很多,可以很快地看完。這也是我們?yōu)槭裁催x擇0.11版的原因之一。第13章介紹tools/ 它僅用于將內(nèi)核中的磁盤(pán)引導(dǎo)程序塊與其它主要內(nèi)核模塊連接成一個(gè)完整的內(nèi)核映像(kernelimage)文LinuxLinux0.11源代碼的語(yǔ)法使其能在RedHat9系統(tǒng)下順利編譯出正確的內(nèi)核來(lái)。Linux內(nèi)核中的一些常數(shù)定義和基本數(shù)據(jù)結(jié)構(gòu)定義,以及保護(hù)模PC機(jī)硬件方面的信息。在參考繁雜凌亂的文獻(xiàn)列表。比如在Linux文檔項(xiàng)目LDP(LinuxProject)中的文件時(shí),我們會(huì)明確地列出具體需要參考哪一篇HOWTO文章,而并不是僅僅給出LDP的地址了事。LinusLinux3MJBach著的《UNIX操作法,Linux內(nèi)核源代碼中很多重要函數(shù)的名稱(chēng)都取自該書(shū)。因此,在閱讀本書(shū)時(shí),這是一本必不可少的1版。LinusMINIX1.0Linux內(nèi)核全可以從Tanenbaum的書(shū)中獲得。LinuxLinuxGURU的初步知識(shí)。這時(shí)你應(yīng)該去閱讀更多的源代碼,最好是循序漸進(jìn)地從1.0版本開(kāi)始直到的正在開(kāi)發(fā)中的奇數(shù)編號(hào)的版本。在撰寫(xiě)這本書(shū)時(shí)的Linux內(nèi)核是2.5.44版。當(dāng)你能快速理解這些開(kāi)發(fā)中的版本甚至能提出自己的建議和補(bǔ)Linux誕生和發(fā)展不可缺少的五個(gè)支柱:UNIXLinux提供了POSIXLinux提供了實(shí)現(xiàn)與標(biāo)準(zhǔn)兼容系統(tǒng)的參考指南、A.S.TMINIXLinux的誕生起到了不可忽缺的參考、Internet是Linux成長(zhǎng)和壯大的必要環(huán)境。最后本章概述了基本內(nèi)第2LinuxLinuxLinux內(nèi)核源代碼中組織形式以及子中各個(gè)代碼文件的主要功能以及基本調(diào)用的層次關(guān)系。接下來(lái)就直接切入正題,從Linux/Makefile開(kāi)始,對(duì)每一行代碼進(jìn)行詳細(xì)注釋說(shuō)明。本章內(nèi)容可以X窗口系統(tǒng)、s命令解釋系統(tǒng)以及那些內(nèi)核編程接口等系統(tǒng)程序;操作系統(tǒng)內(nèi)核程序即是本書(shū)所感的部分,它主要用于對(duì)硬件資源的抽象和調(diào)度。Linux內(nèi)核的主要用途就是為了與計(jì)算機(jī)硬件進(jìn)行交互,實(shí)現(xiàn)對(duì)硬件部件的編程控制和接口操作,Linux0.11Linux內(nèi)核的基本體系結(jié)構(gòu)、主Linux0.11內(nèi)核編譯Linux0.11內(nèi)核,則是采用了單內(nèi)核模式。單內(nèi)核模式的主要優(yōu)點(diǎn)是內(nèi)核代碼結(jié)構(gòu)緊湊、執(zhí)行速在單內(nèi)核模式的系統(tǒng)中,操作系統(tǒng)所提供服務(wù)的流程為:應(yīng)用主程序使用指定的參數(shù)值執(zhí)行系統(tǒng)調(diào)t使Ur到lModel體的參數(shù)值調(diào)用特定的系統(tǒng)調(diào)用服務(wù)程序,而這些服務(wù)程序則根據(jù)需要再底層的一些支持函數(shù)以完成特定的功能。在完成了應(yīng)用程序所要求的服務(wù)后,操作系統(tǒng)又從態(tài)切換回用戶(hù)態(tài),返回到應(yīng)用程序中繼Linux5個(gè)模塊構(gòu)成,它們分別是:進(jìn)程調(diào)度模塊、內(nèi)存管理模塊、文件系統(tǒng)模塊、進(jìn)CPU,同時(shí)保證內(nèi)核地執(zhí)行硬件操作。內(nèi)存管理模塊用于確保所有進(jìn)程能夠安全地共享機(jī)器主內(nèi)存區(qū),同時(shí),內(nèi)存管理模塊還支持虛擬內(nèi)存管理方式,使得Linux支持進(jìn)程使用比實(shí)際內(nèi)存空間的換回來(lái)。文件系統(tǒng)模塊用于支持對(duì)外部設(shè)備的驅(qū)動(dòng)和。虛擬文件系統(tǒng)模塊通過(guò)向所有的外部設(shè)2-3所示。其中的連線代表它們之間的依賴(lài)關(guān)系,虛線和虛框部分Linux0.11中還未實(shí)現(xiàn)的部分(Linux0.95版才開(kāi)始逐步實(shí)現(xiàn)虛擬文件系統(tǒng),而網(wǎng)絡(luò)接口的支持到0.96版才有。(NFS成圖2-4所示的框圖結(jié)構(gòu)。 硬件控函數(shù) ,共可管理15級(jí)中斷向量。其級(jí)連示意圖見(jiàn)圖2-5所示。其中從的INT引腳連接到主的IR2引腳上。主8259A的端口址是0x20,從是0xA0。時(shí)鐘時(shí)鐘鍵盤(pán)聯(lián)int2IRQ5軟盤(pán)IRQ6并行口1IRQ7IR3IR4數(shù)據(jù)D7-實(shí)時(shí)鐘IRQ8 保留 協(xié)處理器IRQ13硬盤(pán)IRQ14 IR0CAS2-IR3IR4指令對(duì)8259A進(jìn)行初始化編程的狀態(tài)。一旦完成了初始化編程,即進(jìn)入操作狀態(tài),此時(shí)即IRQ15對(duì)于Linux內(nèi)核來(lái)說(shuō),中斷信號(hào)通常分為兩類(lèi):硬件中斷和軟件中斷(異常)。每個(gè)中斷是由0-255用,屬于軟件中斷,但I(xiàn)n公司稱(chēng)之為異常。因?yàn)檫@些中斷是在CPU執(zhí)行指令時(shí)探測(cè)到異常情況而引(在Linux系統(tǒng)中,則將int32--int47(0x20--0x2f)對(duì)應(yīng)于8259A中斷控制發(fā)出的硬件中斷請(qǐng)求信號(hào)IRQ0-IRQ15,并把程序編程發(fā)出的系統(tǒng)調(diào)用(system_call)中斷設(shè)置為int128(0x80)。(tier_interrupt以來(lái)經(jīng)過(guò)的時(shí)鐘滴答數(shù)。每當(dāng)發(fā)生一次時(shí)鐘中斷該值就增CPLdo_timer()1。如果此時(shí)當(dāng)前進(jìn)程時(shí)間程序是一個(gè)可執(zhí)行的文件,而進(jìn)程(process)是一個(gè)執(zhí)行中的程序?qū)嵗?。利用分時(shí)技術(shù),在Linux的時(shí)間片很短(例如15個(gè)系統(tǒng)滴答=150毫秒process則稱(chēng)為父進(jìn)程(parentprocess。內(nèi)核程序使用進(jìn)程標(biāo)識(shí)號(hào)(processID,pid)來(lái)標(biāo)識(shí)每個(gè)進(jìn)程。進(jìn)程由Linux系統(tǒng)中,一個(gè)進(jìn)程可以在內(nèi)核態(tài)(kernelmode)或用戶(hù)態(tài)(usermode)下執(zhí)行,因此,LinuxLinux系統(tǒng)中,進(jìn)程表項(xiàng)task_structinclude/linux/sched.h中。有些書(shū)上稱(chēng)其為PCB(ProcessControlBlock)PD(ProcessorDescriptor。其中保存著用于控structtask_structlong long longpriority longsignal //信號(hào)。是位圖,每個(gè)比特位代表一種信號(hào),信號(hào)值=位偏移值+1。structsigactionsigaction[32]//信號(hào)執(zhí)行屬性結(jié)構(gòu),對(duì)應(yīng)信號(hào)將要執(zhí)行的操作和標(biāo)志信息。longblocked //進(jìn)程碼(對(duì)應(yīng)信號(hào)位圖)。int unsignedlong unsignedlong unsignedlong (字節(jié)數(shù))unsignedlong (字節(jié)數(shù))unsignedlong long long long long long unsignedshort unsignedshort unsignedshort unsignedshort unsignedshort unsignedshort long long long long long long unsignedshort int unsignedshortumask //文件創(chuàng)建屬性位。structm_inode*pwd //當(dāng)前工作 i節(jié)點(diǎn)結(jié)構(gòu)。structm_inode*root //根 i節(jié)點(diǎn)結(jié)構(gòu)。structm_inode*executable//執(zhí)行文件i節(jié)點(diǎn)結(jié)構(gòu)。unsignedlongclose_on_exec//執(zhí)行時(shí)關(guān)閉文件句柄位圖標(biāo)志。(參見(jiàn) structfile*filp[NR_OPEN]//文件結(jié)構(gòu)指針表,最多32項(xiàng)。表項(xiàng)號(hào)即是文件描述符的值。structdesc_structldt[3]//任務(wù)局部描述符表。0-空,1-代碼段cs,2-數(shù)據(jù)和堆棧段ds&ss。structtss_structtss //進(jìn)程的任務(wù)狀態(tài)段信息結(jié)構(gòu)。U文。當(dāng)內(nèi)核需要切換(h)至另一個(gè)進(jìn)程時(shí),它就需要保存當(dāng)前進(jìn)程的所有狀態(tài),也即保存當(dāng)前進(jìn)nux2-6所示。進(jìn)程狀態(tài)保存狀態(tài)。在Linux系統(tǒng)中,睡眠等待狀態(tài)被分為可中斷的和不可中斷的等待狀態(tài)。0系統(tǒng)調(diào)用或中 返10 204當(dāng)進(jìn)程正在被CPU(running醒而進(jìn)入準(zhǔn)備運(yùn)行狀態(tài),該狀態(tài)稱(chēng)為就緒態(tài)。這些狀態(tài)(圖間一列)在內(nèi)核中表示方法相同,都被成為處于TASK_RUNNING狀態(tài)。wake_up()函數(shù)明確喚醒時(shí)才能轉(zhuǎn)換到可SIGSTOP、SIGTSTP、SIGTTINSIGTTOU時(shí)就會(huì)進(jìn)入暫停狀態(tài)??上蚱浒l(fā)送自愿地放棄CPU(TASK_UNINTERRUPTIBLE或ASK_INTERRUPTIBLE核數(shù)據(jù)錯(cuò)誤,內(nèi)核在執(zhí)行臨界區(qū)代碼時(shí)會(huì)一切中斷。在boot/中引導(dǎo)程序把內(nèi)核從磁盤(pán)上加載到內(nèi)存中,并讓系統(tǒng)進(jìn)入保護(hù)模式下運(yùn)行后,就開(kāi)始執(zhí)行系統(tǒng)初始化程序init/main.c。該程序首先確定如何分配使用系統(tǒng)物理內(nèi)存,然后調(diào)用內(nèi)核各部分的初0s00pause()系統(tǒng)調(diào)用,在對(duì)調(diào)度程序的初始化過(guò)程(sched_init())0的運(yùn)行環(huán)境進(jìn)行了設(shè)置。這包括人工預(yù)先exdh(TSS)描述符和局部描述符表(LDT)tr和局部描述符表寄存器ldtr中。00016MB0的代碼段和數(shù)據(jù)段分別包含在內(nèi)核代碼段和數(shù)據(jù)0運(yùn)行著main.c程序。宏move_to_user_mode的功能就是把運(yùn)行級(jí)從內(nèi)核態(tài)的0級(jí)變換到用戶(hù)態(tài)的3級(jí),但是仍然繼續(xù)執(zhí)行原來(lái)的代碼指令流。在移動(dòng)到任務(wù)0的過(guò)程中,宏move_to_user_mode使用了中斷返回指令造成級(jí)改變的方法。該0代碼段3上運(yùn)行。參見(jiàn)圖2-7所示的級(jí)發(fā)生變化時(shí)中斷返回堆棧結(jié)構(gòu)示意圖。0SP0TSS0SP0TSSmove_to_user_mode0數(shù)據(jù)段選擇符和內(nèi)核堆棧指針。然后壓入標(biāo)志0代碼段選擇符和執(zhí)行中斷返回后需要執(zhí)行的下一條指令的偏移位置。該偏移位置是iret后的一條指令處。iret指令時(shí),CPUCS:EIPCPU棧指針彈出到SS:ESP中。由于級(jí)發(fā)上了變化,段寄存器DS、ES、FS和GS的值變得無(wú)效,此時(shí)(long)&init_task建任務(wù)1(進(jìn)程1)之前保持“干凈”狀態(tài)。64fork()系統(tǒng)調(diào)用會(huì)因?yàn)槿蝿?wù)數(shù)組表中沒(méi)有可用空項(xiàng)而出錯(cuò)返回。然后(ASK_UNINTERRUPTIBE隨后對(duì)的任務(wù)數(shù)據(jù)結(jié)構(gòu)進(jìn)行修改。把當(dāng)前進(jìn)程設(shè)置為新進(jìn)程的父進(jìn)程,清除信號(hào)位圖并復(fù)位新15個(gè)系統(tǒng)滴答數(shù)(150毫秒。接著根據(jù)當(dāng)前進(jìn)程設(shè)置任務(wù)tss.esp0tss.ss0被設(shè)器,把還需要把協(xié)處理器的完整狀態(tài)保存到新進(jìn)程的tss.i387結(jié)構(gòu)中。此后系統(tǒng)設(shè)置新任務(wù)的代碼和數(shù)據(jù)段基址、限長(zhǎng)并當(dāng)前進(jìn)程內(nèi)存分頁(yè)管理的頁(yè)表。如果父進(jìn)程項(xiàng),其中址信息指向新進(jìn)程任務(wù)結(jié)構(gòu)中的tss和ldt。最后再將新任務(wù)設(shè)置成可運(yùn)行狀態(tài)并返回新進(jìn)由前面描述可知,LinuxTASK_RUNNING狀態(tài),只是暫時(shí)沒(méi)有被CPU運(yùn)行。進(jìn)程的搶占發(fā)生在進(jìn)程處于用戶(hù)態(tài)執(zhí)行階段,在內(nèi)核態(tài)執(zhí)行時(shí)是不能被搶占的。一定的調(diào)度策略。在Linux0.11中采用了基于優(yōu)先級(jí)排隊(duì)的調(diào)度策略。TASK_RUNNING狀態(tài)進(jìn)程的時(shí)間片都已經(jīng)用完,系統(tǒng)就會(huì)根據(jù)每個(gè)進(jìn)程的優(yōu)先計(jì)算的是:countercounter2schdeule()TASK_RUNNING狀態(tài),重復(fù)上述過(guò)程,直到選擇出一個(gè)進(jìn)程為止。最后調(diào)用switch_to()執(zhí)行實(shí)際的進(jìn)程切換操作。執(zhí)行實(shí)際進(jìn)程切換的任務(wù)由switch_to()宏定義的一段匯編代碼完成。在進(jìn)行切換之前,switch_to()的寄存器信息恢復(fù)到CPU中,系統(tǒng)就正式開(kāi)始運(yùn)行新切換的任務(wù)了。這個(gè)過(guò)程可參見(jiàn)圖2-8所示。8038680386TSSCPU當(dāng)一個(gè)用戶(hù)程序調(diào)用exit()系統(tǒng)調(diào)用時(shí),就會(huì)執(zhí)行內(nèi)核函數(shù)do_exit()。該函數(shù)會(huì)首先釋放進(jìn)程代碼段 的i節(jié)點(diǎn)進(jìn)行同步操作。如果進(jìn)程有子進(jìn)程,則讓init進(jìn)程作為其所有子進(jìn)程的父進(jìn)程。如果進(jìn)程是一通常會(huì)終止該會(huì)話(huà)中的所有進(jìn)程。然后把進(jìn)程狀態(tài)置為僵死狀態(tài)TASK_ZOMBIE。并向其原父進(jìn)程發(fā)送SIGCHLD信號(hào),通知其某個(gè)子進(jìn)程已經(jīng)終止。最后do_exit()調(diào)用調(diào)度函數(shù)去執(zhí)行其它進(jìn)程。由此可wait()waitpid()函數(shù)等待其某個(gè)子進(jìn)程終止。當(dāng)?shù)却淖?640K顯存和BIOS其中,Linux內(nèi)核程序占據(jù)在物理內(nèi)存的開(kāi)始部分,接下來(lái)是用于供硬盤(pán)或軟盤(pán)等塊設(shè)備使用的高速緩沖區(qū)部分。當(dāng)一個(gè)進(jìn)程需要塊設(shè)備中的數(shù)據(jù)時(shí),系統(tǒng)會(huì)首先將數(shù)據(jù)讀到高速緩沖區(qū)中;當(dāng)有數(shù)RAM虛擬盤(pán)的系統(tǒng),主內(nèi)存區(qū)頭統(tǒng)中的內(nèi)存進(jìn)行有效的管理。在InCPU中,提供了兩種內(nèi)存管理(變換)系統(tǒng):內(nèi)存分段系統(tǒng)System在Linux0.113a.程序(進(jìn)程)的邏輯地址;b.CPU的線性地址;c.邏輯地址(LogicalAddress)是指有程序產(chǎn)生的與段相關(guān)的偏移地址部分。在In保護(hù)模式下即是線性地址(LinearAddress)是邏輯地址到物理地址變換之間的中間層。程序代碼會(huì)產(chǎn)生邏輯地址,或者說(shuō)是段中的偏移地址,加上相應(yīng)段的址就生成了一個(gè)線性地址。如果啟用了分頁(yè)機(jī)制,那么線80386的線性地址空間容量為4G。物理地址(PhysicalAddress)是現(xiàn)在CPU外部地址總線上的尋址物理內(nèi)存的地址信號(hào),是地址 虛擬內(nèi)存(VirtualMemory)是指計(jì)算機(jī)呈現(xiàn)出要比實(shí)際擁有的內(nèi)存大得多的內(nèi)存量。因此它允許源的系統(tǒng)上實(shí)現(xiàn)。一個(gè)很恰當(dāng)?shù)谋扔魇牵耗悴恍枰荛L(zhǎng)的軌道就可以讓一列火車(chē)從開(kāi)到。你只需要足夠長(zhǎng)的鐵軌(比如說(shuō)3公里)就可以完成這個(gè)任務(wù)。采取的方法是把后面的鐵軌立刻鋪到火車(chē)的理需要完成的任務(wù)。在Linux0.11內(nèi)核中,給每個(gè)程序(進(jìn)程)都劃分了總?cè)萘繛?4MB的虛擬內(nèi)存空間。因此程序的邏輯地址范圍是0x 到0x 上。每次對(duì)內(nèi)存的都是對(duì)內(nèi)存段中內(nèi)存的。當(dāng)一個(gè)程序一個(gè)內(nèi)存地址時(shí),通過(guò)把相應(yīng)的段性地址就被送到CPU的外部地址總線上,用于直接尋址對(duì)應(yīng)的物理內(nèi)存。射到實(shí)際物理內(nèi)存地址上。與分段機(jī)制類(lèi)似,分頁(yè)機(jī)制允許我們重新定向(變換)每次內(nèi)存,以適的法。通常虛擬內(nèi)存空間要比實(shí)際物理內(nèi)存量大得多。使用一塊不存在的內(nèi)存時(shí)(也即在內(nèi)存頁(yè)表項(xiàng)中已標(biāo)出相應(yīng)內(nèi)存頁(yè)面不在內(nèi)存中,CPU就需要法來(lái)得知這個(gè)情況。這是通過(guò)80386的頁(yè)錯(cuò)誤異常中斷來(lái)實(shí)現(xiàn)的。當(dāng)一個(gè)進(jìn)程一個(gè)不存在頁(yè)面中的CPUCR2控制寄存器中。(比如硬盤(pán)上)加載到物理內(nèi)存中。如果此時(shí)物理內(nèi)存已經(jīng)被全部占用,那么可以借助二級(jí)空間的InCPU使用段(Segment)的概念來(lái)對(duì)程序進(jìn)行尋址。每個(gè)段定義了內(nèi)存中的某個(gè)區(qū)域以及GDTLDTLDTLDT映系統(tǒng)段sys任務(wù)任務(wù)任務(wù)任務(wù)任務(wù)圖中畫(huà)出了具有兩個(gè)任務(wù)時(shí)的情況。對(duì)于中斷描述符表idt,它是保存在內(nèi)核代碼段中的。由于在Linux0.11內(nèi)核中,內(nèi)核和各任務(wù)的代碼段和數(shù)據(jù)段都分別被映射到線性地址空間中相同基址處,且段限長(zhǎng)也一樣,因此內(nèi)核和任務(wù)的代碼段和數(shù)據(jù)段都分別是的。另外,Linux0.11內(nèi)核中沒(méi)有使用系續(xù)地址空間。對(duì)于In80386系統(tǒng),其CPU可以提供多達(dá)4G的線性地址空間。對(duì)于Linux0.11內(nèi)核,GDT2562項(xiàng)空閑、2項(xiàng)系統(tǒng)使用,每個(gè)進(jìn)程使02-11Linux0.11CPU整個(gè)線性地址空間中的地址,然后再使用頁(yè)表PDT(一級(jí)頁(yè)表)和頁(yè)表PT(二級(jí)頁(yè)表)映射到實(shí)際物理地址頁(yè)上。因此兩種變換不能。從Linux內(nèi)核0.99版以后,對(duì)內(nèi)存空間的使用方式發(fā)生了變化。每個(gè)進(jìn)程可以單獨(dú)整個(gè)4G的開(kāi)機(jī)初始化時(shí)bootsectROMBIOS0x7c00處時(shí),并沒(méi)有設(shè)置堆棧段,當(dāng)然程序也esp0xff000x9000:0xff00boot/bootsect.s61、62行。setup.s程序中也沿用了bootsect中設(shè)置的堆棧段。這就是系統(tǒng)初始化時(shí)臨時(shí)使用的堆棧。進(jìn)入保護(hù)模式時(shí)(0x10,espuser_stack數(shù)組的頂端(head.s31行1頁(yè)內(nèi)存(4K)作為堆棧使用。user_stacksched.c67--721024個(gè)長(zhǎng)字。它在物理內(nèi)存中的位置可參見(jiàn)下圖2-12所示。此時(shí)該堆棧是內(nèi)核程序自己使用的堆棧。內(nèi)存頁(yè)表(4kX表初始化時(shí)在main.c中,在執(zhí)行move_to_user_mode()代碼之前,系統(tǒng)一直使用上述堆棧。而在執(zhí)行過(guò)據(jù)結(jié)構(gòu))個(gè)字節(jié),大約為3K字節(jié)。而任務(wù)的用戶(hù)態(tài)堆棧卻可以在用戶(hù)的64MB空間內(nèi)延伸。每個(gè)任務(wù)(0)64MB地址空間。當(dāng)一個(gè)任務(wù)(進(jìn)程)剛被創(chuàng)建時(shí),它的用戶(hù)態(tài)堆棧指針被設(shè)置在其地址空間的末端(64MB頂端),而其內(nèi)核態(tài)堆棧則被設(shè)置成位于其任務(wù)數(shù)據(jù)結(jié)構(gòu)分頁(yè)機(jī)制確定。由于Linux實(shí)現(xiàn)了寫(xiě)時(shí)功能(CopyonWrite),因此在進(jìn)程被創(chuàng)建后,若該進(jìn)程及在建立新任務(wù)時(shí),fork程序在任務(wù)tss段的內(nèi)核級(jí)堆棧字段(tss.esp0和tss.ss0中設(shè)置的,參見(jiàn)kernel/fork.c,93行:p->tss.esp0=PAGE_SIZE+(long)p;p->tss.ss0=0x10;p是新任務(wù)的任務(wù)數(shù)據(jù)結(jié)構(gòu)指針,tss堆棧指針進(jìn)程指針tss.ss00x10呢?這要從內(nèi)核代碼段的長(zhǎng)度范圍來(lái)說(shuō)明。head.s16MB。這Linux0.98版后內(nèi)核段的限長(zhǎng)被修改成了1GB。這兩個(gè)值構(gòu)成。在任務(wù)切換時(shí),老任務(wù)的內(nèi)核棧指針(esp0)CPU來(lái)講,這兩個(gè)值是只讀結(jié)構(gòu)所在頁(yè)面的末端,而它的用戶(hù)態(tài)堆棧就是前面進(jìn)入保護(hù)模式后所使用的堆棧,也即sched.c的開(kāi)始并且限長(zhǎng)為640KB的段。參見(jiàn)圖2-7所示。eflagsiret退出內(nèi)核程序返回到用戶(hù)程序時(shí),將恢復(fù)用戶(hù)態(tài)的堆棧和eflags。這個(gè)過(guò)程見(jiàn)圖2-14所示。 Linux內(nèi)核是一種單內(nèi)核模式的系統(tǒng),因此,內(nèi)核中所有的程序幾乎都有緊密的聯(lián)系,它們之要在開(kāi)始閱讀內(nèi)核源代碼之前,先熟悉一下源代碼文件的結(jié)構(gòu)和安排。這里我們首先列出Linux內(nèi)核完整的源代碼,包括其中的子。然后逐一介紹各個(gè)中所tarlinux-0.11.tar.gzlinux/中。其中的結(jié)構(gòu)見(jiàn)圖2-15所示:頭文件│├─│├─│└─│├─│├─│└─ 中含有14個(gè)子 ,總共包括102個(gè)代碼文件。下面逐個(gè)對(duì)這些子 中除了包括所有的14個(gè) 編譯。因此,make工具軟件是程序項(xiàng)目的管理軟件。 有的源代碼文件,只要在linux 下運(yùn)行一次make軟件即可。 boot3301個(gè)扇區(qū)PCROMBIOSBIOS0x7C00處進(jìn)行執(zhí)行。setup.s程序主要用于機(jī)器的硬件配置參數(shù),并把內(nèi)核模塊system移動(dòng)到適當(dāng)?shù)膬?nèi)存位置處。 MINIXMINIXLinux分區(qū)。雖然使用的是Linux則采用了多線程方式。由于采用了多線程處理方式,Linux程序就必須處理競(jìng)爭(zhēng)條件的發(fā)生,Linux系統(tǒng)對(duì)資源分配進(jìn)行了嚴(yán)格地檢查,并且在內(nèi)核模式下運(yùn)行時(shí),如果任務(wù)沒(méi)有主動(dòng)睡眠(調(diào)用sleep(),就不讓內(nèi)核切換任務(wù)。fs/是文件系統(tǒng)實(shí)現(xiàn)程序的,共包含17個(gè)C語(yǔ)言程序。這些程序之間的主要關(guān)系見(jiàn)圖虛框中是的程序文件不屬于文件系統(tǒng),帶箭頭的線條表示關(guān)系,粗線條表示有相互關(guān)系。 blockfilechar圖2-16 中各程序中函數(shù)之間的關(guān)系由圖可以看出,該中的程序可以劃分成四個(gè)部分:高速緩沖區(qū)管理、低層文件操作、文件數(shù)據(jù)和文件函數(shù),在對(duì)本中文件進(jìn)行注釋說(shuō)明時(shí),我們也將分成這四個(gè)部分來(lái)描述。對(duì)于文件系統(tǒng),我們可以將它看成是內(nèi)存高速緩沖區(qū)的擴(kuò)展部分。所有對(duì)文件系統(tǒng)中數(shù)據(jù)的,都需要首先到高速緩沖區(qū)中。本中的程序主要用來(lái)管理高速緩沖區(qū)中緩沖塊的使用分配和塊設(shè)備上的文件系統(tǒng)。管理高速緩沖區(qū)的程序是buffer.c,而其它程序則主要都是用于文件系統(tǒng)管理。在file_table.c文件中,目前僅定義了一個(gè)文件句柄(描述符)結(jié)構(gòu)數(shù)組。ioctl.c文件將kernel/chr_drv/tty.c中的函數(shù),實(shí)現(xiàn)字符設(shè)備的io控制功能。exec.c程序主要包含一個(gè)執(zhí)行程序函數(shù)read_write.c程序用于實(shí)現(xiàn)文件讀/寫(xiě)和定位三個(gè)系統(tǒng)調(diào)用函數(shù)。stat.c程序中實(shí)現(xiàn)了兩個(gè)獲取文件狀態(tài)的系統(tǒng)調(diào)用函數(shù)。open.c程序主要包含實(shí)現(xiàn)修改文件屬性和創(chuàng)建與關(guān)閉文件的系統(tǒng)調(diào)用函數(shù)。名和文件名的操作函數(shù)和系統(tǒng)調(diào)用函數(shù)。block_dev.c程序包含塊數(shù)據(jù)讀和寫(xiě)函數(shù)。inode.c程序中包i節(jié)點(diǎn)操作的函數(shù)。truncate.c程序用于在刪除文件時(shí)釋放文件所占用的設(shè)備數(shù)據(jù)空間。bitmap.c程序用于處理文件系統(tǒng)中i節(jié)點(diǎn)和邏輯數(shù)據(jù)塊的位圖。super.c程序中包含對(duì)文件系統(tǒng)超級(jí)塊的處理函數(shù)。buffer.cll_rw_block是塊設(shè)備的底層讀fskernel/blk_drv/ll_rw_block.c中的塊設(shè)備讀寫(xiě)驅(qū)動(dòng)函數(shù)。放在這里只是讓 頭文件中總共有32個(gè).h頭文件。其中主下有13個(gè),asm子中有4個(gè),linux子中10個(gè),sys子中有5個(gè)。這些頭文件各自的功能見(jiàn)如下簡(jiǎn)述,具體的作用和所包含的信息請(qǐng)參見(jiàn) 錯(cuò)誤號(hào)頭文件。包含系統(tǒng)中各種出錯(cuò)號(hào)。(Linus從minix中引進(jìn)的) 個(gè)宏(va_start,va_arg和va_end用于vsprintf、vprintf、vfprintf函數(shù)。 ,, LinuxLIBRARY,則還包括系統(tǒng)調(diào)用號(hào)和內(nèi)嵌匯編_syscall0() <linux/config.h>內(nèi)核配置頭文件。定義鍵盤(pán)語(yǔ)言和硬盤(pán)類(lèi)型(HD_TYPE) <linux/kernel.h>內(nèi)核頭文件。含有一些內(nèi)核常用函數(shù)的定義 該中僅包含一個(gè)文件main.c。用于執(zhí)行內(nèi)核所有的初始化工作,然后移到用戶(hù)模式創(chuàng)建新進(jìn)程,并在控制臺(tái)設(shè)備上運(yùn)行s程序。并設(shè)置了中斷允許標(biāo)志。在執(zhí)行從態(tài)移到用戶(hù)態(tài)之后,系統(tǒng)第一次調(diào)用創(chuàng)建進(jìn)程函數(shù)fork(),創(chuàng)建運(yùn)行s程序。 linux/kernel12Makefile3個(gè)子。所有處理任kernel/fork、exit、調(diào)度程序以及一些系統(tǒng)調(diào)用程序等。還包括處get_hd_blocktty_write等。由于這些文件中代碼之間調(diào)用關(guān)系復(fù)雜,因此這里就不詳細(xì)列出各文件之間的關(guān)系圖,但仍然可以進(jìn)行大概分類(lèi),見(jiàn)圖2-17所示。asm.s程序是用于處理系統(tǒng)硬件異常所引起的中斷,對(duì)各硬件異常的實(shí)際處理程序則是在traps.c文件中,在各個(gè)中斷處理過(guò)程中,將分別調(diào)用traps.c中相應(yīng)的C語(yǔ)言處理函數(shù)。fork.c程序給出了sys_fork系統(tǒng)調(diào)用中使用了兩個(gè)C語(yǔ)言函數(shù):find_empty_process(日的秒數(shù),作為開(kāi)機(jī)秒時(shí)間。僅在init/main.c中被調(diào)用一次。printk.c程序包含一個(gè)內(nèi)核信息顯示函數(shù)printk()。signal.c程序中包括了有關(guān)信號(hào)處理的4個(gè)系統(tǒng)調(diào)用以及一個(gè)在對(duì)應(yīng)的中斷處理程序中處理信號(hào)的函do_signal()。system_call.sLinux系統(tǒng)調(diào)用(int0x80)的接口處理過(guò)程,實(shí)際的處理過(guò)程則包含在各系統(tǒng)調(diào)用相應(yīng)的C語(yǔ)言處理函數(shù)中,這些處理函數(shù)分布在整個(gè)Linux內(nèi)核代碼中。塊設(shè)備驅(qū)動(dòng)程序子通常情況下,用戶(hù)是通過(guò)文件系統(tǒng)來(lái)設(shè)備的,因此設(shè)備驅(qū)動(dòng)程序?yàn)槲募到y(tǒng)實(shí)現(xiàn)了調(diào)用接口。之間使用了高速緩沖機(jī)制。在塊設(shè)備上的數(shù)據(jù)時(shí),系統(tǒng)首先以數(shù)據(jù)塊的形式把塊設(shè)備上的數(shù)據(jù)讀入到高速緩沖區(qū)中,然后再提供給用戶(hù)。blk_drv子共包含4c1blk.h由于是塊設(shè)備程序的,所以與C文件放在一起。這幾個(gè)文件之間的大致關(guān)系,見(jiàn)圖2-18所示。圖2-18 blk.h3個(gè)C程序中共用的塊設(shè)備結(jié)構(gòu)和數(shù)據(jù)塊請(qǐng)求結(jié)構(gòu)。hd.c程序主要實(shí)現(xiàn)對(duì)硬盤(pán)數(shù)據(jù)塊進(jìn)行讀/do_hdrequest()函數(shù);floppy.c程序中主要實(shí)現(xiàn)了對(duì)軟盤(pán)數(shù)據(jù)塊的讀寫(xiě)驅(qū)動(dòng)函數(shù),主要是do_fd_request函數(shù)。ll_rw_blk.c中程序?qū)崿F(xiàn)了低層塊設(shè)備數(shù)據(jù)讀寫(xiě)函數(shù)塊設(shè)備數(shù)據(jù)的地方被調(diào)用,尤其是在高速緩沖區(qū)處理文件fs/buffer.c中。字符設(shè)備驅(qū)動(dòng)程序子字符設(shè)備程序 共含有4個(gè)C語(yǔ)言程序和2個(gè)匯編程序文件。這些文件實(shí)現(xiàn)了對(duì)串行端 tty_io.cttytty_read()tty_write(),為文件系統(tǒng)提供了上層Cdo_tty_interrupt(),該函數(shù)將會(huì)在中斷類(lèi)型為讀對(duì)顯示器和鍵盤(pán)中斷的初始化設(shè)置程序con_init()。會(huì)在實(shí)現(xiàn)系統(tǒng)調(diào)用sys_ioctl()的fs/ioctl.c程序中被調(diào)用。 該子Cmath_emulate.cmath_emulate()int7的中斷處理程序調(diào)用的C函數(shù)。當(dāng)機(jī)器中沒(méi)有數(shù)學(xué)協(xié)處理器,而CPU卻又執(zhí)行了協(xié)處理器的指令時(shí),就會(huì)該協(xié)處理器的仿真代碼。本程序中只是打印一條出錯(cuò)信息,并向用戶(hù)程序發(fā)送一個(gè)協(xié)處理器錯(cuò)誤信號(hào) 與普通靜態(tài)庫(kù)的實(shí)現(xiàn)方法完全一樣。讀者可從中了解一般libc函數(shù)庫(kù)的基本組成原理。在lib/中共12個(gè)Ctytsomalloc.c程序較長(zhǎng)以外,其它的程序很短,有的只有一二這些文件中主要包括有退出函數(shù)_exit()、關(guān)閉文件函數(shù)close(fd)、文件描述符函數(shù)dup()、文件函數(shù)wait()、創(chuàng)建會(huì)話(huà)系統(tǒng)調(diào)用setsid()以及在include/string.h中實(shí)現(xiàn)的所有字符串操作函數(shù)。 該2個(gè)代碼文件。主要用于管理程序?qū)χ鲀?nèi)存區(qū)的使用,實(shí)現(xiàn)了進(jìn)程邏輯地址到線性地址Linux3864G6464MB。所有內(nèi)核程序占用其中第一個(gè)段,并且物理地址與該段線性地址相同。然后每個(gè)貝,并執(zhí)行寫(xiě)時(shí)機(jī)制。page.s文件包括內(nèi)存頁(yè)面異常中斷(int14)處理程序,主要用于處理程序由于缺頁(yè)而引起的頁(yè)異常memory.c程序包括對(duì)內(nèi)存進(jìn)行初始化的函數(shù)mem_init(),由page.s的內(nèi)存處理中斷過(guò)程調(diào)用的do_no_page()和do_wp_page()函數(shù)。在創(chuàng)建新進(jìn)程而執(zhí)行進(jìn)程操作時(shí),即使用該文件中的內(nèi)存處理 該下的build.cLinux各個(gè)中被分別編譯生成的目標(biāo)代碼連接合并成一個(gè)可運(yùn)行的內(nèi)核映象文件image。其具體的功能可參見(jiàn)下一章內(nèi)容。在Linux系統(tǒng)中,內(nèi)核為應(yīng)用程序提供了兩方面的接口。其一是系統(tǒng)調(diào)用接口(5章中說(shuō)明int0x80;另一方面是通過(guò)內(nèi)核庫(kù)函數(shù)(12章中說(shuō)明)與內(nèi)核進(jìn)行信息交流。內(nèi)核庫(kù)函數(shù)是基本C函數(shù)庫(kù)libc的組成部分。許多系統(tǒng)調(diào)用是作為基本C語(yǔ)言函數(shù)庫(kù)的一部分實(shí)現(xiàn)的。用象libc等庫(kù)中的函數(shù)來(lái)內(nèi)核資源。通過(guò)調(diào)用這些庫(kù)中的程序,應(yīng)用程序代碼能夠完成各種常用工作,例如,打開(kāi)和關(guān)閉對(duì)文件或設(shè)備的、進(jìn)行科學(xué)計(jì)算、出錯(cuò)處理以及組和用戶(hù)標(biāo)識(shí)號(hào)ID等系統(tǒng)調(diào)用是內(nèi)核與外界接口的最。在內(nèi)核中,每個(gè)系統(tǒng)調(diào)用都有一個(gè)序列號(hào)(在的話(huà),程序的移植性就不好了。因此目前LinuxLSB(LinuxStandardBase)和許多其它標(biāo)準(zhǔn)都不允許應(yīng)用程序直接系統(tǒng)調(diào)用宏。系統(tǒng)調(diào)用的有關(guān)文檔可參見(jiàn)Linux操作系統(tǒng)的手冊(cè)的第2部分。I/Ofopenfcloseopen和close類(lèi)似的功能,但卻是在更高的層次上。在這種情況下,系統(tǒng)調(diào)用通常能提供比庫(kù)函數(shù)略微好一些的性能,但是庫(kù)函數(shù)卻能提供的功能,而且更具檢錯(cuò)能力。系統(tǒng)提供的庫(kù)函數(shù)有關(guān)文檔可參見(jiàn)操作系統(tǒng)的手冊(cè)第3部分。從本節(jié)起,我們開(kāi)始對(duì)內(nèi)核源代碼文件進(jìn)行注釋。首先注釋linux Makefilemake運(yùn)行時(shí)的輸入數(shù)據(jù)文件。只Makefile的當(dāng)前中鍵入makeMakefile文件中的設(shè)置對(duì)源程序或目標(biāo)代makeMakefile信息文件,該文件描述了整個(gè)程序包中各程序make命令就能進(jìn)行所有必要的重新編譯工作。make程序Makefile數(shù)據(jù)文件和代碼文件的最后修改時(shí)間(last-modificationtime)來(lái)確定那些文件需要進(jìn)行更Makefilemaketools/build執(zhí)行程序?qū)⑺袃?nèi)核編譯代碼連接和合并成一個(gè)可運(yùn)行的內(nèi)核映像文件image。具體是對(duì)boot/中的GNUgcc/gassystembuild工具將這三塊組合成一個(gè)內(nèi)核映象文件image.基本編譯連接/組合結(jié)構(gòu)如圖2-20所示。
112ifyouwanttheram-diskdevice,definethistobetheRAM3sizein 45RAMDISK=#-67=as86-0-8=ld86-101112=-s-x-#?連接中包含的所有文件成員及其的符號(hào)13=gcc # CFLAGS=-Wall-O-fstrength-reduce-fomit-frame-pointer#fstrength-reducemstring-insns =cppnostdincIincludecppgccnostdincIinclude#義是不要搜索標(biāo)準(zhǔn)的頭文件 #選項(xiàng)指定的 18#ROOT_DEVspecifiesthedefaultroot-devicewhenmakingthe#ThiscanbeeitherFLOPPY,/dev/xxxxorempty,inwhichcase#defaultof/dev/hd6isusedby# #在的設(shè)備,這可以是軟盤(pán)(FLOPPY)、/dev/xxxx或者干脆空著,空著時(shí)#build程序(在tools/ ARCHIVES=kernel/kernel.omm/mm.ofs/fs.o# 和 ARCHIVES(歸檔文件)DRIVERSkernel/blk_drv/blk_drv.akernel/chr_drv/chr_drv.a.a #由 $(CC)$(CFLAGS)-nostdincIincludeSo$*.s$gccCFLAGS#僅使用include/ #停止(-S),從而產(chǎn)生與輸入的各個(gè)C文件對(duì)應(yīng)的匯編語(yǔ)言形式的#代碼文件。默認(rèn)情況下所產(chǎn)生的匯編程序文件是原C文件名去掉.c#是自動(dòng)目標(biāo)變量,$<代表第一個(gè)先決條件,這里即是符合條件 $(CC)$(CFLAGS)-nostdincIincludeco$*.o$gccC39 Imageboot/bootsectboot/setuptools/systemtools/build#說(shuō)明目標(biāo)(Image) #setup文件、 中的system和build文件tools/buildboot/bootsectboot/setuptools/system$(ROOT_DEV)> $(ROOT_DEVImagedisk if=表示輸入的文件,oftools/build: #由 $(CC)$(CFLAGS)-otools/buildtools/build.c#編譯生成執(zhí)行程序build令52boot/head.o: boot/head.oinit/main.o$(ARCHIVES)$(DRIVERS)$(MATH)$(LIBS)#表示 $(LD)$(LDFLAGS)boot/head.oinit/main.o$(ARCHIVES)$(DRIVERS)$(MATH)$(LIBS)-otools/system> (cdkernel/math; (cdkernel/blk_drv;make) (cdkernel/chr_drv;make) (cdkernel;make) (cdmm;make) (cdfs;make) (cdlib;make)boot/setup: $(AS86)oboot/setup.o $(LD86soboot/setup boot/bootsect: $(AS86)-oboot/bootsect.o$(LD86)-s-oboot/bootsectboot/bootsect.otmp.s:boot/bootsect.s 15)/16116(echo-n"SYSSIZE=(";ls-ltools/system|grepsystem |cut-c25-31|tr'\012''';echo"+15)/16")>catboot/bootsect.s>>arm-fImageSystem.maptmp_makecoreboot/bootsectrm-finit/*.otools/systemtools/build(cdmm;make (cdfs;make(cdkernel;make(cdlib;makeabackup: backup.Z'cdlinux/的上一級(jí)(父)tarcflinuxlinux/執(zhí)行tarcf'|compresstar|傳遞給壓縮程序compress,并將壓縮程序的輸出存成backup.Z文件。(cd..;tarcf-linux|compress-> 重建一個(gè)目標(biāo)對(duì)象的。比如當(dāng)某個(gè)頭文件被改動(dòng)過(guò)后,make頭文件有關(guān)的所有*.c文件。具體方法如下:#文件中'###Dependencies'行后面的所有行(118開(kāi)始的行),并生成tmp_make makemake111行中的$$i實(shí)際上是$($i)的意思。這里$i是這句前面的s變量的值。sed'/\#\#\#Dependencies/q'<Makefile>(foriininit/*.c;doecho-n"init/";$(CPP)-M$$i;done)>>cptmp_make(cdfs;make(cdkernel;make(cdmm;make###init/main.o:init/main.cinclude/unistd.hinclude/sys/stat.hinclude/utime.hinclude/time.hinclude/linux/tty.hinclude/termios.hinclude/linux/mm.hinclude/signal.hinclude/asm/system.hinclude/asm/io.hinclude/stddef.h makefilemake工具程序的配置文件。Make工具程序的主要用途是能自動(dòng)地決定一個(gè)含有很多源程序文件的大型程序中哪個(gè)文件需要被重新編譯。makefile的使用比較復(fù)雜,這里只是根據(jù)上面的makefile文件作些簡(jiǎn)單的介紹。詳細(xì)說(shuō)明請(qǐng)參考GNUmake使用手冊(cè)。告訴make如何編譯和連接一個(gè)文件。當(dāng)明確時(shí),makefile還可以告訴make運(yùn)行各種命令(例如,make的執(zhí)行過(guò)程分為兩個(gè)不同的階段。在第一個(gè)階段,它所有的makefile文件以及包含的makefile文件等,記錄所有的變量及其值、隱式的或顯式的規(guī)則,并構(gòu)造出所有目標(biāo)對(duì)象及其先決條件C代碼程序都將被重新編譯。每次編譯操作都產(chǎn)生一個(gè)與源程序?qū)?yīng)的目標(biāo)文件(objectfile)。最終,如果任何源代碼文件被編譯過(guò)了,那么所有的目標(biāo)文件不管是目標(biāo)(target)...:先決條件命令過(guò) 個(gè) 則須在ke的 條變量。自動(dòng)變量的值是基于目標(biāo)對(duì)象及其先決條件而在命令執(zhí)行前設(shè)置的。例如,$的值表示規(guī)則的處 <$foo.o:foo.cdefs.hcc-c$(CFLAGS)$<-omake能使用習(xí)慣用法來(lái)更新一個(gè)目標(biāo)對(duì)象,你可以不指定命令,寫(xiě)一個(gè)不帶命令的規(guī)則或make程序?qū)?huì)根據(jù)源程序文件的類(lèi)型(程序的后綴)來(lái)判斷要使用哪個(gè)隱式規(guī)則。make程序定義隱式規(guī)則的老式方法(現(xiàn)在這種規(guī)則已經(jīng)不用了,取而代之的是使用面的’$<’值是*.c文件名。而正條make規(guī)則的含義是將*.c程序編譯成*.s代碼。
$(CC)$(CFLAGS)-nostdinc-Iinclude-S-o$*.sg文件。然而,為目標(biāo)而指定命令的規(guī)則也并不一定要有先決條件。例如,與目標(biāo)相關(guān)的含有刪除d)ke文件被改動(dòng)過(guò)后,make就通過(guò)這些依賴(lài)關(guān)系,重新編譯與該頭文件有關(guān)的所有*.c文件。38632位的代碼。Linux16位的啟動(dòng)扇區(qū)近似于In的匯編語(yǔ)言語(yǔ)法(如操作數(shù)的次序相反等。BruceEvans是minix32LinuxLinusTorvalds是很好的朋友。LinusBruceEvansUNIX類(lèi)操作系統(tǒng)的知識(shí),minix操作系統(tǒng)的不足之處也是兩個(gè)好朋友互相探討得出的結(jié)果,這激發(fā)了Linus在In386體系結(jié)構(gòu)上開(kāi)發(fā)一個(gè)全新概念的操作系統(tǒng),因此Linux操作系統(tǒng)的誕生與BruceEvans也有著密切的關(guān)系。有關(guān)這個(gè)編譯器和連接器的源代碼可以從FTP服務(wù)器ftp.funet.fi上或從我的 上as[-03agjuw][-b[bin]][-lm[list]][-nname][-oobj][-ssym] -016-332-g-j-m在列表中擴(kuò)展宏定義;-n后面跟隨模塊名稱(chēng)(取代源文件名稱(chēng)放入目標(biāo)文件中-s產(chǎn)生符,后跟符名-w不顯示警告信息;ld[-03Mims[-]][-Ttextaddr][-llib_extension][-ooutfile]ld[-03Mimrs[-]][-Ttextaddr][-llib_extension][-ooutfile] -M在標(biāo)準(zhǔn)輸出設(shè)備上顯示已的符號(hào)-T后面跟隨文本址(使用適合于strtoul的格式-i分離的指令與數(shù)據(jù)段(I&D)-m在標(biāo)準(zhǔn)輸出設(shè)備上顯示已的模塊-sSystem.mapSystem.map文件中的c03441a0Bdmi_brokenc03441a4Bis_sony_vaio_laptopc03441c0bdmi_ident b bSystem.map位于使用它的軟件(例如內(nèi)核日志記錄程序klogd)能夠?qū)ふ业降牡胤?。在系統(tǒng)啟動(dòng)時(shí),如果沒(méi)有以一個(gè)參數(shù)的形式為klogd給出System.map的位置,則klogd將會(huì)在三個(gè)地方搜尋System.mapklogd,lsof,ps以及其它許多軟件,象Linux早期操作系統(tǒng)的內(nèi)核模式和體系結(jié)構(gòu)。給出了Linux0.11內(nèi)核源代碼的結(jié)構(gòu)RedHat9系統(tǒng)下編譯Linux0.11內(nèi)核時(shí),對(duì)代碼需要進(jìn)行修改的地方。最后從Linux內(nèi)核主下的makefile文件著手,第3本章主要描述boot/中的三個(gè)匯編代碼文件,見(jiàn)列表3-1所示。正如一章中提到的,這三個(gè)文件雖然都是匯編程序,但卻使用了兩種語(yǔ)法格式。bootsect.s和setup.s采用近似于In的匯編語(yǔ)言語(yǔ)In8086as86ld86head.sGNU的匯編程序格式,并且運(yùn)行在保護(hù)模式下,需要用GNUas進(jìn)行編譯。這是一種AT&T語(yǔ)法的匯編語(yǔ)言程序。Inx86處理器系列來(lái)講,GNUi386及以后出的CPU。不支持生成運(yùn)行在實(shí)模式下的程序。最后修改時(shí)間 說(shuō)5052593853641991-12-05閱讀這些代碼除了你需要知道一些一般8086匯編語(yǔ)言的知識(shí)以外,還要對(duì)采用In80X86微處理PC8038632位保護(hù)模式下的編程原理有些了解。所以在開(kāi)始閱讀源代碼之前可CPU0xFFFF0ROM-BIOS中的Linux8086匯編語(yǔ)言編寫(xiě)的(boot/bootsect.s)BIOS讀入到內(nèi)存絕對(duì)地節(jié)代碼(boot/setup.s)讀入到內(nèi)存0x90200處,而內(nèi)核的其它部分(system模塊)則被讀入到從地址512KBLinux系統(tǒng)啟動(dòng)時(shí)這幾個(gè)程序或模塊在內(nèi)存中的動(dòng)態(tài)位置。其中,每一豎條框代表某一時(shí)刻內(nèi)存中 632位運(yùn)行方式的設(shè)置啟動(dòng)被完成IDT、GDTLDT被加載,處理器和協(xié)處理器也已確認(rèn),init/main.cmain()boot/head.S中的,setupROMBIOS中的中斷調(diào)用來(lái)獲取機(jī)器的一些參數(shù)(例如顯示卡模式、硬盤(pán)參數(shù)表等BIOS0x400字節(jié)(1Kb)的中斷向量表,因此需要在使用完BIOS的中斷調(diào)用后才能將這個(gè)區(qū)域覆蓋掉。1個(gè)扇區(qū)PCROMBIOSBIOS0x7C00處,然后將自己bootsect的后面位置(0x90200),BIOS0x13取磁盤(pán)參數(shù)表中當(dāng)前啟動(dòng)引導(dǎo)盤(pán)的參數(shù),接著在屏幕上顯示“Loadingsystem...”system0x10000開(kāi)盤(pán)的類(lèi)型和種類(lèi)(1.44MA盤(pán)嗎?)root_dev(0x508地址處),最后長(zhǎng)跳轉(zhuǎn)到setup程序的開(kāi)始處(0x90200)執(zhí)行setup程序。1
!SYS_SIZEisthenumberofclicks(16bytes)tob
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度體育場(chǎng)館場(chǎng)地租賃與賽事運(yùn)營(yíng)合作協(xié)議3篇
- 2024車(chē)站機(jī)場(chǎng)候機(jī)樓室內(nèi)設(shè)計(jì)裝修合同
- 二零二五年度商業(yè)地產(chǎn)商鋪?zhàn)赓U服務(wù)合同模板6篇
- 2024版醫(yī)療合作合同條款版B版
- 2024項(xiàng)目委托咨詢(xún)服務(wù)協(xié)議-企業(yè)知識(shí)產(chǎn)權(quán)保護(hù)服務(wù)3篇
- 2025年度餐飲企業(yè)特色調(diào)料研發(fā)與供應(yīng)合同3篇
- 二零二五年精密儀器供應(yīng)鏈銷(xiāo)售合作框架合同樣本3篇
- 二零二五年度安防工程材料供應(yīng)合同3篇
- 2024版分紅合作協(xié)議合同范本
- 個(gè)人機(jī)動(dòng)車(chē)抵押借款合同2024樣式
- 勘察工作質(zhì)量及保證措施
- 體外膜肺氧合(ECMO)并發(fā)癥及護(hù)理
- 充電樁巡查記錄表
- 心電圖并發(fā)癥預(yù)防及處理
- 疏散樓梯安全要求全解析
- 汽車(chē)擾流板產(chǎn)品原材料供應(yīng)與需求分析
- 臨床醫(yī)學(xué)院畢業(yè)實(shí)習(xí)管理-new-new課件
- PLC控制系統(tǒng)合同(2024版)
- CJT 511-2017 鑄鐵檢查井蓋
- ISO15189培訓(xùn)測(cè)試卷及答案
- JJG(交通) 171-2021 超聲式成孔質(zhì)量檢測(cè)儀檢定規(guī)程
評(píng)論
0/150
提交評(píng)論