從硬件到內核,聊聊Linux系統的層次結構
相信組裝過電腦的朋友都知道,我們的電腦最主要的幾個零件是:CPU、內存、硬盤。但我們實際使用的時候,我們并不會主動跟硬件打交道,而是和顯示器上顯示的操作系統打交道。
那么問題來了,操作系統到底是怎么操作CPU、內存、硬盤,讓其實現我們的功能的呢?操作系統與硬件之間的層級結構是怎樣的?
這里的操作系統,我們默認說的是 Linux 操作系統。
了解過 Linux 的朋友會知道,其實 Linux 系統的整個系統結構如下面所示:
它由內核、系統調用、Shell、庫函數、應用幾個部分構成。看著是不是有些暈頭轉向叻,沒關系。下面我將用極其簡單的口水文跟你介紹這幾個層級,讓你看完之后印象深刻。
硬件的好基友:內核
緊挨著硬件的是內核,只有內核才能操作硬件,一般我們也叫它內核空間。
大學學過模擬電路和數字電路的同學都知道,計算機里任何的運算到最后都是 1 0 數字,最終通過數字電路的來進行運算。例如我們要計算一個加法(4+5),對于我們來說就是簡單地一個運算,但對于計算機來說,它并不知道 4 是什么,5 是什么,它只知道 1 和 0。并且我們一步就可以算出來的加法,計算機可能要經過無數次運算。一個簡單的加法尚且如此,更不用說更加復雜的算法運算了。
舉上面這個例子主要是想表達硬件操作的復雜性,以及機器碼對于人類的不友好。所以為了對外屏蔽這些硬件細節,就有了內核空間這一層東西。
內核空間是一個虛擬的空間,其直接與硬件打交道。除了內核空間,其他任何模塊都無法與硬件直接接觸,都需要通過內核空間來操作硬件。所以說內核空間是硬件的好基友,任何人要見它,都得經過我。
這么一個設置也有一個好處,那就是保證了硬件的穩定。試想一下,如果誰都能操作硬件。你弄一下,我弄一下,那么硬件估計就被弄殘了。
系統的基石:系統調用
挨著內核兄弟的就是系統調用了,系統調用是操作系統的最小單位,任何操作都是由一個個系統調用組成的。這就像我們的漢字,無論這個字多復雜,它都是由點、橫、撇等組成。而系統調用之于操作系統,就像是筆畫之于漢字。
集大成者:庫函數
如果說系統調用是筆畫,那么庫函數就是漢字的偏旁了。我們記漢字不可能記住它的所有筆畫,但我們能記住它由哪一些偏旁組成。因此,在 Linux 操作系統中也類似,設計者一些常用的操作組合起來,編程庫函數。
例如一個簡單的變量內存分配操作,就需要動用多個系統調用。如果沒有庫函數,我們就得每次都去寫多次系統調用,但有了庫函數我們直接用 malloc() 庫函數就可以實現這個功能。
所以說,庫函數是集大成者,是系統調用的模塊化體現。
效率利器:Shell
我們除了使用庫函數去實現常用的操作之外,還可以使用 Shell 去實現。Shell 其實與庫函數的功能類似,他們都將一些常用的系統調用組裝起來,方便后續調用,可以說是模塊化的提現。
但是 Shell 與庫函數的定位還是略有不同的。庫函數更多時候是作為開發 API 來使用,應用通過調用 API 來實現各種功能。而 Shell 則更多是作為運維的工具,能通過 Shell 腳本實現更多復雜的功能。
Shell 不僅僅是操作系統中的一個層次,它還指某種特定的語言規范,通過這種語言規范,我們可以組裝成 Shell 腳本,從而實現復雜的功能。牛逼的運維都會使用 Shell 腳本來自動化處理業務,從而極大地提高工作效率。
友好使者:應用
在操作系統最外層就是應用了。在這一層我們可以調用 Shell、庫函數、系統調用這幾個層次的東西,從而方便我們的開發。我們常用的各種辦公軟件、圖像處理軟件都是這一層次的東西。
如果要選一個最人類最友好的使者,那么非應用這個小兄弟不可了。經歷了重重難關,從硬件到內核,再從內核到庫函數,最后到應用這一層才能看得比較舒服,我們也才能夠更高效地使用。
總結
許多工作了十幾年的工程師很多時候都搞不清楚操作系統的層級關系,更甚者連內核是什么都不知道。但樹義認為,了解操作系統的層級結構是很重要的知識點,可以為我們深入理解應用層面的知識打下基礎。
例如當我們學到 Netty 的時候,我們會學到 Unix 網絡 IO 模型,這時候就會涉及到數據是如何從文件或者網絡另一端讀取到本機的內存中的。此時,就會涉及到內核空間以及用戶空間的知識。這時如果你不理解內核是什么,那么自然也就無法理解 Unix 網絡 IO 模型這個知識點了。
好了,今天的文章就到這里。如果你喜歡的話,麻煩轉發讓更多的朋友看到。一個人學習可以走得很快,但一群人可以走得更遠。