[MIT6.S081] 1.2 操作系統(tǒng)結(jié)構(gòu)

(轉(zhuǎn)載鏈接:https://mit-public-courses-cn-translatio.gitbook.io/mit6-s081/ )?
過去幾十年,人們將一些分層的設(shè)計(jì)思想加入到操作系統(tǒng)中,并運(yùn)行的很好。我將會(huì)為你列出操作系統(tǒng)經(jīng)典的組織結(jié)構(gòu),這個(gè)組織結(jié)構(gòu)同時(shí)也是這門課程的主要內(nèi)容,這里的組織結(jié)構(gòu)對于操作系統(tǒng)來說還是挺常見的。
這里實(shí)際上就是操作系統(tǒng)內(nèi)部組成,當(dāng)我想到這里的組織結(jié)構(gòu)時(shí),我首先會(huì)想到用一個(gè)矩形表示一個(gè)計(jì)算機(jī),這個(gè)計(jì)算機(jī)有一些硬件資源,我會(huì)將它放在矩形的下面,硬件資源包括了CPU,內(nèi)存,磁盤,網(wǎng)卡。所以硬件資源在最低一層。

在這個(gè)架構(gòu)的最上層,我們會(huì)運(yùn)行各種各樣的應(yīng)用程序,或許有一個(gè)文本編輯器(VI),或許有一個(gè)C編譯器(CC),你還可以運(yùn)行大量我們今天會(huì)討論的其他事物,例如作為CLI存在的Shell,所以這些就是正在運(yùn)行的所有程序。這里程序都運(yùn)行在同一個(gè)空間中,這個(gè)空間通常會(huì)被稱為用戶空間(Userspace)。

區(qū)別于用戶空間程序,有一個(gè)特殊的程序總是會(huì)在運(yùn)行,它稱為Kernel。Kernel是計(jì)算機(jī)資源的守護(hù)者。當(dāng)你打開計(jì)算機(jī)時(shí),Kernel總是第一個(gè)被啟動(dòng)。Kernel程序只有一個(gè),它維護(hù)數(shù)據(jù)來管理每一個(gè)用戶空間進(jìn)程。Kernel同時(shí)還維護(hù)了大量的數(shù)據(jù)結(jié)構(gòu)來幫助它管理各種各樣的硬件資源,以供用戶空間的程序使用。Kernel同時(shí)還有大量內(nèi)置的服務(wù),例如,Kernel通常會(huì)有文件系統(tǒng)實(shí)現(xiàn)類似文件名,文件內(nèi)容,目錄的東西,并理解如何將文件存儲在磁盤中。所以用戶空間的程序會(huì)與Kernel中的文件系統(tǒng)交互,文件系統(tǒng)再與磁盤交互。
在這門課程中,我們主要關(guān)注點(diǎn)在Kernel、連接Kernal和用戶空間程序的接口、Kernel內(nèi)軟件的架構(gòu)。所以,我們會(huì)關(guān)心Kernel中的服務(wù),其中一個(gè)服務(wù)是文件系統(tǒng),另一個(gè)就是進(jìn)程管理系統(tǒng)。每一個(gè)用戶空間程序都被稱為一個(gè)進(jìn)程,它們有自己的內(nèi)存和共享的CPU時(shí)間。同時(shí),Kernel會(huì)管理內(nèi)存的分配。不同的進(jìn)程需要不同數(shù)量的內(nèi)存,Kernel會(huì)復(fù)用內(nèi)存、劃分內(nèi)存,并為所有的進(jìn)程分配內(nèi)存。
文件系統(tǒng)通常有一些邏輯分區(qū)。目前而言,我們可以認(rèn)為文件系統(tǒng)的作用是管理文件內(nèi)容并找出文件具體在磁盤中的哪個(gè)位置。文件系統(tǒng)還維護(hù)了一個(gè)獨(dú)立的命名空間,其中每個(gè)文件都有文件名,并且命名空間中有一個(gè)層級的目錄,每個(gè)目錄包含了一些文件。所有這些都被文件系統(tǒng)所管理。
這里還有一些安全的考慮,我們可以稱之為Access Control。當(dāng)一個(gè)進(jìn)程想要使用某些資源時(shí),比如讀取磁盤中的數(shù)據(jù),使用某些內(nèi)存,Kernel中的Access Control機(jī)制會(huì)決定是否允許這樣的操作。對于一個(gè)分時(shí)共享的計(jì)算機(jī),例如Athena系統(tǒng),這里可能會(huì)變得很復(fù)雜。因?yàn)樵贏thena系統(tǒng)中,每一個(gè)進(jìn)程可能屬于不同的用戶,因此會(huì)有不同Access規(guī)則來約定哪些資源可以被訪問。
在一個(gè)真實(shí)的完備的操作系統(tǒng)中,會(huì)有很多很多其他的服務(wù),比如在不同進(jìn)程之間通信的進(jìn)程間通信服務(wù),比如一大票與網(wǎng)絡(luò)關(guān)聯(lián)的軟件(TCP/IP協(xié)議棧),比如支持聲卡的軟件,比如支持?jǐn)?shù)百種不同磁盤,不同網(wǎng)卡的驅(qū)動(dòng)。所以在一個(gè)完備的系統(tǒng)中,Kernel會(huì)包含大量的內(nèi)容,數(shù)百萬行代碼。

這就是對于Kernel的一個(gè)快速瀏覽。
我們同時(shí)也對應(yīng)用程序是如何與Kernel交互,它們之間的接口長什么樣感興趣。這里通常成為Kernel的API,它決定了應(yīng)用程序如何訪問Kernel。通常來說,這里是通過所謂的系統(tǒng)調(diào)用(System Call)來完成。系統(tǒng)調(diào)用與程序中的函數(shù)調(diào)用看起來是一樣的,但區(qū)別是系統(tǒng)調(diào)用會(huì)實(shí)際運(yùn)行到系統(tǒng)內(nèi)核中,并執(zhí)行內(nèi)核中對于系統(tǒng)調(diào)用的實(shí)現(xiàn)。在這門課程的后面,我會(huì)詳細(xì)介紹系統(tǒng)調(diào)用?,F(xiàn)在,我只會(huì)介紹一些系統(tǒng)調(diào)用在應(yīng)用程序中是長什么樣的。
第一個(gè)例子是,如果應(yīng)用程序需要打開一個(gè)文件,它會(huì)調(diào)用名為open的系統(tǒng)調(diào)用,并且把文件名作為參數(shù)傳給open。假設(shè)現(xiàn)在要打開一個(gè)名為“out”的文件,那么會(huì)將文件名“out”作為參數(shù)傳入。同時(shí)我們還希望寫入數(shù)據(jù),那么還會(huì)有一個(gè)額外的參數(shù),在這里這個(gè)參數(shù)的值是1,表明我想要寫文件。

這里看起來像是個(gè)函數(shù)調(diào)用,但是open是一個(gè)系統(tǒng)調(diào)用,它會(huì)跳到Kernel,Kernel可以獲取到open的參數(shù),執(zhí)行一些實(shí)現(xiàn)了open的Kernel代碼,或許會(huì)與磁盤有一些交互,最后返回一個(gè)文件描述符對象。上圖中的fd全稱就是file descriptor。之后,應(yīng)用程序可以使用這個(gè)文件描述符作為handle,來表示相應(yīng)打開的文件。
如果你想要向文件寫入數(shù)據(jù),相應(yīng)的系統(tǒng)調(diào)用是write。你需要向write傳遞一個(gè)由open返回的文件描述符作為參數(shù)。你還需要向write傳遞一個(gè)指向要寫入數(shù)據(jù)的指針(數(shù)據(jù)通常是char型序列),在C語言中,可以簡單傳遞一個(gè)雙引號表示的字符串(下圖中的\n表示是換行)。第三個(gè)參數(shù)是你想要寫入字符的數(shù)量。

第二個(gè)參數(shù)的指針,實(shí)際上是內(nèi)存中的地址。所以這里實(shí)際上告訴內(nèi)核,將內(nèi)存中這個(gè)地址起始的6個(gè)字節(jié)數(shù)據(jù)寫入到fd對應(yīng)的文件中。
另一個(gè)你可能會(huì)用到的,更有意思的系統(tǒng)調(diào)用是fork。fork是一個(gè)這樣的系統(tǒng)調(diào)用,它創(chuàng)建了一個(gè)與調(diào)用進(jìn)程一模一樣的新的進(jìn)程,并返回新進(jìn)程的process ID/pid。這里實(shí)際上會(huì)復(fù)雜的多,我們后面會(huì)有更多的介紹。

所以對吧?這些系統(tǒng)調(diào)用看起來就跟普通的函數(shù)調(diào)用一樣。系統(tǒng)調(diào)用不同的地方是,它最終會(huì)跳到系統(tǒng)內(nèi)核中。
這里只是淺嘗輒止,我們后面會(huì)介紹更多。所以這些是一些快速預(yù)覽。
[MIT6.S081] 1.2 操作系統(tǒng)結(jié)構(gòu)的評論 (共 條)
