作業系統使用者態和核心態之間的切換過程

2021-05-12 07:29:16 字數 3724 閱讀 7243

作業系統使用者態和核心態之間的切換過程

1. 使用者態和核心態的概念區別

究竟什麼是使用者態,什麼是核心態,這兩個基本概念以前一直理解得不是很清楚,根本原因個人覺得是在於因為大部分時候我們在寫程式時關注的重點和著眼的角度放在了實現的功能和**的邏輯性上,先看乙個例子:

1)例子

void testfork()

printf(「testfork ok/n」);

}這段**很簡單,從功能的角度來看,就是實際執行了乙個

fork()

,生成乙個新的程序,從邏輯的角度看,就是判斷了如果

fork()

返回的是

0則列印相關語句,然後函式最後再列印一句表示執行完整個

testfork()

函式。**的執行邏輯和功能上看就是如此簡單,一共四行**,從上到下一句一句執行而已,完全看不出來**有體現出使用者態和程序態的概念。

如果說前面兩種是靜態觀察的角度看的話,我們還可以從動態的角度來看這段**,即它被轉換成

cpu執行的指令後載入執行的過程,這時這段程式就是乙個動態執行的指令序列。而究竟載入了哪些**,如何載入就是和作業系統密切相關了。

2)特權級

熟悉unix/linux

系統的人都知道,

fork

的工作實際上是以系統呼叫的方式完成相應功能的,具體的工作是由

sys_fork

負責實施。其實無論是不是

unix

或者linux

,對於任何作業系統來說,建立乙個新的程序都是屬於核心功能,因為它要做很多底層細緻地工作,消耗系統的物理資源,比如分配物理記憶體,從父程序拷貝相關資訊,拷貝設定頁目錄頁表等等,這些顯然不能隨便讓哪個程式就能去做,於是就自然引出特權級別的概念,顯然,最關鍵性的權力必須由高特權級的程式來執行,這樣才可以做到集中管理,減少有限資源的訪問和使用衝突。

特權級顯然是非常有效的管理和控制程式執行的手段,因此在硬體上對特權級做了很多支援,就

intel x86

架構的cpu

來說一共有

0~3四個特權級,

0級最高,

3級最低,硬體上在執行每條指令時都會對指令所具有的特權級做相應的檢查,相關的概念有

cpl、

dpl和

rpl,這裡不再過多闡述。硬體已經提供了一套特權級使用的相關機制,軟體自然就是好好利用的問題,這屬於作業系統要做的事情,對於

unix/linux

來說,只使用了

0級特權級和

3級特權級。也就是說在

unix/linux

系統中,一條工作在

0級特權級的指令具有了

cpu能提供的最高權力,而一條工作在

3級特權級的指令具有

cpu提供的最低或者說最基本權力。

3)使用者態和核心態

現在我們從特權級的排程來理解使用者態和核心態就比較好理解了,當程式執行在

3級特權級上時,就可以稱之為執行在使用者態,因為這是最低特權級,是普通的使用者程序執行的特權級,大部分使用者直接面對的程式都是執行在使用者態;反之,當程式執行在

0級特權級上時,就可以稱之為執行在核心態。

雖然使用者態下和核心態下工作的程式有很多差別,但最重要的差別就在於特權級的不同,即權力的不同。執行在使用者態下的程式不能直接訪問作業系統核心資料結構和程式,比如上面例子中的

testfork()

就不能直接呼叫

sys_fork()

,因為前者是工作在使用者態,屬於使用者態程式,而

sys_fork()

是工作在核心態,屬於核心態程式。

當我們在系統中執行乙個程式時,大部分時間是執行在使用者態下的,在其需要作業系統幫助完成某些它沒有權力和能力完成的工作時就會切換到核心態,比如

testfork()

最初執行在使用者態程序下,當它呼叫

fork()

最終觸發

sys_fork()

的執行時,就切換到了核心態。

2.   

使用者態和核心態的轉換

1)使用者態切換到核心態的

3種方式

a. 系統呼叫

這是使用者態程序主動要求切換到核心態的一種方式,使用者態程序通過系統呼叫申請使用作業系統提供的服務程式完成工作,比如前例中

fork()

實際上就是執行了乙個建立新程序的系統呼叫。而系統呼叫的機制其核心還是使用了作業系統為使用者特別開放的乙個中斷來實現,例如

