新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 深度介紹Linux內(nèi)核是如何工作的

        深度介紹Linux內(nèi)核是如何工作的

        作者: 時間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

        本文發(fā)表于Linux Format magazine雜志,作者從技術(shù)深度上解釋了Linux Kernel是如何工作的。相信對Linux開發(fā)者來說有不小的幫助。

        本文引用地址:http://www.104case.com/article/201610/305866.htm

        牛津字典中對kernel一詞的定義是:較軟的、通常是一個堅果可食用的部分。當(dāng)然還有第二種定義:某個東西核心或者最重要的部分。對Linux來說,它的Kernel無疑屬于第二種解釋。讓我們來看看這個重要的東西是如何工作的,先從一點(diǎn)理論說起。

        廣義地來說kernel就是一個軟件,它在硬件和運(yùn)行在計算機(jī)上的應(yīng)用程序之間提供了一個層。嚴(yán)格點(diǎn)從計算機(jī)科學(xué)的角度來說,Linux中的Kernel指的是Linus Torvalds在90年代初期寫的那點(diǎn)代碼。

        所有的你在Linux各版本中看到的其他東西--Bash shell、KDE窗口管理器、web瀏覽器、X服務(wù)器、Tux Racer以及所有的其他,都不過是運(yùn)行在Linux上的應(yīng)用而已,而不是操作系統(tǒng)自身的一部分。為了給大家一個更加直觀的感覺,我來舉個例子,比如RHEL5的安裝大概要占據(jù)2.5GB的硬盤空間(具體多大當(dāng)然視你的選擇安裝來定),在這其中,kernel以及它的各個模塊組件,只有47MB,所占比例約為2%。

        在kernel內(nèi)部

        那么kernel到底是如何工作的呢?如下面的圖表。Kernel通過許多的進(jìn)入端口也就是我們從技術(shù)角度所說的系統(tǒng)調(diào)用,來使得運(yùn)行在它上面的應(yīng)用程序可用。Kernel使用的系統(tǒng)調(diào)用比如讀和寫來提供你硬件的抽象(abstraction)。

        從程序員的視角來看,這些看起來只是普通的功能調(diào)用,然而實(shí)際上系統(tǒng)調(diào)用在處理器的操作模式上,從用戶空間到Kernel空間有一個明顯的切換。同時,系統(tǒng)調(diào)用提供了一個Linux虛擬機(jī),可以被認(rèn)為是對硬件的抽象。

        Kernel提供的更明顯的抽象之一是文件系統(tǒng)。舉例來說,這里有一段短的程序是用C寫的,它打開了一個文件并將內(nèi)容拷貝到標(biāo)準(zhǔn)的輸出:

        #include

        int main()

        {

        int fd, count; char buf[1000];

        fd=open(mydata, O_RDONLY);

        count = read(fd, buf, 1000);

        write(1, buf, count);

        close(fd);

        }

        在這里,你可以看到四個系統(tǒng)調(diào)用的例子:打開、讀、寫和關(guān)閉。不談這段程序語法的細(xì)節(jié),重點(diǎn)是:通過這些系統(tǒng)調(diào)用Linux Kernel提供了一個文件的錯覺,而實(shí)際上它不過是一堆數(shù)據(jù)有了個名字,這樣一來你就不必去與硬件底層的堆棧、分區(qū)、頭和指針、分區(qū)等交涉了,而是直接以例子中的方式與硬件交流,這也就是我們所說的抽象(abstraction),將底層的東西以更易懂的方式表達(dá)出來。

        臺前幕后

        系統(tǒng)文件是Kernel提供的較為明顯的一種抽象。還有一些特性不是這么的明顯,比如進(jìn)程調(diào)度。任何一個時間,都可能有好幾個進(jìn)程或者程序等待著運(yùn)行。Kernel的時間調(diào)度給每個進(jìn)程分配CPU時間,所以就一段時間內(nèi)來說,我們會有種錯覺:電腦同一時間運(yùn)行好幾個程序。這是另外一個C程序:

        #include

        main()

        {

        if (fork()) {

        write(1, Parentn, 7);

        wait(0);

        exit(0);

        }

        else {

        write(1, Childn, 6);

        exit(0);

        }

        }

        在這個程序中創(chuàng)建了一個新進(jìn)程,而原來的進(jìn)程(父進(jìn)程)和新進(jìn)程(子進(jìn)程)都編寫了標(biāo)準(zhǔn)輸出然后結(jié)束。注意系統(tǒng)調(diào)用fork(), exit() 以及 wait()執(zhí)行程序的創(chuàng)建、結(jié)束和各自同步。這是進(jìn)程管理和調(diào)度中最典型的簡單調(diào)用。

        Kernel還有一個更加不易見到的功能,連程序員都不易察覺,那就是存儲管理。每個程序運(yùn)行得都好像它有個自己的地址空間來調(diào)用一樣,實(shí)際上它跟其他進(jìn)程一樣共享計算機(jī)的物理存儲,如果系統(tǒng)運(yùn)行的存儲過低,它的地址空間甚至?xí)淮疟P的交互區(qū)暫時寄用。存儲管理的另外一個方面是防止一個進(jìn)程訪問其他進(jìn)程的地址空間--對于多進(jìn)程操作系統(tǒng)來說這是很必要的一個防范措施。

        Kernel同樣還配置網(wǎng)絡(luò)鏈接協(xié)議比如IP、TCP和UDP等,它們在網(wǎng)絡(luò)上提供機(jī)器對機(jī)器(machine-to-machine)和進(jìn)程對進(jìn)程(process-to-process)的通信。這里又會造成一種假象,即TCP在兩個進(jìn)程之間提供了一個固定連接--就好像連接兩個電話的銅線一樣,實(shí)際中卻并沒有固定的連接,特殊的引用協(xié)議比如FTP、DNS和HTTP是通過用戶級程序來實(shí)施的,而并非Kernel的一部分。

        Linux(像之前的Unix)在安全方面口碑很好,這是因?yàn)镵ernel跟蹤記錄了每個運(yùn)行進(jìn)程的user ID和group ID,每次當(dāng)一個應(yīng)用企圖訪問資源(比如打開一個文件來寫入)的時候,Kernel就會核對文件上的訪問許可然后做出允許/禁止的命令。這種訪問控制模式最終對整個Linux系統(tǒng)的安全作用很大。

        Kernel還提供了一大套模塊的集合,其功能包括如何處理與硬件設(shè)備交流的諸多細(xì)節(jié)、如何從磁盤讀取一個分區(qū)、如果從網(wǎng)絡(luò)接口卡獲取數(shù)據(jù)包等。有時我們稱這些為設(shè)備驅(qū)動。

        模塊化的Kernel

        現(xiàn)在我們隊Kernel是做什么的已經(jīng)有了一些了解,讓我們再來簡單看下它的物理組成。早期版本的Linux Kernel是整體式的,也就是說所有的部件都靜態(tài)地連接成一個(很大的)執(zhí)行文件。

        相比較而言,現(xiàn)在的Linux Kernel是模塊化的:許多功能包含在模塊內(nèi),然后動態(tài)地載入kernel中。這使得kernel的內(nèi)核很小,而且在運(yùn)行kernel時可以不必reboot就能載入和替代模塊。

        Kernel的內(nèi)核在boot time時從位于/boot 目錄的一個文件加載進(jìn)存儲中,通常這個/boot 目錄會被叫做KERNELVERSION,KERNELVERSION與kernel版本有關(guān)。(如果你想知道你的kernel版本是什么,運(yùn)行命令行顯示系統(tǒng)信息-r。)kernel的模塊位于目錄/lib/modules/KERNELVERSION之下,所有的組件都會在kernel安裝時被拷貝。

        管理模塊

        大部分情況下,Linux管理它的模塊不需要你的幫忙,但是如果必要的時候有命令行可以來手動檢查和管理模塊。比如,為了查清楚當(dāng)前到底哪個模塊在載入kernel。這里有一個輸出的例子:


        上一頁 1 2 3 下一頁

        關(guān)鍵詞:

        評論


        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 渭源县| 方正县| 禄劝| 绥阳县| 隆德县| 深圳市| 中牟县| 临城县| 仙居县| 子长县| 黄浦区| 新乡市| 翁源县| 荔波县| 灵寿县| 固镇县| 郎溪县| 开封县| 杨浦区| 酉阳| 太原市| 松桃| 绥宁县| 徐水县| 玉溪市| 东乡县| 静宁县| 广元市| 津市市| 喀喇| 将乐县| 碌曲县| 内乡县| 奉节县| 静海县| 江阴市| 开封县| 来凤县| 自治县| 巴青县| 延吉市|