本篇文章系統(tǒng)的給大家講述linux操作系統(tǒng)原理,這是一篇非常好的linux系統(tǒng)基礎(chǔ)教程,我們總結(jié)了相關(guān)的全部精選內(nèi)容,一起來(lái)學(xué)習(xí)下。
linux操作系統(tǒng)原理文字版
一.計(jì)算機(jī)經(jīng)歷的四個(gè)時(shí)代
1.第一代:
真空管計(jì)算機(jī),輸入和輸出:穿孔卡片,對(duì)計(jì)算機(jī)操作起來(lái)非常不便,做一件事可能需要十幾個(gè)人去共同去完成,年份大概是:1945-1955。而且耗電量特別大,如果那個(gè)時(shí)候你家里有臺(tái)計(jì)算機(jī)的話(huà),可能你一開(kāi)計(jì)算機(jī)你家的電燈泡亮度就會(huì)變暗,哈哈~
2.第二代:
晶體管計(jì)算機(jī),批處理(串行模式運(yùn)行)系統(tǒng)出現(xiàn)。相比第一臺(tái)省電多了。典型代表是mainframe。年份大概是:1955-1965。在那個(gè)年代:fortran語(yǔ)言也就誕生啦~一門(mén)非常古老的計(jì)算機(jī)語(yǔ)言。
3.第三代:
集成電路出現(xiàn),多道處理程序(并行模式運(yùn)行)設(shè)計(jì),比較典型的代表就是:分時(shí)系統(tǒng)(把cpu的運(yùn)算分成了時(shí)間片)。年份大概是:1965-1980年左右。
4.第四代:
pc機(jī)出現(xiàn),大概是從:1980年左右。相信這個(gè)時(shí)代典型人物代表:比爾蓋茨,喬布斯。
二.計(jì)算機(jī)的工作體系
雖然說(shuō)計(jì)算機(jī)經(jīng)過(guò)了四個(gè)時(shí)代的演變,但是到今天為止,計(jì)算機(jī)的工作體系還是比較簡(jiǎn)單的。一般而言,我們的計(jì)算機(jī)有五大基本部件。
1.mmu(內(nèi)存控制單元,實(shí)現(xiàn)內(nèi)存分頁(yè)【memory page】)
運(yùn)算機(jī)制被獨(dú)立在cpu(計(jì)算控制單元)上,在cpu當(dāng)中有一個(gè)獨(dú)特的芯片叫mmu。他是用來(lái)計(jì)算進(jìn)程的線線地址和物理地址的對(duì)應(yīng)關(guān)系的。它還用于訪問(wèn)保護(hù)的,即一個(gè)進(jìn)程先要訪問(wèn)到不是它的內(nèi)存地址,是會(huì)被拒絕的!
2.存儲(chǔ)器(memory)
3.顯示設(shè)備(vga接口,顯示器等等)【屬于io設(shè)備】
4.輸入設(shè)備(keyboard,鍵盤(pán)設(shè)備)【屬于io設(shè)備】
5.硬盤(pán)設(shè)備(hard dish control ,硬盤(pán)控制器或適配器)【屬于io設(shè)備】
擴(kuò)充小知識(shí):
這些硬件設(shè)備在一條總線上鏈接,他們通過(guò)這條線進(jìn)行數(shù)據(jù)交互,里面的帶頭大哥就是cpu,擁有最高指揮權(quán)。那么它是如何工作的呢?
a.取指單元(從內(nèi)存中取得指令);
b.解碼單元(完成解碼[講內(nèi)存中取到的數(shù)據(jù)轉(zhuǎn)換成cpu真正能運(yùn)行的指令]);
c.執(zhí)行單元(開(kāi)始執(zhí)行指令,根據(jù)指令的需求去調(diào)用不同的硬件去干活。);
我們通過(guò)上面知道了mmu是cpu的一部分,但是cpu有還要其他的部件嗎?當(dāng)然是有的啦,比如指令寄存器芯片,指令計(jì)數(shù)器芯片,堆棧指針。
指令寄存器芯片:就是cpu用于將內(nèi)存中的數(shù)據(jù)取出來(lái)存放的地方;
指令計(jì)數(shù)器芯片:就是cpu為了記錄上一次在內(nèi)存中取數(shù)據(jù)的位置,方便下一次取值;
堆棧指針:cpu每次取完指令后,就會(huì)把堆棧指針指向下一個(gè)指令在內(nèi)存中的位置。
他們的工作周期和cpu是一樣快的速度,跟cpu的工作頻率是在同一個(gè)時(shí)鐘周期下,因此他的性能是非常好的,在cpu內(nèi)部總線上完成數(shù)據(jù)通信。指令寄存器芯片,指令計(jì)數(shù)器芯片,堆棧指針。這些設(shè)備通常都被叫做cpu的寄存器。
寄存器其實(shí)就是用于保存現(xiàn)場(chǎng)的。尤其是在時(shí)間多路復(fù)用尤為明顯。比如說(shuō)cpu要被多個(gè)程序共享使用的時(shí)候,cpu經(jīng)常會(huì)終止或掛起一個(gè)進(jìn)程,操作系統(tǒng)必須要把它當(dāng)時(shí)的運(yùn)行狀態(tài)給保存起來(lái)(方便cpu一會(huì)回來(lái)處理它的時(shí)候可以繼續(xù)接著上次的狀態(tài)干活。)然后繼續(xù)運(yùn)行其他進(jìn)程(這叫計(jì)算機(jī)的上下文切換)。
三.計(jì)算機(jī)的存儲(chǔ)體系。
1.對(duì)稱(chēng)多處理器smp
cpu里面除了有mmu和寄存器(接近c(diǎn)pu的工作周期)等等,還有cpu核心,正是專(zhuān)門(mén)處理數(shù)據(jù)的,一顆cpu有多個(gè)核心,可以用于并行跑你的代碼。工業(yè)上很多公司采用多顆cpu,這種結(jié)構(gòu)我們稱(chēng)之為對(duì)稱(chēng)多處理器。
2.程序局部性原理
空間局部性:
程序是由指令和數(shù)據(jù)組成的。空間局部性指的是一個(gè)數(shù)據(jù)被訪問(wèn)到之后,那么離這個(gè)數(shù)據(jù)很近的其他數(shù)據(jù)隨后也可能會(huì)被訪問(wèn)到。
時(shí)間局部性:
一般而言當(dāng)一個(gè)程序執(zhí)行完畢后,可能很快會(huì)被訪問(wèn)到。數(shù)據(jù)也是同樣的原理,一個(gè)數(shù)據(jù)的被訪問(wèn)到,很可能會(huì)再次訪問(wèn)到。
正是因?yàn)槌绦蚓植啃缘拇嬖冢允沟脽o(wú)論是在空間局部性或者時(shí)間的局部性的角度來(lái)考慮,一般而言我們都需要對(duì)數(shù)據(jù)做緩存。
擴(kuò)充小知識(shí):
由于cpu內(nèi)部的寄存器存儲(chǔ)的空間有限,于是就用了內(nèi)存來(lái)存儲(chǔ)數(shù)據(jù),但是由于cpu和速度和內(nèi)存的速度完全不在一個(gè)檔次上,因此在處理的數(shù)據(jù)的時(shí)候回到多數(shù)都在等(cpu要在內(nèi)存中取一個(gè)數(shù)據(jù),cpu轉(zhuǎn)一圈的時(shí)間就可以處理完,內(nèi)存可能是需要轉(zhuǎn)20圈)。為了解決使得效率更加提高,就出現(xiàn)了緩存這個(gè)概念。
既然我們知道了程序的局部性原理,有知道了cpu為了獲得更多的空間其實(shí)就是用時(shí)間去換空間,但是緩存就是可以直接讓cpu拿到數(shù)據(jù),節(jié)省了時(shí)間,所以說(shuō)緩存就是用空間去換時(shí)間
3.就算進(jìn)存儲(chǔ)體系
工作時(shí)間就的朋友可能見(jiàn)過(guò)磁帶機(jī),現(xiàn)在基本上都被out了,企業(yè)很多都用機(jī)硬盤(pán)來(lái)替代磁帶機(jī)了,所以我們這里就從我們最熟悉的家用電腦的結(jié)構(gòu)來(lái)說(shuō),存下到上一次存儲(chǔ)數(shù)據(jù)是不一樣。我們可以簡(jiǎn)單舉個(gè)例子,他們的周存儲(chǔ)周期是有很大差距的。尤為明顯的是機(jī)械硬盤(pán)和內(nèi)存,他們兩個(gè)存取熟讀差距是相當(dāng)大的。
擴(kuò)充小知識(shí):
相比自己家用的臺(tái)式機(jī)或是筆記本可能自己拆開(kāi)過(guò),講過(guò)機(jī)械式硬盤(pán),固態(tài)硬盤(pán)或是內(nèi)存等等。但是可能你沒(méi)有見(jiàn)過(guò)緩存物理設(shè)備,其實(shí)他是在cpu上的。因此我們對(duì)它的了解可能會(huì)有些盲區(qū)。
先說(shuō)說(shuō)一級(jí)緩存和耳機(jī)緩存吧,他們的cpu在這里面取數(shù)據(jù)的時(shí)候時(shí)間周期基本上查不了多少,因一級(jí)緩存和二級(jí)緩存都在cpu核心內(nèi)部資源。(在其他硬件條件相同的情況下。一級(jí)緩存128k可能市場(chǎng)價(jià)格會(huì)買(mǎi)到300元左右,、一級(jí)緩存256k可能會(huì)買(mǎi)到600元左右,一級(jí)緩存512k可能市場(chǎng)價(jià)格就得過(guò)四位數(shù)這個(gè)具體價(jià)格可以參考京東啊。這足以說(shuō)明緩存的造價(jià)是非常高的!)這個(gè)時(shí)候你可能會(huì)問(wèn)那三級(jí)緩存呢?其實(shí)三級(jí)緩存就是就是多顆cpu共享的空間。當(dāng)然多顆cpu也是共享內(nèi)存的。
4.非一致性?xún)?nèi)存訪問(wèn)(numa)
我們知道當(dāng)多顆cpu共享三級(jí)緩存或是內(nèi)存的時(shí)候,他們就會(huì)出現(xiàn)了一個(gè)問(wèn)題,即資源征用。我們知道變量或是字符串在內(nèi)存中被保存是有內(nèi)存地址的。他們是如何去領(lǐng)用內(nèi)存地址呢?我們可以參考下圖:
沒(méi)錯(cuò),這些玩硬件的大牛們將三級(jí)緩存分割,分別讓不同的cpu占用不同的內(nèi)存地址,這樣我們可以理解他們都有自己的三級(jí)緩存區(qū)域,不會(huì)存在資源搶奪的問(wèn)題,但是要注意的是他們還是同一塊三級(jí)緩存。就好像北京市有朝陽(yáng)區(qū),豐臺(tái)區(qū),大興區(qū),海淀區(qū)等等,但是他們都是北京的所屬地。我們可以這里理解。這就是numa,他的特性就是:非一致性?xún)?nèi)存訪問(wèn),都有自己的內(nèi)存空間。
擴(kuò)展小知識(shí):
那么問(wèn)題來(lái)了,基于重新負(fù)載的結(jié)果,如果cpu1運(yùn)行的進(jìn)程被掛起,其地址在他自己的它的緩存地址是有記錄的,但是當(dāng)cpu2再次運(yùn)行這個(gè)程序的時(shí)候被cpu2拿到的它是如何處理的呢?
這就沒(méi)法了,只能從cpu1的三級(jí)換粗區(qū)域中復(fù)制一份地址過(guò)來(lái)一份或是移動(dòng)過(guò)來(lái)一份讓cpu2來(lái)處理,這個(gè)時(shí)候是需要一定時(shí)間的。所以說(shuō)重新負(fù)載均衡會(huì)導(dǎo)致cpu性能降低。這個(gè)時(shí)候我們就可以用進(jìn)程綁定來(lái)實(shí)現(xiàn),讓再次處理該進(jìn)程的時(shí)候還是用之前處理的cpu來(lái)處理。即進(jìn)程的cpu的親緣性。
5.緩存中的通寫(xiě)和回寫(xiě)機(jī)制。
cpu在處理數(shù)據(jù)的地方就是在寄存器中修改,當(dāng)寄存器沒(méi)有要找的數(shù)據(jù)是,就會(huì)去一級(jí)緩存找,如果一級(jí)緩存中沒(méi)有數(shù)據(jù)就會(huì)去二級(jí)緩存中找,依次查找知道從磁盤(pán)中找到,然后在加載到寄存器中。當(dāng)三級(jí)緩存從內(nèi)存中取數(shù)據(jù)發(fā)現(xiàn)三級(jí)緩存不足時(shí),就會(huì)自動(dòng)清理三級(jí)緩存的空間。
我們知道數(shù)據(jù)最終存放的位置是硬盤(pán),這個(gè)存取過(guò)程是由操作系統(tǒng)來(lái)完成的。而我們cpu在處理數(shù)據(jù)是通過(guò)兩種寫(xiě)入方式將數(shù)據(jù)寫(xiě)到不同的地方,那就是通寫(xiě)(寫(xiě)到內(nèi)存中)和回寫(xiě)(寫(xiě)到一級(jí)緩存中)。很顯然回寫(xiě)的性能好,但是如果斷電的話(huà)就尷尬了,數(shù)據(jù)會(huì)丟失,因?yàn)樗苯訉?xiě)到一級(jí)緩存中就完事了,但是一級(jí)緩存其他cpu是訪問(wèn)不到的,因此從可靠性的角度上來(lái)說(shuō)通寫(xiě)方式會(huì)更靠譜。具體采用哪種方式得你自己按需而定啦。
四.io設(shè)備
1.io設(shè)備由設(shè)備控制器和設(shè)備本身組成。
設(shè)備控制器:集成在主板的一塊芯片活一組芯片。負(fù)責(zé)從操作系統(tǒng)接收命令,并完成命令的執(zhí)行。比如負(fù)責(zé)從操作系統(tǒng)中讀取數(shù)據(jù)。
設(shè)備本身:其有自己的接口,但是設(shè)備本身的接口并不可用,它只是一個(gè)物理接口。如ide接口。
擴(kuò)展小知識(shí):
每個(gè)控制器都有少量的用于通信的寄存器(幾個(gè)到幾十個(gè)不等)。這個(gè)寄存器是直接集成到設(shè)備控制器內(nèi)部的。比方說(shuō),一個(gè)最小化的磁盤(pán)控制器,它也會(huì)用于指定磁盤(pán)地址,扇區(qū)計(jì)數(shù),讀寫(xiě)方向等相關(guān)操作請(qǐng)求的寄存器。所以任何時(shí)候想要激活控制器,設(shè)備驅(qū)動(dòng)程序從操作系統(tǒng)中接收操作指令,然后將它轉(zhuǎn)換成對(duì)應(yīng)設(shè)備的基本操作,并把操作請(qǐng)求放置在寄存器中才能完成操作的。每個(gè)寄存器表現(xiàn)為一個(gè)io端口。所有的寄存器組合稱(chēng)為設(shè)備的i/o地址空間,也叫i/o端口空間,
2.驅(qū)動(dòng)程序
真正的硬件操作是由驅(qū)動(dòng)程序操作完成的。驅(qū)動(dòng)程序通常應(yīng)該由設(shè)備生產(chǎn)上完成,通常驅(qū)動(dòng)程序位于內(nèi)核中,雖然驅(qū)動(dòng)程序可以在內(nèi)核外運(yùn)行,但是很少有人這么玩,因?yàn)樗托世玻?/p>
3.實(shí)現(xiàn)輸入和輸出
設(shè)備的i/o端口沒(méi)法事前分配,因?yàn)楦鱾€(gè)主板的型號(hào)不一致,所以我們需要做到動(dòng)態(tài)指定。電腦在開(kāi)機(jī)的時(shí)候,每個(gè)io設(shè)備都要想總線的i/o端口空間注冊(cè)使用i/o端口。這個(gè)動(dòng)態(tài)端口是由所有的寄存器組合成為設(shè)備的i/o地址空間,有2^16次方個(gè)端口,即65535個(gè)端口。
如上圖所示,我們的cpu有要想跟指定設(shè)備打交道,就需要把指令傳給驅(qū)動(dòng),然后驅(qū)動(dòng)講cpu的指令轉(zhuǎn)換成設(shè)備能理解的信號(hào)放在寄存器中(也可以叫套接字,socket).所以說(shuō)寄存器(i/o端口)是cpu通過(guò)總線和設(shè)備打交道的地址(i/o端口)。
擴(kuò)展小知識(shí):
三種方式實(shí)現(xiàn)i/o設(shè)備的輸入和輸出:
a..輪詢(xún):
通常指的是用戶(hù)程序發(fā)起一個(gè)系統(tǒng)調(diào)用,內(nèi)核將其翻譯成一個(gè)內(nèi)核對(duì)應(yīng)驅(qū)動(dòng)的過(guò)程調(diào)用,然后設(shè)備驅(qū)動(dòng)程序啟動(dòng)i/o,并在一個(gè)連續(xù)循環(huán)不斷中檢查該設(shè)備,并看該設(shè)備是否完成了工作。這有點(diǎn)類(lèi)似于忙等待(就是cpu會(huì)用固定周期不斷通過(guò)遍歷的方式去查看每一個(gè)i/o設(shè)備去查看是否有數(shù)據(jù), 顯然這種效率并不理想。),
b..中斷:
中斷cpu正在處理的程序,中斷cpu正在執(zhí)行的操作,從而通知內(nèi)核來(lái)獲取中斷請(qǐng)求。在我們的主板通常有一個(gè)獨(dú)特的設(shè)備,叫做可編程中斷控制器。這個(gè)中斷控制器可以通過(guò)某個(gè)針腳和cpu直接進(jìn)行通信,能夠出發(fā)cpu發(fā)生某個(gè)位置偏轉(zhuǎn),進(jìn)而讓cpu知道某個(gè)信號(hào)到達(dá)。中斷控制器上會(huì)有一個(gè)中斷向量(我們每一個(gè)i/o設(shè)備在啟動(dòng)時(shí),要想中斷控制器注冊(cè)一個(gè)中斷號(hào),這個(gè)號(hào)通常是唯一的。通常中斷向量的每一個(gè)針腳都是可以識(shí)別多個(gè)中斷號(hào)的),也可以叫中斷號(hào)。
因此當(dāng)這個(gè)設(shè)備真正發(fā)生中斷時(shí),這個(gè)設(shè)備不會(huì)把數(shù)據(jù)直接放到總線上,這個(gè)設(shè)備會(huì)立即向中斷控制器發(fā)出中斷請(qǐng)求,中斷控制器通過(guò)中斷向量識(shí)別這個(gè)請(qǐng)求是哪個(gè)設(shè)備發(fā)來(lái)的,然后通過(guò)某種方式通知給cpu,讓cpu知道具體哪個(gè)設(shè)備中斷求情到達(dá)了。這個(gè)時(shí)候cpu可以根據(jù)設(shè)備注冊(cè)使用i/o端口號(hào),從而就能獲取到設(shè)備的數(shù)據(jù)了。(注意,cpu是不能直接取數(shù)據(jù)的喲,因?yàn)樗皇墙邮盏搅酥袛嘈盘?hào),它只能通知內(nèi)核,讓內(nèi)核自己運(yùn)行在cpu上,由內(nèi)核來(lái)獲取中斷請(qǐng)求。)舉個(gè)例子,一個(gè)網(wǎng)卡接收到外來(lái)ip的請(qǐng)求,網(wǎng)卡也有自己的緩存區(qū),cpu講網(wǎng)卡中的緩存拿到內(nèi)存中進(jìn)行去讀,先判斷是不是自己的ip,如果是就開(kāi)始拆報(bào)文,最后會(huì)獲取到一個(gè)端口號(hào),然后cpiu在自己的中斷控制器去找這個(gè)端口,并做相應(yīng)的處理。
內(nèi)核中斷處理分為兩步:中斷上半部分(立即處理)和中斷下半部分(不一定)。還是從網(wǎng)卡接收數(shù)據(jù)為例,當(dāng)用戶(hù)請(qǐng)求到達(dá)網(wǎng)卡時(shí),cpu會(huì)命令講網(wǎng)卡緩存區(qū)的數(shù)據(jù)直接拿到內(nèi)存中來(lái),也就是接收到數(shù)據(jù)后會(huì)立即處理(此處的處理就是將網(wǎng)卡的數(shù)據(jù)讀到內(nèi)存中而已,不做下一步處理,以方便以后處理的。),這個(gè)我們稱(chēng)之為中斷的上半部分,而后來(lái)真正來(lái)處理這個(gè)請(qǐng)求的叫做下半部份
c.dma:
直接內(nèi)存訪問(wèn),大家都知道數(shù)據(jù)的傳輸都是在總線上實(shí)現(xiàn)的,cpu是控制總線的使用者,在某一時(shí)刻到底是有哪個(gè)i/o設(shè)備使用總線是由cpu的控制器來(lái)決定的。總線有三個(gè)功能分別是:地址總線(完成對(duì)設(shè)備的尋址功能),控制總線(控制各個(gè)設(shè)備地址使用總線的功能)以及數(shù)據(jù)總線(實(shí)現(xiàn)數(shù)據(jù)傳輸)。
通常是i/o設(shè)備自帶的一個(gè)具有智能型的控制芯片(我們稱(chēng)之為直接內(nèi)存訪問(wèn)控制器),當(dāng)需要處理中斷上半部分時(shí),cpu會(huì)告知dma設(shè)備,接下來(lái)總線歸dma設(shè)備使用,并且告知其可以使用的內(nèi)存空間,用于將i/o設(shè)備的數(shù)據(jù)讀取到內(nèi)存空間中去。當(dāng)dma的i/o設(shè)備將數(shù)據(jù)讀取完成后,會(huì)發(fā)送消息告訴cpu以及完成了讀取操作,這個(gè)時(shí)候cpu再回通知內(nèi)核數(shù)據(jù)已經(jīng)加載完畢,具體中斷下半部分的處理就來(lái)交個(gè)內(nèi)核處理了。現(xiàn)在大多數(shù)設(shè)備都是用dma控制器的,比如:網(wǎng)卡,硬盤(pán)等等。
五.操作系統(tǒng)概念
通過(guò)上面的學(xué)習(xí),我們知道了的計(jì)算機(jī)有五大基本部件。操作系統(tǒng)主要就是把這五個(gè)部件給它抽象為比較直觀的接口,由上層程序員或者用戶(hù)直接使用的。那事實(shí)上在操作系統(tǒng)中被抽象出來(lái)的東西又該是什么呢?
1.cpu(time slice)
在操作系統(tǒng)中,cpu被抽象成了時(shí)間片,而后將程序抽象成進(jìn)程,通過(guò)分配時(shí)間片讓程序運(yùn)行起來(lái)。cpu有尋址單元用于來(lái)識(shí)別變量在內(nèi)存的中所保存的集體內(nèi)存地址。
而我們主機(jī)內(nèi)部的總線是取決于cpu的位寬(也叫字長(zhǎng)),比如32bit的地址總線,它能表示2的32次方個(gè)內(nèi)存地址,轉(zhuǎn)換成10進(jìn)制就是4g內(nèi)存空間,這個(gè)時(shí)候你應(yīng)該就明白為什么32位的操作系統(tǒng)中只能識(shí)別4g內(nèi)存了吧?即使你的物理內(nèi)存是16g,但是可用的還是4g,所以,你如果發(fā)現(xiàn)你的操作系統(tǒng)能識(shí)別4g以上的內(nèi)存地址,那么你的操作系統(tǒng)一定就不是32位的啦!
2.內(nèi)存(memory)
在操作系統(tǒng)中,內(nèi)存的實(shí)現(xiàn)是通過(guò)虛擬地址空間來(lái)實(shí)現(xiàn)的。
3.i/o設(shè)備
在操作系統(tǒng)中,最核心的i/o設(shè)備就是磁盤(pán),大家都知道磁盤(pán)是提供存儲(chǔ)空間的,在內(nèi)核中把它抽象成了文件。
4.進(jìn)程
說(shuō)白了,計(jì)算機(jī)存在的主要目的不就是運(yùn)行程序嗎?程序跑起來(lái),我們統(tǒng)一叫進(jìn)程(我們暫時(shí)不用理會(huì)線程)。那如果多個(gè)進(jìn)程同時(shí)運(yùn)行就意味著把這些有限的抽象資源(cpu,memory等等)分配給多個(gè)進(jìn)程。我們把這些抽象資源統(tǒng)稱(chēng)為資源集。
資源集包括:
1>.cpu時(shí)間;
2>.內(nèi)存地址:抽象成虛擬地址空間(如32位操作系統(tǒng),支持4g空間,內(nèi)核占用1g空間,進(jìn)程也會(huì)默認(rèn)自己有3g可用,事實(shí)上未必有3g空間,因?yàn)槟愕碾娔X可能會(huì)是小于4g的內(nèi)存。)
3>.i/o:一切皆文件打開(kāi)的多個(gè)文件,通過(guò)fd(文件描述符,file descriptor)打開(kāi)指定的文件。我們把文件分為三類(lèi):正常文件、設(shè)備文件、管道文件。
每一個(gè)進(jìn)行都有自己作業(yè)地址結(jié)構(gòu),即:task struct。其就是內(nèi)核為每個(gè)進(jìn)程維護(hù)的一個(gè)數(shù)據(jù)結(jié)構(gòu)(一個(gè)數(shù)據(jù)結(jié)構(gòu)就是用來(lái)保存數(shù)據(jù)的,說(shuō)白了就是內(nèi)存空間,記錄著該進(jìn)程所擁有的資源集,當(dāng)然還有它的父進(jìn)程,保存現(xiàn)場(chǎng)【用于進(jìn)程切換】,內(nèi)存映射等待)。task struct模擬出來(lái)了線性地址,讓進(jìn)程去使用這些線性地址,但是它會(huì)記錄著線性地址和物理內(nèi)存地址的映射關(guān)系的。
5.內(nèi)存映射-頁(yè)框
只要不是內(nèi)核使用的物理內(nèi)存空間我們稱(chēng)之為用戶(hù)空間。內(nèi)核會(huì)吧用戶(hù)空間的物理內(nèi)存切割成固定大小的頁(yè)框(即page frame),歡聚話(huà)說(shuō),就是且更成一個(gè)固定大小的存儲(chǔ)單位,比默認(rèn)的單個(gè)存儲(chǔ)單元(默認(rèn)是一個(gè)字節(jié),即8bit)要大.通常每4k一個(gè)存儲(chǔ)單位。每一個(gè)頁(yè)框作為一個(gè)獨(dú)立的單元向外進(jìn)行分配,且每一個(gè)頁(yè)框也都其編號(hào)。【舉個(gè)例子:假設(shè)有4g空間可用,每一個(gè)頁(yè)框是4k,一共有1m個(gè)頁(yè)框。】這些頁(yè)框要分配給不同的進(jìn)程使用。
我們假設(shè)你有4g內(nèi)存,操作系統(tǒng)占用了1個(gè)g,剩余的3g物理內(nèi)存分配給用戶(hù)空間使用。每一進(jìn)程啟動(dòng)之后,都會(huì)認(rèn)為自己有3g空間可用,但是實(shí)際上它壓根就用不完3g。進(jìn)程進(jìn)行寫(xiě)入內(nèi)存是被離散存儲(chǔ)的。哪有空余內(nèi)存就往哪存取。具體的存取算法不要問(wèn)我,我也沒(méi)有研究過(guò)。
進(jìn)程空間結(jié)構(gòu):
1>.預(yù)留空間
2>.棧(變量存放處)
3>.共享庫(kù)
4>.堆(打開(kāi)一個(gè)文件,文件中的數(shù)據(jù)流存放處)
5>.數(shù)據(jù)段(全局的靜態(tài)變量存放處)
6>.代碼段
進(jìn)程和內(nèi)存的存儲(chǔ)關(guān)系如下:
每個(gè)進(jìn)程空間都有預(yù)留空間,當(dāng)某個(gè)進(jìn)程發(fā)現(xiàn)自己打開(kāi)的數(shù)據(jù)已經(jīng)不夠用,它需要打開(kāi)一個(gè)新文件(打開(kāi)一個(gè)新文件就需要在進(jìn)程的地址空間存放數(shù)據(jù)),很顯然我們上圖的進(jìn)程地址空間是線性的并不是真正意義上的。當(dāng)一個(gè)進(jìn)程真正去申請(qǐng)使用一個(gè)內(nèi)存時(shí),需要向內(nèi)核發(fā)起系統(tǒng)調(diào)用,由內(nèi)核在物理內(nèi)存上找一個(gè)物理空間,并告訴該進(jìn)程可以使用的內(nèi)存地址。比方說(shuō)進(jìn)程要在堆上打開(kāi)一個(gè)文件,它需要向操作系統(tǒng)(內(nèi)核)申請(qǐng)使用內(nèi)存空間,且在物理內(nèi)存允許的范圍內(nèi)(即請(qǐng)求的內(nèi)存需要小于空閑物理內(nèi)存),內(nèi)核會(huì)分配給該進(jìn)程內(nèi)存地址。
每一進(jìn)程都有自己想線性地址,這個(gè)地址是操作系統(tǒng)虛擬出來(lái)的,并不真實(shí)存在,它需要把這個(gè)虛擬地址和真正的物理內(nèi)存做一個(gè)映射關(guān)系,如圖“進(jìn)程和內(nèi)存的存儲(chǔ)關(guān)系”,最終的進(jìn)程數(shù)據(jù)的存放處位置還是映射到內(nèi)存中了。這就意味著,當(dāng)一個(gè)進(jìn)行跑到cpu上執(zhí)行時(shí),它告訴cpu的是自己的線性地址,這時(shí)候cpu不會(huì)直接去找這個(gè)線性地址(因?yàn)榫€性地址是虛擬出來(lái)的,不真實(shí)存在,真正存放地址進(jìn)程的是物理內(nèi)存地址。),它會(huì)先去找這歌進(jìn)程的“task struct”,并裝載頁(yè)表(page table)[記錄著線性地址到物理內(nèi)存的映射關(guān)系,每一個(gè)對(duì)應(yīng)關(guān)系叫做一個(gè)頁(yè)表項(xiàng)。],以讀取到進(jìn)程的所擁有的線性地址所對(duì)應(yīng)的真正的物理內(nèi)存地址。
擴(kuò)展小知識(shí):
cpu訪問(wèn)進(jìn)程的地址時(shí),首先獲取到的是進(jìn)程的線性地址,它將這個(gè)線性地址交給自己的芯片mmu進(jìn)行計(jì)算,得到真正的物理內(nèi)存地址,從而達(dá)到訪問(wèn)進(jìn)程內(nèi)存地址的目的。換句話(huà)說(shuō),只要他想要訪問(wèn)一個(gè)進(jìn)程的內(nèi)存地址,就必須經(jīng)過(guò)mmu運(yùn)算,這樣導(dǎo)致效率很低,因此他們有引進(jìn)了一個(gè)緩存,用于存放頻繁訪問(wèn)的數(shù)據(jù),這樣就可以提高效率,不用mmu進(jìn)行計(jì)算,直接拿到數(shù)據(jù)去處理就ok了,這個(gè)緩存器我們稱(chēng)之為:tlb:轉(zhuǎn)換后援緩沖器(緩存頁(yè)表的查詢(xún)結(jié)果)
注意:在32bit的操作系統(tǒng)是線線地址到物理內(nèi)存的映射。而在64bit操作系統(tǒng)是恰恰相反的!
6.用戶(hù)態(tài)和內(nèi)核態(tài)
操作系統(tǒng)運(yùn)行時(shí)為了呢能夠?qū)崿F(xiàn)協(xié)調(diào)多任務(wù),操作系統(tǒng)被分割成了2段,其中接近于硬件一段具有特權(quán)權(quán)限的叫做內(nèi)核空間,而進(jìn)程運(yùn)行在用戶(hù)空間當(dāng)中。所以說(shuō),應(yīng)用程序需要使用特權(quán)指令或是要訪問(wèn)硬件資源時(shí)需要系統(tǒng)調(diào)用。
只要是被開(kāi)發(fā)成應(yīng)用程序的,不是作為操作系統(tǒng)本身的一部分而存在的,我們稱(chēng)之為用戶(hù)空間的程序。他們運(yùn)行狀態(tài)稱(chēng)之為用戶(hù)態(tài)。
需要在內(nèi)核(我們可以認(rèn)為是操作系統(tǒng))空間運(yùn)行的程序,我們稱(chēng)之他們運(yùn)行在內(nèi)核空間,他們運(yùn)行的狀態(tài)為用戶(hù)態(tài),也叫核心態(tài)。注意:內(nèi)核不負(fù)責(zé)完成具體工作。在內(nèi)核空間可用執(zhí)行任何特權(quán)操作。
每一個(gè)程序要想真正運(yùn)行起來(lái),它最終是向內(nèi)核發(fā)起系統(tǒng)調(diào)用來(lái)完成的,或者有一部分的程序不需要內(nèi)核的參與,有我們的應(yīng)用程序就能完成。我們打個(gè)比方,你要計(jì)算2的32次方的結(jié)果,是否需要運(yùn)行在內(nèi)核態(tài)呢?答案是否定的,我們知道內(nèi)核是不負(fù)責(zé)完成具體工作的,我們只是想要計(jì)算一個(gè)運(yùn)算結(jié)果,也不需要調(diào)用任何的特權(quán)模式,因此,如果你寫(xiě)了一些關(guān)于計(jì)算數(shù)值的代碼,只需要把這個(gè)代碼交給cpu運(yùn)行就可以了。
如果一個(gè)應(yīng)用程序需要調(diào)用內(nèi)核的功能而不是用戶(hù)程序的功能的話(huà),應(yīng)用程序會(huì)發(fā)現(xiàn)自己需要做一個(gè)特權(quán)操作,而應(yīng)用程序自身沒(méi)有這個(gè)能力,應(yīng)用程序會(huì)向內(nèi)核發(fā)申請(qǐng),讓內(nèi)核幫忙完成特權(quán)操作。內(nèi)核發(fā)現(xiàn)應(yīng)用程序是有權(quán)限使用特權(quán)指令的,內(nèi)核會(huì)運(yùn)行這些特權(quán)指令并把執(zhí)行結(jié)果返回給應(yīng)用程序,然后這個(gè)應(yīng)用程序拿到特權(quán)指令的執(zhí)行結(jié)果后,繼續(xù)后續(xù)的代碼。這就是模式轉(zhuǎn)換。
因此一個(gè)程序員想要讓你的程序具有生產(chǎn)力,就應(yīng)該盡量讓你的代碼運(yùn)行在用戶(hù)空間,如果你的代碼大多數(shù)都運(yùn)行在內(nèi)核空間的話(huà),估計(jì)你的應(yīng)用程序并不會(huì)給你打來(lái)太大的生產(chǎn)力喲。因?yàn)槲覀冎纼?nèi)核空間不負(fù)責(zé)產(chǎn)生生產(chǎn)力。
擴(kuò)充小知識(shí):
我們知道計(jì)算機(jī)的運(yùn)行就是運(yùn)行指定的。指令還分特權(quán)指令級(jí)別和非特權(quán)指令級(jí)別。了解過(guò)計(jì)算機(jī)的朋友可能知道x86的cpu架構(gòu)大概分成了四個(gè)層次,由內(nèi)之外共有四個(gè)環(huán),被稱(chēng)為環(huán)0,環(huán)1,環(huán)2,環(huán)3。我們知道環(huán)0的都是特權(quán)指令,環(huán)3的都是用戶(hù)指令。一般來(lái)講,特權(quán)指令級(jí)別是指操作硬件,控制總線等等。
一個(gè)程序的執(zhí)行,需要在內(nèi)核的協(xié)調(diào)下,有可能在用戶(hù)態(tài)和內(nèi)核態(tài)互相切換,所以說(shuō)一個(gè)程序的執(zhí)行,一定是內(nèi)核調(diào)度它到cpu上去執(zhí)行的 。有些應(yīng)用程序是操作系統(tǒng)運(yùn)行過(guò)程當(dāng)中,為了完成基本功能而運(yùn)行的,我們就讓他在后臺(tái)自動(dòng)運(yùn)行,這叫守護(hù)進(jìn)程。但是有的程序是用戶(hù)需要的時(shí)候才運(yùn)行的,那如何通知內(nèi)核講我們需要的應(yīng)用程序運(yùn)行起來(lái)呢?這個(gè)時(shí)候你就需要一個(gè)解釋器,它能和操作系統(tǒng)打交道,能夠發(fā)起指令的執(zhí)行。說(shuō)白了就是能夠把用戶(hù)需要的運(yùn)行請(qǐng)求提交給內(nèi)核,進(jìn)而內(nèi)核給它開(kāi)放其運(yùn)行所需要的有賴(lài)于的基本條件。從而程序就執(zhí)行起來(lái)了。
下面我們?cè)诳赐扑]幾本關(guān)于linux操作系統(tǒng)原理的書(shū)
linux操作系統(tǒng)原理電子書(shū)
操作系統(tǒng)原理及應(yīng)用(linux) pdf掃描版[30mb]
深度探索linux操作系統(tǒng):系統(tǒng)構(gòu)建和原理解析 pdf掃描版[129mb]
操作系統(tǒng)原理linux篇 徐德民 pdf
linux內(nèi)核注釋 孫更新等 pdf掃描版(86m)
linux操作系統(tǒng)視頻內(nèi)容
跟阿銘學(xué)Linux第二版最新版(附阿銘linux全套視頻教程)chm格式
linux系統(tǒng)掛載數(shù)據(jù)盤(pán)的方法(視頻圖文教程)
以上就是我們給大家整理的關(guān)于linux操作系統(tǒng)原理 linux系統(tǒng)基礎(chǔ)教程的全部?jī)?nèi)容,希望我們整理的內(nèi)容能夠給你提供到幫助。