linux

的int 80h

中斷。b. 異常當

cpu在執行執行在使用者態下的程式時,發生了某些事先不可知的異常,這時會觸發由當前執行程序切換到處理此異常的核心相關程式中,也就轉到了核心態,比如缺頁異常。

c. 外圍裝置的中斷

當外圍裝置完成使用者請求的操作後,會向

cpu發出相應的中斷訊號,這時

cpu會暫停執行下一條即將要執行的指令轉而去執行與中斷訊號對應的處理程式,如果先前執行的指令是使用者態下的程式,那麼這個轉換的過程自然也就發生了由使用者態到核心態的切換。比如硬碟讀寫操作完成,系統會切換到硬碟讀寫的中斷處理程式中執行後續操作等。這3

種方式是系統在執行時由使用者態轉到核心態的最主要方式,其中系統呼叫可以認為是使用者程序主動發起的,異常和外圍裝置中斷則是被動的。

2)具體的切換操作

從觸發方式上看,可以認為存在前述

3種不同的型別,但是從最終實際完成由使用者態到核心態的切換操作上來說,涉及的關鍵步驟是完全一致的,沒有任何區別,都相當於執行了乙個中斷響應的過程,因為系統呼叫實際上最終是中斷機制實現的,而異常和中斷的處理機制基本上也是一致的,關於它們的具體區別這裡不再贅述。關於中斷處理機制的細節和步驟這裡也不做過多分析,涉及到由使用者態切換到核心態的步驟主要包括:

[1]

從當前程序的描述符中提取其核心棧的

ss0及

esp0

資訊。[2]

使用ss0

和esp0

指向的核心棧將當前程序的

cs,eip,eflags,ss,esp

資訊儲存起來,這個

過程也完成了由使用者棧到核心棧的切換過程,同時儲存了被暫停執行的程式的下一

條指令。

[3]

將先前由中斷向量檢索得到的中斷處理程式的

cs,eip

資訊裝入相應的暫存器,開始

執行中斷處理程式,這時就轉到了核心態的程式執行了。

舉個例子:

下面的圖中執行了連續的兩條指令:

mov eax, 0x4

int 0x80

可以看到,指令

mov eax, 0x4

對應的cs

為0x7

,eip

為0x308a,ss

為0xf

,esp

為0x80320

這表明此條指令的特權級是

3級,也就是說該指令是工作在使用者態下的。

int 0x80

即所謂的系統呼叫執行的軟中斷,此條指令執行完之後,

cs變換成了

0x8,eip

為0x1400,ss

變成了0x10, esp

變成了0x1ffffec

。這時系統已經轉入了核心態執行,而且棧也變為了核心棧。

核心態程式執行完畢時如果要從核心態返回使用者態,可以通過執行指令

iret

來完成,指令

iret

會將先前壓棧的進入核心態前的

cs,eip,eflags,ss,esp

資訊從棧裡彈出,載入到各個對應的暫存器中,重新開始執行使用者態的程式,這個過程不再詳述。

作業系統使用者態和核心態

核心態 cpu可以訪問記憶體所有資料,包括外圍裝置,例如硬碟,網絡卡.cpu也可以將自己從乙個程式切換到另乙個程式 使用者態 只能受限的訪問記憶體,且不允許訪問外圍裝置.占用cpu的能力被剝奪,cpu資源可以被其他程式獲取 為什麼要有使用者態和核心態 由於需要限制不同的程式之間的訪問能力,防止他們獲...

作業系統 使用者態和核心態

3g 4g大部分是共享的,是核心態的位址空間。這裡存放整個核心的 和所有的核心模組以及核心所維護的資料。2 特權級的概念 對於任何作業系統來說,建立乙個程序是核心功能。建立程序要做很多任務作,會消耗很多物理資源。比如分配物理記憶體,父子程序拷貝資訊,拷貝設定頁目錄頁表等等,這些工作得由特定的程序去做...

作業系統 核心態和使用者態

核心態和使用者態 核心態和使用者態 核心態 當乙個任務 程序 執行系統呼叫而陷入核心 中執行時,我們就稱程序處於核心執行態 或簡稱為核心態 其他的屬於使用者態。使用者程式執行在使用者態,作業系統執行在核心態.作業系統核心執行在核心態,而伺服器執行在使用者態 使用者態不能干擾核心態.所以cpu指令就有...