一步步编写操作系统 55 CPL和DPL入门2
接上節。
圖中第132行的jmp指令,段選擇子為SELECTOR_CODE,其RPL的值為RPL0,RPL0定義在include/boot.inc中,其值為0。選擇子的索引部分值為1,表示對應GDT中第1個段描述符,該描述符的DPL為0,(它是用include/boot.inc中的DESC_DPL_0定義的,圖中未展示)。
在跳轉之前,CS為0,其低2位RPL部分為0,也就是CPL為0,當執行跳轉指令jmp dword SELECTOR_CODE:p_mode_start時,目標代碼段(即第1個段描述符)的DPL為0,與當前特權級一致(處理器會根據CPL、RPL、DPL做特權級檢查,此檢查過程咱們在介紹完RPL時再討論),處理器允許轉移,所以新的特權級依然是0,該值保存在段寄存器CS的低2位,這就是特級級轉移的粗略過程,也是進入保護模式后特權為0的來龍去脈。
說完了CPL,咱們再看看,受訪者的特權標簽在哪里。
在段描述符中有一個屬性還為該內存標明了特權等級,這就是段描述符中的DPL字段的作用,它就是受訪者的特權標簽。話說,不僅只有段描述符中有DPL字段,以后所介紹的所有描述符都有DPL。
DPL,即Descriptor Privilege Level,描述符特權級,這下您清楚為什么DPL字段在段描述符中占2位的原因了吧,兩位能表示4個組合,00b、01b、10b、11b,所有特權級都齊了。
計算機是人發明的,用人的思想來理解計算機原理是再合適不過的。拿校園生活舉例,班長權限比班主任低,班長有權限安排學生打掃衛生,班主任有權限查看學生成績。班長沒權限查看學生成績,但班主任有權限安排學生打掃衛生。這就是擁有高特權級的事物可以訪問同級或更低特權級資源,而低特權級的事物無法訪問高特權級資源的典型例子。
在計算機中也一樣,DPL是段描述符所代表的內存區域的“門檻”權限,訪問者能否邁過此門檻訪問到本描述符所代表的資源,其特權級至少要等于這個門檻,訪問者特權能否大于該門檻?這要看受訪資源是代碼還是數據啦。不難想像,只有具備“能動”行為的訪問者才具備訪問的能力,在計算機中真正的訪問者是硬件cpu,而指揮cpu行為(訪問誰及如何訪問)的是具有可執行能力的指令代碼,數據是不能訪問別人的,所以我們再強調一下訪問者就是代碼段中的指令,這對理解當前特權級非常重要。
訪問者任何時候都不允許訪問比自己特權更高的資源,無論受訪資源是數據還是代碼。在不涉及RPL的前提下,下面咱們要分情況討論啦。
對于受訪者為數據段(段描述符中type字段中未有X可執行屬性)來說:
只有訪問者的權限大于等于該DPL表示的最低權限才能夠繼續訪問,否則連這個門檻都邁不過去。比如,DPL為1的段描述符,只有特權級為0、1的訪問者才有資格訪問它所代表的資源,特權為2、3的訪問者會被cpu拒之門外。
對于受訪者為代碼段(段描述符中type字段中含有X可執行屬性)來說:
只有訪問者的權限等于該DPL表示的最低權限才能夠繼續訪問,即只能平級訪問。任何權限大于或小于它的訪問者都將被cpu拒之門外。這是為什么呢?自問自答之前先明確一個概念,對于受訪者為代碼段一這說法,實際上是指處理器從當前運行的代碼段上轉移到受訪者這個目標代碼段上去執行,并不是說把該目標代碼段當數據一樣訪問,在真實物理機器上,代碼段通常情況下不被當成數據來處理的,但確實可以這么做(話說虛擬機中會把代碼當成數據來處理)。
咱們先說為什么比它特權級更高的代碼也無法“訪問”它(即轉移到它上面運行)。
代碼指令代表cpu的行為,低特權級的代碼能做的事,高特權級代碼也能做,換句話說高特權的代碼不需要低特權代碼的幫助,正常情況下cpu沒有理由先自降等級后再去做某事。代碼段是cpu執行的指令,不是數據,這里所說的“受訪者為代碼段”其實就是指cpu從訪問者所在的段轉移到該代碼段上去執行。舉個例子,cpu若相當于汽車,代碼則相當于司機,它指揮cpu前進的方向。段的變換相當于換了司機,特權級較高的代碼段相當于技術水平較高的F1車手,特權級較低的代碼段相當于技術水平較低的普通司機,這輛車為了充分展示性能、活得更加精彩,它始終希望它的搭檔是駕駛技術高超的F1車手,要是把搭檔降級為普通司機,它可萬萬不能答應啊。
不過,凡事都有例外的時候,這是唯一一種處理器會從高特權降到低特權運行的情況:處理器從中斷處理程序中返回到用戶態的時候。
中斷處理都是在0特權級下進行的,因為中斷的發生多半是外部硬件發生了某種狀況或發生了某種不可抗力事件而必須要通cpu導致的,所以,在中斷的處理過程中需要具備訪問硬件的能力,在大多數情況下只有cpu處于0特權級才能訪問硬件,這是因為eflags寄存器中的IOPL位的值通常被設置為0(該位的作用就是限制訪問IO端口的最低特權級),并且TSS中不存在 IO位圖,有關這部分后面馬上會講到。再者,有些中斷處理中需要的指令只能在0特權級下使用,這部分指令稱為特權指令,所以中斷發生后其處理的過程必須在0特權級下進行。用戶進程是在3特權級,在運行用戶程序時若發生了中斷,cpu會暫停用戶程序的執行,隨后cpu就會自動由3特權級進入到0特權級,在0特權級下將執行用戶程序時的現場環境(也就是著名的概念:上下文)保存起來(這個保存上下文的動作可以由cpu通過TSS完成,這是cpu在硬件上提供的功能,但其效率并不高,所以大多數操作系統都是自己寫代碼手動保存上下文環境),待中斷處理完成后,cpu會恢復用戶程序的執行,也就是說會回到3特權級。以后在講了中斷和用戶進程時大伙兒會更清楚這一點。
現在大家知道了,除了從中斷處理過程返回外,任何時候cpu都不允許從高特權級轉移到低特權級。再結合之前咱們所說的大前提,訪問者任何時候都不允許訪問比自己特權更高的資源,代碼段也是資源,只不過可以讓cpu轉移過去執行而已,所以,比目標代碼段特權級低的訪問者也會被拒絕訪問目標代碼段。綜上所述,對于受訪問者為代碼段的情況,只能是平級訪問。也就是說,假如當前特權級為2,只能轉移到DPL為2特權級的代碼段上運行,轉移到0、1、3特權級都會被處理器拒絕。
不過本質上來說,代碼能否運行與代碼本身的特權等級并無關系,不同等級下的代碼段中的機器碼都是一樣的,特權級只是寫在描述符的DPL中,并沒有寫在機器碼中,所以高特權級的代碼并不比低特權級的代碼顯得“高大上”,目標段(代碼段或數據段)的特權級僅僅是在被訪問時由處理器檢查一次,之后再無用途,所以特權級并不影響處理器執行指令。把計算機資源劃分成不等級,只是讓處理器知道自己正在處理的資源的“份量”有多重,必須用同樣的身份來執行,不能兒戲。
如果處理器僅能平移代碼段的話,另外三個特權級的代碼將沒有機會運行啦。如何穿過特權屏障呢?處理器又提供了多種方式用于從低特權的代碼轉移到高特權代碼。
處理器的特權級升高之后,程序想干什么就干什么,多少都覺得有點恐怖,有沒有一種好辦法,即執行高特權級代碼段上的指令,又不提升特權級?一種方式是利用一致性代碼段。
什么是一致性代碼段?早在當初介紹段描述符結構時就已經提過它了,不過確實只是提了一下而已以至于您可能完全沒有印象^_^。在段描述符中,如果該段為非系統段(段描述符的S字段為0),可以用type字段中的C位來表示該段是否為一致性代碼段。C為1時則表示該段是一致性代碼段,C為0時則表示該段為非一致性代碼段。上面所提到的代碼段是非一致性代碼段,所以只能平級轉移。
一致性代碼段也稱為依從代碼段,Conforming,用來實現從低特權級的代碼向高特權級的代碼轉移。一致性代碼段是指,如果自己是轉移后的目標段,自己的特權級(DPL)一定要大于等于轉移前的CPL,即數值上CPL>=DPL,也就是一致性代碼段的DPL是權限的上限,任何在此權限之下的特權級都可以轉到此代碼段上執行。這是似乎很奇怪但卻意料之中,奇怪的是,低特權級訪問高特權級居然是可以的,而意料之中的是,這才能實現了代碼轉移。該關系用公式表示如下:
在數值上,CPL >=一致性代碼段的DPL。
一致性代碼段的一大特點是,轉移后的特權級不與自己的特權級(DPL)為主,而是與轉移前的低特權級一致,聽從、依從轉移前的低特權級,這就是它稱為“依從、一致”的原因。也就是說,處理器遇到目標段為一致性代碼段時,并不會將CPL用該目標段的DPL替換。
大家注意啦,既然是轉移到特權級更高的一致性代碼段后CPL不變,這說明這種轉移本身并沒有提升特權級,只是可以跑到特權級更高的代碼段中去執行指令,對計算機而言并未造成因特權級升高而產生潛在危險,所以在特權級檢查過程中,請求者的RPL并不參與。
特權級檢查是發生在訪問者訪問受訪者的一瞬間,只檢查一次,在檢查過后,在該段上以后的執行過程中也不會再被檢查,處理器也并不會因為執行了高特權級的代碼而覺得自己了不起,在它眼里任何級別的指令都是一樣的。特權級就是一個個的關卡,僅僅是進門時的檢測而已,與關卡后面的代碼和數據無關。這種情況類似必須要刷工卡才能進公司一樣,即使不刷工卡,您的工位還是那個工位,電腦還是那個電腦,您照樣還是可以使用它們,這些資源并不會有什么改變,它們與咱們是否刷工卡是無關的。所以,盡管轉移到一致性代碼段后CPL還保持為原來的低特權級并未提升,但也沒什么好奇怪的,畢竟目的是運行目標代碼段上的指令,達到目的就行了,何必在意身份呢,人家西游記里的孫悟空當初只是弼馬溫的時候,由于其身份卑微是無法參加王母娘娘蟠桃大會的,最后還不是一樣把蟠桃吃個夠,碉堡了^_^。
順便說一句,代碼段可以有一致性和非一致性之分,但所有的數據段總是非一致的,即,數據段不允許被比本數據段特權級更低的代碼段訪問。
按理說,把代碼劃分為不同等級就是為了等級變換,如果還以卑微的身份去運行高特權級的代碼,似乎不夠體面,人家孫悟空為了面子還號稱為齊天大圣呢,其實cpu中實現特權級變換的“門路”多著呢,還有4個“門”。
總結
以上是生活随笔為你收集整理的一步步编写操作系统 55 CPL和DPL入门2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第一次办信用卡哪个银行额度高
- 下一篇: java lambda 循环list_J