2012-01-16 25 views
5

我只是讀了在Linux在我的OS-書是如何工作的,當我遇到這個來..沒有上下文切換的系統調用?

[...]內核作爲一個單一的,monolitic二進制創建。主要原因是提高性能。因爲所有的內核代碼和數據結構都保存在一個地址空間中,所以當進程調用操作系統函數或傳遞硬件中斷時,不需要上下文切換。

這對我來說聽起來相當驚人,它必須存儲進程的上下文才能進入內核模式來處理中斷。但是,好吧,我現在就買它。在描述進程的調度上下文的幾頁中,它說:

進程執行時發生的系統調用和中斷將使用此堆棧。

「這個堆棧」是內核存儲進程寄存器等的地方。

這不是第一次報價的直接矛盾嗎?我以某種方式錯誤地解釋它?

回答

3

我認爲第一個引用是指單片內核和microkernel之間的差異。

Linux是單片的,它的所有內核組件(設備驅動程序,調度程序,VM管理器)運行在ring 0。因此,在執行系統調用和處理中斷時不需要上下文切換。

對比度微內核,其中類似的設備驅動程序和IPC提供商組件user space運行,環0。因此之外,這種結構需要額外的上下文中執行的系統調用時(因爲該執行模塊可以駐留在用戶空間中)開關和處理中斷(將中斷轉發給設備驅動程序)。

+0

謝謝。自從我研究這個問題已經很長時間了,但我的印象是,硬件中斷實際上是_interrupts_執行,並立即跳轉到處理程序,而不是稍後輪詢中斷。我認爲如果進程在內核模式下執行,它仍然需要在跳轉之前存儲它的上下文,但也許這是我的錯誤?如果被調用的方法正確處理使用的寄存器,我想現在這與其他方法調用沒有什麼不同。我是否正確地使用了? – user1130005 2012-01-16 10:57:23

+0

我的理解是進程在用戶模式下運行,並且在處理中斷之前的確有一個上下文切換到內核模式。但是,*處理*中斷不需要在單片內核中進行額外的上下文切換,而是在微內核中進行(因爲設備驅動程序駐留在用戶空間中)。 – 2012-01-16 11:07:37

2

「上下文切換」可能意味着一些事情中的一種,它們都是相關的:(1)從用戶切換到內核模式以處理系統調用,或者自主切換到內核模式以處理針對中斷堆棧的中斷,或者(2)切換到在用戶空間中運行另一個用戶進程,跳轉到兩者之間的內核空間。

從用戶空間到內核空間的任何移動都意味着要保存足夠的用戶空間以可靠地返回。如果內核空間代碼決定 - 當你不再運行該進程的用戶代碼時 - 是時候讓另一個用戶進程運行了,它會進入。

因此,至少說2-3個堆棧或地方來存儲一個「上下文」:硬件中斷需要一個內核級堆棧來說明返回的內容;用戶方法/子程序調用使用標準堆棧來完成此操作。等

最初的Unix內核 - 現在這個部分的模型沒有那麼不同 - 運行系統調用就像一個處理早餐訂單的短期訂單:把這個放在爐子上,爲訂單騰出空間剛剛到達的培根,開始培根,回到第一個訂單。全部在內核切換上下文中。不是一個巨大的監控應用程序,這可能會讓IBM和DEC軟件人士瘋狂。

0

在Linux中進行系統調用時,會從用戶空間切換到內核空間(ring3到ring0)。每個進程都有一個關聯的內核模式堆棧,由系統調用使用。在執行系統調用之前,進程的CPU寄存器存儲在其用戶模式堆棧中,該堆棧與內核模式堆棧不同,並且是進程用於用戶空間執行的堆棧。

當進程處於內核模式(或用戶模式)時,調用同一模式的函數將不需要上下文切換。這是第一個引用所指的內容。

第二個引用是指內核模式堆棧,而不是用戶模式堆棧。在說到這一點之後,我必須提到Linux優化,其中內核空間不需要轉換來執行系統調用,即所有與系統調用相關的處理都是在用戶空間本身完成的(因此no context switch)。 vsyscallVDSO是這樣的技術。背後的想法很簡單。它是向用戶空間發送執行相應系統調用所需的數據。更多信息可在this LWN article找到。

除此之外,還有一些研究項目中的所有執行都發生在同一個環中。用戶空間程序和操作系統代碼都位於same ring中。想法是擺脫環形開關的開銷。 Microsoft's [singularity][2] OS就是這樣一個項目。