操作系統篇-調用門與特權級(CPL、DPL和RPL)


 

|| 版權聲明:本文為博主原創文章,未經博主允許不得轉載。

  一、前言

  在前兩篇文章(《操作系統篇-淺談實模式與保護模式》《操作系統篇-分段機制與GDT|LDT》)中,我們提到過特權級與調用門,特別是在說到保護模式時,我們提到了內存的保護,“保護”這兩個字的含義何在呢?不同權級之間是如何相互訪問,如何通訊,如何保護,這些東西都跟調用門和不同代碼段的特權級緊密相關。本文主要探討的就是,保護模式下的調用門與特權級,在閱讀本文之前,建議大家先看看blog的之前幾篇文章(當然,在本文中也會提到之前講過的一些知識),熟悉一些基本結構與原理,對本文的理解將會大大加深。

  二、特權級

  a.概念

  關於特權級,我們在《操作系統篇-分段機制與GDT|LDT》的描述符結構中有提到過。在分段機制中,特權級總共有4個特權級別,從高到低分別是0、1、2、3,數字越小表示的特權級別越大。如下圖所示:

 

  較為核心的代碼和數據將被放在特權級較高的層級中。處理器將用這樣的機制來避免低特權級的任務在不被允許的情況下訪問位於高特權級的段中。如果處理器檢測到一個訪問請求是不合法的,將會產生常規保護錯誤。有時候也將高特權級稱為內層,低特權級稱為外層。

  b.CPL、DPL和RPL

  (1)CPL

  CPL是當前執行的程序或任務的特權級。它被存儲在CS和SS的第0位和第1位上。通常情況下,CPL代表代碼所在的段的特權級。當程序轉移到不同特權級的代碼段時,處理器將改變CPL。只有0和3兩個值,分別表示用戶態和內核態

   (2)DPL

  DPL表示段或門的特權級。它被存儲在段描述符或者門描述符的DPL字段中(《操作系統篇-分段機制與GDT|LDT》中有提到),當當前代碼段試圖訪問一個段或者門(這里大家先把門看成跟段一樣,下面我們會介紹),DPL將會和CPL以及段或者門選擇子的RPL相比較,根據段或者門類型的不同,DPL將會區別對待。

   RPL是通過段選擇子的第0和第1位表現出來的。RPL是代碼中根據不同段跳轉而確定,以動態刷新CS里的CPL,在代碼段選擇符中。而且RPL對每個段來說不是固定的,兩次訪問同一段時的RPL可以不同。操作系統往往用RPL來避免低特權級應用程序訪問高特權級段內的數據,即便提出訪問請求的段有足夠的特權級,如果RPL不夠也是不行的,當RPL的值比CPL大的時候,RPL將起決定性作用。也就是說,RPL相當於附加的一個權限控制,只有當RPL>DPL的時候,才起到實際的限制作用。

   三、調用門

   a.結構

  調用門用於在不同特權級之間實現受控的程序控制轉移,通常僅用於使用特權級保護機制的操作系統中。本質上,它只是一個描述符,一個不同於代碼段和數據段的描述符,可以安裝在GDT或者LGT中,但是不能安裝在IDT(中斷描述符表)中。它主要是定義了目標代碼對應段的選擇子、入口地址的偏移和一些屬性等。結構跟代碼段以及數據段描述符大不相同。結構如下圖所示:

一個門描述了由一個選擇子和一個偏移所指定的線性地址,程序正是通過這個地址進行轉移的。

   b.通過調用門訪問代碼段

  調用門的訪問一般通過call、jmp指令的操作數提供的一個遠指針,該指針中的段選擇子用於指定調用門,CPU會使用調用門中的偏移值實現跳轉。如下圖:

 

  通過調用門進行程序的轉移控制時,CPU會檢查以下這幾個字段:1.當前代碼段的CPL;2.調用門描述符中的DPL;3.調用門描述符中的RPL;4.目的代碼描述符的DPL;5.目標代碼段描述符中的一致性標志C(一致與非一致下面會提到)。如下圖:

  對於call和jmp指令,有着不同的優先級檢查規則的:

  對call來說:當前CPL<=調用門描述符DPL,RPL<=調用門描述符DPL,當前CPL>=目的代碼段描述符DPL;

  對jmp來說:除了跟call的“當前CPL<=調用門描述符DPL,RPL<=調用門描述符DPL”一樣外,如果目的代碼段的一致的話,CPL>=目的代碼段的DPL,而如果目的代碼段是非一致的話,CPL=目的代碼段的DPL。

   另外,只有call指令可以將代碼通過調用門轉移到特權級更高的非一致性代碼之中。對於非一致性代碼的成功轉移,CPL被目的代碼的DPL刷新,會引起堆棧切換;對於一致性代碼,不會刷新,也不會切換。

  調用門的作用是,讓一個代碼段中的過程被不同特權級的程序訪問。通常用於低特權級代碼來訪問高特權級的代碼段。

   c.一致代碼段與非一致代碼段

  什么是一致代碼段:簡單理解,就是操作系統拿出來被共享的代碼段,可以被低特權級的用戶直接調用訪問的代碼。向特權級更高的一致性代碼段的控制轉移,允許程序以當前特權級繼續執行。通常這些共享代碼,是"不訪問"受保護的資源和某些類型異常處理。對於一致性代碼來說,特權級高的程序不允許訪問特權級低的數據:即是說核心態不允許調用用戶態的數據;特權級低的程序可以訪問到特權級高的數據.但是特權級不會改變:用戶態還是用戶態

  代碼段可以是一致性的或者非一致性的。那什么是非一致性代碼段呢?可以理解為,為了避免低特權級的訪問而被操作系統保護起來的系統代碼。向不同特權級的非一致代碼段轉移將導致一般保護異常,除非使用了任務門或者調用門。產生一致性代碼和非一致性代碼的主要原因是:單純的0-3特權級只能保證高特權級可以訪問特權級的東西,而低特權級的段有時候要訪問內核數據段,此時就需要一些靈活策略。對於非一致代碼段來說,只允許同級間訪問,絕對禁止不同級訪問:核心態不用用戶態,而用戶態也不使用核心態。

  通常低特權代碼必須通過"門"來實現對高特權代碼的訪問和調用。不訪問保護措施的系統工具和某些異常類型的處理過程需要放在一致性代碼段中。需要防止低特權級程序訪問的工具要放在非一致代碼段中。
  每當調用門用於把程序控制轉移到一個更高級別的非一致性代碼段時,CPU會自動切換到目的代碼段特權級的堆棧去。每個任務只能定義最多4個棧分別對應4個特權級每個棧都位於不同的段中,並且使用段選擇符和段中偏移值指定。堆棧的切換我們在后期的文章會配合例子來講解。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM