天天看點

作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...

作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...
作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...

作者:sparkdev

來源:http://www.cnblogs.com/sparkdev/

本文以 32 位系統為例介紹核心空間(kernel space)和使用者空間(user space)。

核心空間和使用者空間

對 32 位作業系統而言,它的尋址空間(虛拟位址空間,或叫線性位址空間)為 4G(2的32次方)。也就是說一個程序的最大位址空間為 4G。

作業系統的核心是核心(kernel),它獨立于普通的應用程式,可以通路受保護的記憶體空間,也有通路底層硬體裝置的所有權限。為了保證核心的安全,現在的作業系統一般都強制使用者程序不能直接操作核心。

具體的實作方式基本都是由作業系統将虛拟位址空間劃分為兩部分,一部分為核心空間,另一部分為使用者空間。針對 Linux 作業系統而言,最高的 1G 位元組(從虛拟位址 0xC0000000 到 0xFFFFFFFF)由核心使用,稱為核心空間。而較低的 3G 位元組(從虛拟位址 0x00000000 到 0xBFFFFFFF)由各個程序使用,稱為使用者空間。

對上面這段内容我們可以這樣了解:「每個程序的 4G 位址空間中,最高 1G 都是一樣的,即核心空間。隻有剩餘的 3G 才歸程序自己使用。」

「換句話說就是, 最高 1G 的核心空間是被所有程序共享的!」下圖描述了每個程序 4G 位址空間的配置設定情況(此圖來自網際網路):

作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...

為什麼需要區分核心空間與使用者空間

在 CPU 的所有指令中,有些指令是非常危險的,如果錯用,将導緻系統崩潰,比如清記憶體、設定時鐘等。如果允許所有的程式都可以使用這些指令,那麼系統崩潰的機率将大大增加。

是以,CPU 将指令分為特權指令和非特權指令,對于那些危險的指令,隻允許作業系統及其相關子產品使用,普通應用程式隻能使用那些不會造成災難的指令。

比如 Intel 的 CPU 将特權等級分為 4 個級别:Ring0~Ring3。其實 Linux 系統隻使用了 Ring0 和 Ring3 兩個運作級别(Windows 系統也是一樣的)。

當程序運作在 Ring3 級别時被稱為運作在使用者态,而運作在 Ring0 級别時被稱為運作在核心态。

核心态與使用者态

好了我們現在需要再解釋一下什麼是核心态、使用者态:「當程序運作在核心空間時就處于核心态,而程序運作在使用者空間時則處于使用者态。」

在核心态下,程序運作在核心位址空間中,此時 CPU 可以執行任何指令。運作的代碼也不受任何的限制,可以自由地通路任何有效位址,也可以直接進行端口的通路。

在使用者态下,程序運作在使用者位址空間中,被執行的代碼要受到 CPU 的諸多檢查,它們隻能通路映射其位址空間的頁表項中規定的在使用者态下可通路頁面的虛拟位址,且隻能對任務狀态段(TSS)中 I/O 許可位圖(I/O Permission Bitmap)中規定的可通路端口進行直接通路。

對于以前的 DOS 作業系統來說,是沒有核心空間、使用者空間以及核心态、使用者态這些概念的。可以認為所有的代碼都是運作在核心态的,因而使用者編寫的應用程式代碼可以很容易的讓作業系統崩潰掉。

對于 Linux 來說,通過區分核心空間和使用者空間的設計,隔離了作業系統代碼(作業系統的代碼要比應用程式的代碼健壯很多)與應用程式代碼。

即便是單個應用程式出現錯誤也不會影響到作業系統的穩定性,這樣其它的程式還可以正常的運作(Linux 可是個多任務系統啊!)。

「是以,區分核心空間和使用者空間本質上是要提高作業系統的穩定性及可用性。」

如何從使用者空間進入核心空間

其實所有的系統資源管理都是在核心空間中完成的。比如讀寫磁盤檔案,配置設定回收記憶體,從網絡接口讀寫資料等等。

我們的應用程式是無法直接進行這樣的操作的。但是我們可以通過核心提供的接口來完成這樣的任務。

