Linux為什么區(qū)分內(nèi)核空間和用戶空間 ???
程序如果要被CPU執(zhí)行,就得編譯成CPU可以執(zhí)行的指令,一大堆的程序就變成了一堆的指令。一個操作系統(tǒng)它也是一堆程序組成的,可以想象CPU的指令是很多的,但是這么多的指令中,有些指令涉及到系統(tǒng)底層的東西,如果有些指令錯用或者使用不當(dāng)是非常危險的,比如清內(nèi)存、設(shè)置時鐘、修改用戶訪問權(quán)限、分配系統(tǒng)資源等等,可能導(dǎo)致系統(tǒng)崩潰。CPU將這些指令進行了分類,分為特權(quán)指令和非特權(quán)指令,不讓所有程序都能使用所有指令,如果所有程序都能使用,那系統(tǒng)崩潰就會變得非常常見了。
操作系統(tǒng)的核心是內(nèi)核,它是獨立于普通的應(yīng)用程序,負責(zé)管理系統(tǒng)的進程、內(nèi)存、設(shè)備驅(qū)動程序、文件和網(wǎng)絡(luò)系統(tǒng),決定著系統(tǒng)的性能和穩(wěn)定性,所以一定要保證內(nèi)核的安全。
為了保護內(nèi)核的安全,操作系統(tǒng)一般都限制用戶進程不能直接操作內(nèi)核,在32位操作系統(tǒng)總的地址空間4G(2^32 = 4GB),實現(xiàn)這個限制的方式就是操作系統(tǒng)將總的地址空間分為兩個部分,對于Linux操作系統(tǒng):
1. 高位的1G空間(0xC000 0000 - 0xFFFF FFFF)分配給內(nèi)核,稱為內(nèi)核空間,內(nèi)核程序運行在內(nèi)核空間,對應(yīng)的進程就處于內(nèi)核態(tài)(管態(tài))。
2. 另外3G空間(0x0000 0000 - 0xBFFF FFFF)分配給用戶使用,稱為用戶空間,用戶程序運行在用戶空間,對應(yīng)的進程處于用戶態(tài)(目態(tài))。
引用之前寫的一篇文章(你該知道你寫的程序的內(nèi)存布局)的圖
總之,有1G的內(nèi)核空間是每個進程共享的,剩下的3G是進程自己使用的。
在內(nèi)核態(tài)下,CPU可以執(zhí)行指令系統(tǒng)的全集,也就是說內(nèi)核態(tài)進程可以調(diào)用系統(tǒng)的一切資源,但是特權(quán)指令只能在內(nèi)核態(tài)下執(zhí)行,它不直接提供給用戶使用,用戶態(tài)下只能使用非特權(quán)指令,也就是說用戶態(tài)進程只能執(zhí)行簡單運算,不能直接調(diào)用系統(tǒng)資源。
那么CPU如何知道當(dāng)前是否可以使用特權(quán)指令?
有一個標(biāo)志寄存器,又稱程序狀態(tài)字寄存器PSW(Program Status Word),有一個標(biāo)志位來標(biāo)識處理器當(dāng)前處于哪一個狀態(tài),比如0是處于用戶態(tài),1是處于內(nèi)核態(tài),有了這個狀態(tài)就能判斷該使用什么指令。
Linux操作系統(tǒng)通過區(qū)分內(nèi)核空間和用戶空間的這種設(shè)計,將操作系統(tǒng)代碼和用戶程序代碼分開,這樣即使在某一個應(yīng)用程序出錯,也不會影響到操作系統(tǒng),再說,Linux操作系統(tǒng)是多任務(wù)系統(tǒng),其它應(yīng)用程序不也還能運行。
現(xiàn)代操作系統(tǒng)基本上都是分內(nèi)核空間和用戶空間的做法,來保護操作系統(tǒng)自身的安全性和穩(wěn)定性,這也是區(qū)分內(nèi)核空間和用戶空間的本質(zhì)。