天天看點

Windows核心的基本概念

 Windows核心的基本概念

1  處理器模式

Windows使用 0 和3 兩種特權級。0 表示CPU處于核心模式(kernel mode);3 表示使用者模式(user mode)。

1.1  記憶體管理

Windows 将32位虛拟記憶體空間按照0~4 GB的線性位址空間看待。其中2~4GB是所有程序共享的,為系統位址空間。0~2GB 為程序位址空間。

在系統位址空間中,典型的三種記憶體頁面管理算法:

  1. 非換頁記憶體池。這部分記憶體區域在初始化時已經被映射到實體頁面,是以Windows利用空閑連結清單的做法,按照不同的粒度(1、2、3、>=4 個頁面的大小),将空閑頁面連結起來,空閑頁面本身即連結清單的結點,申請和釋放頁面的操作實際上是針對空閑連結清單來進行的。
  1. 換業記憶體池。在換頁記憶體池區域,空閑的頁面并沒有被映射好實體頁面,Windows使用位圖來管理頁面的配置設定。配置設定連續的多個頁面,即從位圖中找到連續的零位。
  2. 系統PTE區域。把PTE當作資源來管理。當核心需要一段虛拟位址來映射實體頁面時,它可以使用系統PTE區域中的位址。

1.2  程序和線程管理

程序定義了一個執行環境,包括私有的位址空間、一個句柄表、以及一個安全環境。

線程則是一個控制流,有自己的調用棧,記錄了它的執行曆史。

Windows 中的程序和線程的關系:

Windows核心的基本概念

1.3  中斷和異常

中斷(interrupt) 是處理器與外部裝置打交道的重要途經; 異常(exception) 是處理器的正常指令流在執行過程中産生的一下特殊事件,需要緊急處理才能繼續原來的指令流。

Intel x86 利用IDT(Interrupt Descriptor Table,中斷描述符表),将中斷或異常與一個處理服務例程關聯,一旦發生中斷或異常,該服務例程即被執行。

Windows 允許裝置驅動程式為特定的中斷向量添加它的中斷服務例程(ISR ,Interrupt Service Routine)。

Windows 規定了一套軟體中斷優先級,稱為中斷請求級别(IROL,Interrupt Request Level),Windows 使用0~31來表示IRQL,數值越大,優先級越高。

IRQL=0 表示普通線程,稱為PASSIVE_LEVEL或被動級别;

IRQL=1 表示異步過程調用(APC ,Asynchronous Procedure Call),稱為APC_LEVEL;

IRQL=2 表示延遲過程調用(DPC,Deferred Procedure Call),稱為DISPATCH/DPC或者DISPATCH_LEVEL。

3~26是裝置IRQL,27~31是一些特殊的硬體中斷。

核心模式異常處理:異常分發器首先将異常交給核心調試器來處理,若不存在核心調試器或者核心調試器沒有處理該異常,則嘗試分發到一個基于幀的異常處理器(frame-based exception handler)。

使用者模式異常處理:異常分發器首先判斷程序的調試端口是否有效,若有效,則發送消息至調試端口,然後等待應答,否則将異常交給核心調試器。如果異常仍未得到處理,則将控制轉到使用者模式下,由使用者模式的異常分發器(ntdll.dll 中的KeUserExceptionDispatcher 函數)尋找一個基于幀的異常處理器。如果在使用者模式下該異常仍為得到處理,則控制再次回到核心模式下。這次,核心模式的異常處理器首先嘗試調試端口,若異常仍未被處理,則再嘗試目前程序的異常端口。連接配接程序異常端口的是Windows子系統,是以,Windows子系統在異常處理的最後時刻由機會處理它所屬程序的異常。如果它也不能處理,則該程序被終止。

1.4  同步

同步是為了解決并發通路。windows作業系統提供多種多種同步機制,根據執行環境中的IRQL值大于APC_LEVEL或者等于PASSIVE_LEVEL,可以将同步分為“不依賴線程排程的同步機制”和“基于線程排程的同步機制”兩類。

當IRQL大于APC_LEVEL時,Windows提供了一些友善的同步保護機制,供核心自身或裝置驅動程式使用。IRQL大于APC_LEVEL時典型的同步機制如下:

  1. 提升IRQL。根據IRQL的定義,當處理器在某個IRQL上運作時,他隻能被更高IRQL的中斷打斷,意味着,不用擔心低IRQL的過程會搶占掉目前執行過程。這種做法在單處理器系統上可以做的更好,但是多處理器系統上,提升IRQL還不夠,往往還需要其他同步機制(如自旋鎖)。
  2. 互鎖操作。利用Intel X86處理器提供的lock指令字首,可以實作基于整數操作的保護,確定一個操作以原子方式進行。這種操作隻能在小粒度資料上(可以達到64位記憶體單元)進行同步保護,而且是指令級保護。
  3. 無鎖的單連結清單。windows利用64位互鎖指令來實作無鎖的單連結清單資料結構,支援多核,多處理器環境。
  4. 自旋鎖(spin lock)。自旋鎖本身是一種忙等。為了獲得自旋鎖,處理器持續監測鎖狀态。直至可用。此時即使有線程排程執行,APC排隊,也沒機會執行。是以自旋鎖通常用于IRQL大于等于DISPATCH_LEVEL的代碼。windows還提供一些自旋鎖的擴充:執行體自旋鎖(支援共享和獨占的語義),排隊自旋鎖(queued spin lock)和棧内排隊自旋鎖(in-stack queued spin lock)。

IRQL值等于PASSIVE_LEVEL線程之間的同步。

windows定義了統一的機制支援各種線程同步原語:分發器對象(dispatcher object),其資料結構頭部為DISPATCH_HEADER。

windows Server 2003 實作了以下分發器對象:

  1. 事件(event):分為事件通知對象和事件同步對象,差別在于,當事件對象變成有信号狀态時,是解除所有正在等待該對象的線程,還是隻喚醒第一個以WaitAny方式等待該對象的線程。
  2. 突變體(mutant):突變體是Windows核心中互斥體的實作,如果突變體對象為無信号狀态,則一定被某個線程“占有”,否則可滿足任何一個線程的等待要求。突變體記錄了“所有者”線程資訊,通常可用于實作“鎖”。
  3. 信号量(semaphore):信号量有一個計數器,用于控制最多可以有多少個線程共享一個資源。當計數器達到預定最大值時,信号量将變成無信号狀态。
  4. 隊列對象(queue):這是Windows核心中用于支援線程池的機制,其資料結構為KQUEUE,通常可以用于控制一項任務的并發程度。它的典型用途是I/O完成端口。
  5. 程序對象:Windows的核心程序對象本身也是一個分發器對象,當程序對象被初始建立時,為無信号狀态,程序結束為有信号狀态。
  6. 線程對象:同理如上。
  7. 定時器對象:定時器對象既是一個像DPC一樣的例程,也是個可等待的分發器對象,當設定的時間到期時,定時器變成有信号狀态。
  8. 門對象(gate object):在windows中,門對象和門等待時線程排程器的特殊支援,它繞過了以上分發器對象同步過程中的很多步驟。喚醒一個門等待的線程幾乎是以最快捷的方式進行,線程排程器會直接将線程插入到某個處理器的就緒隊列中。

除此之外,還有更豐富的同步機制:包括,快速互斥體(fast mutex),守護互斥體(guarded mutex),執行體資源(executive resource)和推鎖(push lock)。