比如應用程式要讀取磁盤上的一個檔案,它可以向核心發起一個 "系統調用" 告訴核心:"我要讀取磁盤上的某某檔案"。

其實就是通過一個特殊的指令讓程序從使用者态進入到核心态(到了核心空間),在核心空間中,CPU 可以執行任何的指令,當然也包括從磁盤上讀取資料。具體過程是先把資料讀取到核心空間中,然後再把資料拷貝到使用者空間并從核心态切換到使用者态。

此時應用程式已經從系統調用中傳回并且拿到了想要的資料,可以開開心心的往下執行了。簡單說就是應用程式把高科技的事情(從磁盤讀取檔案)外包給了系統核心,系統核心做這些事情既專業又高效。

對于一個程序來講,從使用者空間進入核心空間并最終傳回到使用者空間,這個過程是十分複雜的。舉個例子,比如我們經常接觸的概念 "堆棧",其實程序在核心态和使用者态各有一個堆棧。

運作在使用者空間時程序使用的是使用者空間中的堆棧,而運作在核心空間時,程序使用的是核心空間中的堆棧。是以說,Linux 中每個程序有兩個棧,分别用于使用者态和核心态。

下圖簡明的描述了使用者态與核心态之間的轉換:

作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...

既然使用者态的程序必須切換成核心态才能使用系統的資源,那麼我們接下來就看看程序一共有多少種方式可以從使用者态進入到核心态。

概括的說,有三種方式:

系統調用、軟中斷和硬體中斷

。這三種方式每一種都涉及到大量的作業系統知識,是以這裡不做展開。

整體結構

接下來我們從核心空間和使用者空間的角度看一看整個 Linux 系統的結構。它大體可以分為三個部分,從下往上依次為:硬體 -> 核心空間 -> 使用者空間。如下圖所示(此圖來自網際網路):

作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...

在硬體之上,核心空間中的代碼控制了硬體資源的使用權,使用者空間中的代碼隻有通過核心暴露的系統調用接口(System Call Interface)才能使用到系統中的硬體資源。其實,不光是 Linux,Windows 作業系統的設計也是大同小異。

實際上我們可以将每個處理器在任何指定時間點上的活動概括為下列三者之一:

  • 運作于使用者空間,執行使用者程序。
  • 運作于核心空間,處于程序上下文,代表某個特定的程序執行。
  • 運作于核心空間,處于中斷上下文,與任何程序無關,處理某個特定的中斷。

以上三點幾乎包括所有的情況,比如當 CPU 空閑時,核心就運作一個空程序,處于程序上下文,但運作在核心空間。

說明:Linux 系統的中斷服務程式不在程序的上下文中執行,它們在一個與所有程序都無關的、專門的中斷上下文中執行。

之是以存在一個專門的執行環境,就是為了保證中斷服務程式能夠在第一時間響應和進行中斷請求,然後快速地退出。

總結

現代的作業系統大都通過核心空間和使用者空間的設計來保護作業系統自身的安全性和穩定性。是以在我們閱讀有關作業系統的資料時經常遇到核心空間、使用者空間和核心态、使用者态等概念,希望本文能夠幫助您了解這些基本的概念。

參考:

1、https://www.cnblogs.com/Anker/p/3269106.html

2、https://blog.csdn.net/linux12121/article/details/52628941

作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...

轉載申明:轉載本号文章請注明作者和來源;尊重知識和創作者,本号文章若遇到版權等問題,請留言聯系我們處理。

推薦閱讀

更多架構相關技術知識總結請參考“架構師技術全聯盟書店”相關電子書(32本技術資料打包彙總詳情可通過“閱讀原文”擷取)。

内容持續更新,現在下單“架構師技術全店打包彙總(全)”,後續可享全店内容更新“免費”贈閱,疫情活動期間價格僅168元(原總價240元)。

溫馨提示:

掃描二維碼關注公衆号,點選連結擷取“架構師技術全店資料打包彙總(全)”電子書資料詳情。

作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...
作業系統讀寫者問題實驗報告_Linux作業系統,為什麼需要核心空間和使用者空間?...

繼續閱讀